SHOW:
|
|
- or go back to the newest paste.
1 | diff --git a/config/CustomMods/SpecialMods.ini b/config/CustomMods/SpecialMods.ini | |
2 | index 28c8e27..661452f 100644 | |
3 | --- a/config/CustomMods/SpecialMods.ini | |
4 | +++ b/config/CustomMods/SpecialMods.ini | |
5 | @@ -1,4 +1,12 @@ | |
6 | #===================================================== | |
7 | +# View Drop Mob Shift | |
8 | +#===================================================== | |
9 | +#Enable? Retail: False | |
10 | +AltGameViewNpc = True | |
11 | ||
12 | #===================================================== | |
13 | # Admin Login On Skill Super Haste Active | |
14 | #===================================================== | |
15 | #Start with the super rod skill activated? | |
16 | diff --git a/java/net/sf/l2j/Config.java b/java/net/sf/l2j/Config.java | |
17 | index e0d8b1a..d159519 100644 | |
18 | --- a/java/net/sf/l2j/Config.java | |
19 | +++ b/java/net/sf/l2j/Config.java | |
20 | @@ -52,6 +52,8 @@ | |
21 | // Clans settings | |
22 | // -------------------------------------------------- | |
23 | /** Clans */ | |
24 | + public static boolean ALT_GAME_VIEWNPC; | |
25 | public static boolean ANNOUNCE_BOSS_ALIVE; | |
26 | public static boolean ANNOUNCE_RAIDBOS_KILL; | |
27 | public static boolean ANNOUNCE_GRANDBOS_KILL; | |
28 | @@ -1410,6 +1412,7 @@ | |
29 | private static final void loadSpecial() | |
30 | { | |
31 | final ExProperties Special = initProperties(SPECIAL_MODS); | |
32 | + ALT_GAME_VIEWNPC = Boolean.parseBoolean(Special.getProperty("AltGameViewNpc", "False")); | |
33 | AUTO_LOOT_EXCLUDE_ITEMS = Special.getProperty("AutoLootExcludeItems", "1341,1342,1343,1344,1345"); | |
34 | String[] array = AUTO_LOOT_EXCLUDE_ITEMS.split(","); | |
35 | AUTO_LOOT_LIST_EXCLUDE_ITEMS = new int[array.length]; | |
36 | diff --git a/java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java b/java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java | |
37 | index 1eeeed6..1c2a717 100644 | |
38 | --- a/java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java | |
39 | +++ b/java/net/sf/l2j/gameserver/handler/VoicedCommandHandler.java | |
40 | @@ -27,6 +27,7 @@ | |
41 | import net.sf.l2j.Config; | |
42 | import net.sf.l2j.gameserver.GameServer; | |
43 | import net.sf.l2j.gameserver.handler.voicedcommandhandlers.GainXpSp; | |
44 | +import net.sf.l2j.gameserver.handler.voicedcommandhandlers.Shiff_Mod; | |
45 | import net.sf.l2j.gameserver.handler.voicedcommandhandlers.VoicedBanking; | |
46 | import net.sf.l2j.gameserver.handler.voicedcommandhandlers.VoicedBossSpawn; | |
47 | import net.sf.l2j.gameserver.handler.voicedcommandhandlers.VoicedCastles; | |
48 | @@ -58,6 +59,7 @@ | |
49 | private VoicedCommandHandler() | |
50 | { | |
51 | _datatable = new HashMap<>(); | |
52 | + registerVoicedCommandHandler(new Shiff_Mod()); | |
53 | if(Config.ENABLE_COMMAND_RAID) | |
54 | { | |
55 | registerVoicedCommandHandler(new VoicedBossSpawn()); | |
56 | diff --git a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java | |
57 | index 09a06a9..48cdbd5 100644 | |
58 | --- a/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java | |
59 | +++ b/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminEditChar.java | |
60 | @@ -579,7 +579,7 @@ | |
61 | * @param player : The {@link Player} who requested that action. | |
62 | * @param targetPlayer : The {@link Player} target to gather informations from. | |
63 | */ | |
64 | - private static void gatherPlayerInfo(Player player, Player targetPlayer) | |
65 | + public static void gatherPlayerInfo(Player player, Player targetPlayer) | |
66 | { | |
67 | final NpcHtmlMessage html = new NpcHtmlMessage(0); | |
68 | gatherPlayerInfo(player, targetPlayer, html); | |
69 | diff --git a/java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/Shiff_Mod.java b/java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/Shiff_Mod.java | |
70 | new file mode 100644 | |
71 | index 0000000..6c8586e | |
72 | --- /dev/null | |
73 | +++ b/java/net/sf/l2j/gameserver/handler/voicedcommandhandlers/Shiff_Mod.java | |
74 | @@ -0,0 +1,193 @@ | |
75 | +/* This program is free software: you can redistribute it and/or modify it under | |
76 | + * the terms of the GNU General Public License as published by the Free Software | |
77 | + * Foundation, either version 3 of the License, or (at your option) any later | |
78 | + * version. | |
79 | + * | |
80 | + * This program is distributed in the hope that it will be useful, but WITHOUT | |
81 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
82 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
83 | + * details. | |
84 | + * | |
85 | + * You should have received a copy of the GNU General Public License along with | |
86 | + * this program. If not, see <http://www.gnu.org/licenses/>. | |
87 | + */ | |
88 | +package net.sf.l2j.gameserver.handler.voicedcommandhandlers; | |
89 | + | |
90 | +import java.text.DecimalFormat; | |
91 | +import java.util.StringTokenizer; | |
92 | + | |
93 | +import net.sf.l2j.commons.lang.StringUtil; | |
94 | + | |
95 | +import net.sf.l2j.Config; | |
96 | +import net.sf.l2j.gameserver.data.xml.IconTable; | |
97 | +import net.sf.l2j.gameserver.data.xml.ItemData; | |
98 | +import net.sf.l2j.gameserver.data.xml.NpcData; | |
99 | +import net.sf.l2j.gameserver.handler.IVoicedCommandHandler; | |
100 | +import net.sf.l2j.gameserver.model.actor.Player; | |
101 | +import net.sf.l2j.gameserver.model.actor.template.NpcTemplate; | |
102 | +import net.sf.l2j.gameserver.model.item.DropCategory; | |
103 | +import net.sf.l2j.gameserver.model.item.DropData; | |
104 | +import net.sf.l2j.gameserver.network.serverpackets.ActionFailed; | |
105 | +import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage; | |
106 | + | |
107 | +public class Shiff_Mod implements IVoicedCommandHandler | |
108 | +{ | |
109 | + private final static int PAGE_LIMIT = 15; | |
110 | + private static final String[] _voicedCommands = | |
111 | + { | |
112 | + "shifffmodddrop", | |
113 | + }; | |
114 | + | |
115 | + @Override | |
116 | + public boolean useVoicedCommand(String command, Player activeChar, String target) | |
117 | + { | |
118 | + | |
119 | + if (activeChar.isDead() || activeChar.isFakeDeath() || activeChar.getKarma() > 0 || activeChar.getPvpFlag() > 0 || activeChar.isAlikeDead() || activeChar.isFestivalParticipant() || activeChar.isInJail() | |
120 | + || activeChar.isInOlympiadMode() || activeChar.isInObserverMode() || activeChar.isFlying() || activeChar.isTeleporting() || activeChar.isParalyzed() | |
121 | + || activeChar.isSleeping() || activeChar.isInDuel () || activeChar.isBetrayed() || activeChar.isMounted() || activeChar.isRooted()) | |
122 | + { | |
123 | + activeChar.sendMessage("You Cannot Use This Command Right Now"); | |
124 | + activeChar.sendPacket(ActionFailed.STATIC_PACKET); | |
125 | + return false; | |
126 | + } | |
127 | + if (command.startsWith("shifffmodddrop")) | |
128 | + { | |
129 | + final StringTokenizer st = new StringTokenizer(command, " "); | |
130 | + st.nextToken(); | |
131 | + int npcId = Integer.parseInt(st.nextToken()); | |
132 | + int page = (st.hasMoreTokens()) ? Integer.parseInt(st.nextToken()) : 1; | |
133 | + | |
134 | + ShiffNpcDropList(activeChar, npcId, page); | |
135 | + } | |
136 | + return true; | |
137 | + } | |
138 | + | |
139 | + @Override | |
140 | + public String[] getVoicedCommandList() | |
141 | + { | |
142 | + return _voicedCommands; | |
143 | + } | |
144 | + | |
145 | + private static void ShiffNpcDropList(Player activeChar, int npcId, int page) | |
146 | + { | |
147 | + final NpcTemplate npcData = NpcData.getInstance().getTemplate(npcId); | |
148 | + if (npcData == null) | |
149 | + { | |
150 | + activeChar.sendMessage("Npc template is unknown for id: " + npcId + "."); | |
151 | + return; | |
152 | + } | |
153 | + | |
154 | + final StringBuilder sb = new StringBuilder(2000); | |
155 | + | |
156 | + if (!npcData.getDropData().isEmpty()) | |
157 | + { | |
158 | + StringUtil.append(sb, "<html><title> ", npcData.getName(), " Drop List ", page, "</title><body>"); | |
159 | + StringUtil.append(sb, "<center><img src=\"l2ui_ch3.herotower_deco\" width=256 height=32><br>"); | |
160 | + StringUtil.append(sb, "<img src=\"L2UI.SquareGray\" width=280 height=1>"); | |
161 | + StringUtil.append(sb, "<table border=0 bgcolor=000000 width=\"290\"><tr>"); | |
162 | + StringUtil.append(sb, "<td align=center><font color=\"LEVEL\">Name Item</font></td>"); | |
163 | + StringUtil.append(sb, "<td align=center><font color=\"FF6600\">Quantity Drop</font></td>"); | |
164 | + StringUtil.append(sb, "<td align=center>Chance Drop</td>"); | |
165 | + StringUtil.append(sb, "</tr></table>"); | |
166 | + StringUtil.append(sb, "<img src=\"L2UI.SquareGray\" width=280 height=1>"); | |
167 | + StringUtil.append(sb, "<br><img src=\"L2UI.SquareGray\" width=280 height=1>"); | |
168 | + | |
169 | + int myPage = 1; | |
170 | + int i = 0; | |
171 | + int shown = 0; | |
172 | + boolean hasMore = false; | |
173 | + | |
174 | + for (DropCategory cat : npcData.getDropData()) | |
175 | + { | |
176 | + if (shown == PAGE_LIMIT) | |
177 | + { | |
178 | + hasMore = true; | |
179 | + break; | |
180 | + } | |
181 | + | |
182 | + for (DropData drop : cat.getAllDrops()) | |
183 | + { | |
184 | + if (myPage != page) | |
185 | + { | |
186 | + i++; | |
187 | + if (i == PAGE_LIMIT) | |
188 | + { | |
189 | + myPage++; | |
190 | + i = 0; | |
191 | + } | |
192 | + continue; | |
193 | + } | |
194 | + | |
195 | + if (shown == PAGE_LIMIT) | |
196 | + { | |
197 | + hasMore = true; | |
198 | + break; | |
199 | + } | |
200 | + | |
201 | + | |
202 | + | |
203 | + DecimalFormat df2 = new DecimalFormat("##.##"); | |
204 | + | |
205 | + double ChanceInt = ((double)drop.getChance()/10000 * Config.RATE_DROP_ITEMS); | |
206 | + String Chance = df2.format(ChanceInt); | |
207 | + | |
208 | + int caluleAdena = ((int)Config.RATE_DROP_ADENA + (int)Config.RATE_DROP_ITEMS); | |
209 | + | |
210 | + | |
211 | + StringUtil.append(sb, "<table bgcolor=000000><tr>"); | |
212 | + StringUtil.append(sb, "<td><img src=\"" + IconTable.getIcon(drop.getItemId()) + "\" width=32 height=32></td><td>"); | |
213 | + StringUtil.append(sb, "<table><tr><td><font color=\"LEVEL\">", ItemData.getInstance().getTemplate(drop.getItemId()).getName(), "</font>"); | |
214 | + | |
215 | + //calculando porcentagem Adenas Drop | |
216 | + if(drop.getItemId() == 57) { | |
217 | + StringUtil.append(sb, "<font color=\"FF6600\"> (", drop.getMinDrop() * caluleAdena, "/", drop.getMaxDrop() * caluleAdena , ")</font>"); | |
218 | + } | |
219 | + else | |
220 | + { | |
221 | + //calculando porcentagem Items Drop | |
222 | + StringUtil.append(sb, "<font color=\"FF6600\"> (", drop.getMinDrop() , "/", drop.getMaxDrop() , ")</font>"); | |
223 | + } | |
224 | + StringUtil.append(sb, "</td></tr>"); | |
225 | + StringUtil.append(sb, "<tr><td>Rate: " + String.valueOf(Chance) + "%" + (drop.isQuestDrop() ? "Quest" : (cat.isSweep() ? "<font color=\"00FF00\"> Sweep</font><img src=\"L2UI.SquareGray\" width=233 height=1>" : "<font color=\"3BB9FF\"> Drop</font><img src=\"L2UI.SquareGray\" width=233 height=1>")) + "</td></tr></table></td></tr>"); | |
226 | + shown++; | |
227 | + } | |
228 | + } | |
229 | + | |
230 | + | |
231 | + StringUtil.append(sb, "</table>"); | |
232 | + StringUtil.append(sb, "<img src=\"L2UI.SquareGray\" width=280 height=1><br>"); | |
233 | + StringUtil.append(sb, "<img src=\"L2UI.SquareGray\" width=280 height=1>"); | |
234 | + StringUtil.append(sb, "<table width=\"100%\" bgcolor=000000><tr>"); | |
235 | + | |
236 | + if (page > 1) | |
237 | + { | |
238 | + StringUtil.append(sb, "<td width=120><a action=\"bypass -h voiced_shifffmodddrop ", npcId, " ", page - 1, "\">Prev Page</a></td>"); | |
239 | + if (!hasMore) | |
240 | + StringUtil.append(sb, "<td width=100>Page ", page, "</td><td width=70></td></tr>"); | |
241 | + } | |
242 | + | |
243 | + if (hasMore) | |
244 | + { | |
245 | + if (page <= 1) | |
246 | + StringUtil.append(sb, "<td width=120></td>"); | |
247 | + | |
248 | + StringUtil.append(sb, "<td width=100>Page ", page, "</td><td width=70><a action=\"bypass -h voiced_shifffmodddrop ", npcId, " ", page + 1, "\">Next Page</a></td></tr>"); | |
249 | + } | |
250 | + StringUtil.append(sb, "</table>"); | |
251 | + } | |
252 | + else | |
253 | + StringUtil.append(sb, "This NPC has no drops."); | |
254 | + | |
255 | + StringUtil.append(sb, "</body></html>"); | |
256 | + | |
257 | + final NpcHtmlMessage html = new NpcHtmlMessage(0); | |
258 | + html.setHtml(sb.toString()); | |
259 | + activeChar.sendPacket(html); | |
260 | + } | |
261 | + | |
262 | + public void addRadar(Player activeChar, int x, int y, int z) | |
263 | + { | |
264 | + activeChar.getRadarList().addMarker(x, y, z); | |
265 | + } | |
266 | + | |
267 | +} | |
268 | \ No newline at end of file | |
269 | diff --git a/java/net/sf/l2j/gameserver/model/WorldObject.java b/java/net/sf/l2j/gameserver/model/WorldObject.java | |
270 | index 491d925..aec4dc6 100644 | |
271 | --- a/java/net/sf/l2j/gameserver/model/WorldObject.java | |
272 | +++ b/java/net/sf/l2j/gameserver/model/WorldObject.java | |
273 | @@ -175,7 +175,10 @@ | |
274 | { | |
275 | _name = value; | |
276 | } | |
277 | - | |
278 | + public void onActionShift(Player player) | |
279 | + { | |
280 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
281 | + } | |
282 | public final int getObjectId() | |
283 | { | |
284 | return _objectId; | |
285 | diff --git a/java/net/sf/l2j/gameserver/model/actor/Creature.java b/java/net/sf/l2j/gameserver/model/actor/Creature.java | |
286 | index 95d63d2..c669703 100644 | |
287 | --- a/java/net/sf/l2j/gameserver/model/actor/Creature.java | |
288 | +++ b/java/net/sf/l2j/gameserver/model/actor/Creature.java | |
289 | @@ -48,6 +48,7 @@ | |
290 | import net.sf.l2j.gameserver.model.location.Location; | |
291 | import net.sf.l2j.gameserver.model.zone.type.WaterZone; | |
292 | import net.sf.l2j.gameserver.network.serverpackets.AbstractNpcInfo.NpcInfo; | |
293 | +import net.sf.l2j.gameserver.network.serverpackets.ActionFailed; | |
294 | import net.sf.l2j.gameserver.network.serverpackets.ChangeMoveType; | |
295 | import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket; | |
296 | import net.sf.l2j.gameserver.network.serverpackets.Revive; | |
297 | @@ -1436,7 +1437,16 @@ | |
298 | player.getAI().tryToInteract(this, isCtrlPressed, isShiftPressed); | |
299 | } | |
300 | } | |
301 | + @Override | |
302 | + public void onActionShift(Player player) | |
303 | + { | |
304 | + if (player.getTarget() != this) | |
305 | + player.setTarget(this); | |
306 | + | |
307 | + else | |
308 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
309 | + super.onActionShift(player); | |
310 | + } | |
311 | /** | |
312 | * @return true if this {@link Creature} is inside an active {@link WorldRegion}. | |
313 | */ | |
314 | @@ -1884,7 +1894,6 @@ | |
315 | { | |
316 | return false; | |
317 | } | |
318 | - | |
319 | /** | |
320 | * Test and cast curses if : | |
321 | * <ul> | |
322 | diff --git a/java/net/sf/l2j/gameserver/model/actor/Npc.java b/java/net/sf/l2j/gameserver/model/actor/Npc.java | |
323 | index 17a0088..95069bd 100644 | |
324 | --- a/java/net/sf/l2j/gameserver/model/actor/Npc.java | |
325 | +++ b/java/net/sf/l2j/gameserver/model/actor/Npc.java | |
326 | @@ -2,6 +2,7 @@ | |
327 | ||
328 | import java.text.DateFormat; | |
329 | import java.util.ArrayList; | |
330 | +import java.util.Arrays; | |
331 | import java.util.List; | |
332 | import java.util.Map; | |
333 | import java.util.StringTokenizer; | |
334 | @@ -33,6 +34,8 @@ | |
335 | import net.sf.l2j.gameserver.enums.items.ShotType; | |
336 | import net.sf.l2j.gameserver.idfactory.IdFactory; | |
337 | import net.sf.l2j.gameserver.model.WorldObject; | |
338 | +import net.sf.l2j.gameserver.model.actor.instance.Merchant; | |
339 | +import net.sf.l2j.gameserver.model.actor.instance.Monster; | |
340 | import net.sf.l2j.gameserver.model.actor.status.NpcStatus; | |
341 | import net.sf.l2j.gameserver.model.actor.template.NpcTemplate; | |
342 | import net.sf.l2j.gameserver.model.clanhall.ClanHall; | |
343 | @@ -224,7 +227,69 @@ | |
344 | { | |
345 | return (_shotsMask & type.getMask()) == type.getMask(); | |
346 | } | |
347 | - | |
348 | + @Override | |
349 | + public void onActionShift(Player player) | |
350 | + { | |
351 | + // Check if the L2PcInstance is a GM | |
352 | + if (player.isGM()) | |
353 | + { | |
354 | + final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); | |
355 | + html.setFile("data/html/admin/npcinfo.htm"); | |
356 | + html.replace("%class%", getClass().getSimpleName()); | |
357 | + html.replace("%id%", getTemplate().getNpcId()); | |
358 | + html.replace("%lvl%", getTemplate().getLevel()); | |
359 | + html.replace("%name%", getTemplate().getName()); | |
360 | + html.replace("%race%", getTemplate().getRace().toString()); | |
361 | + html.replace("%tmplid%", getTemplate().getIdTemplate()); | |
362 | + html.replace("%aggro%", getTemplate().getAggroRange()); | |
363 | + html.replace("%corpse%", StringUtil.getTimeStamp(getTemplate().getCorpseTime())); | |
364 | + html.replace("%enchant%", getTemplate().getEnchantEffect()); | |
365 | + html.replace("%loc%", getX() + " " + getY() + " " + getZ()); | |
366 | + | |
367 | + if (getSpawn() != null) | |
368 | + { | |
369 | + html.replace("%spawn%", getSpawn().getLoc().toString()); | |
370 | + html.replace("%resp%", StringUtil.getTimeStamp(getSpawn().getRespawnDelay())); | |
371 | + html.replace("%rand_resp%", StringUtil.getTimeStamp(getSpawn().getRespawnRandom())); | |
372 | + } | |
373 | + else | |
374 | + { | |
375 | + html.replace("%spawn%", "<font color=FF0000>null</font>"); | |
376 | + html.replace("%loc2d%", "<font color=FF0000>--</font>"); | |
377 | + html.replace("%loc3d%", "<font color=FF0000>--</font>"); | |
378 | + html.replace("%resp%", "<font color=FF0000>--</font>"); | |
379 | + html.replace("%rand_resp%", "<font color=FF0000>--</font>"); | |
380 | + } | |
381 | + | |
382 | + html.replace("%ai_type%", getTemplate().getAiType().name()); | |
383 | + html.replace("%ai_clan%", (getTemplate().getClans() != null) ? "<tr><td width=100><font color=\"LEVEL\">Clan:</font></td><td align=right width=170>" + Arrays.toString(getTemplate().getClans()) + " " + getTemplate().getClanRange() + "</td></tr>" + ((getTemplate().getIgnoredIds() != null) ? "<tr><td width=100><font color=\"LEVEL\">Ignored ids:</font></td><td align=right width=170>" + Arrays.toString(getTemplate().getIgnoredIds()) + "</td></tr>" : "") : ""); | |
384 | + html.replace("%ai_move%", String.valueOf(getTemplate().canMove())); | |
385 | + html.replace("%ai_seed%", String.valueOf(getTemplate().isSeedable())); | |
386 | + html.replace("%ai_ssinfo%", _currentSsCount + "[" + getTemplate().getSsCount() + "] - " + getTemplate().getSsRate() + "%"); | |
387 | + html.replace("%ai_spsinfo%", _currentSpsCount + "[" + getTemplate().getSpsCount() + "] - " + getTemplate().getSpsRate() + "%"); | |
388 | + html.replace("%butt%", ((this instanceof Merchant) ? "<button value=\"Shop\" action=\"bypass -h admin_show_shop " + getNpcId() + "\" width=65 height=19 back=\"L2UI_ch3.smallbutton2_over\" fore=\"L2UI_ch3.smallbutton2\">" : "")); | |
389 | + player.sendPacket(html); | |
390 | + } | |
391 | + else if (Config.ALT_GAME_VIEWNPC) | |
392 | + { | |
393 | + if (!(this instanceof Monster)) | |
394 | + { | |
395 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
396 | + return; | |
397 | + } | |
398 | + final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId()); | |
399 | + html.setFile("data/html/custom/dropNpc/npcinfo.htm"); | |
400 | + html.replace("%id%", getTemplate().getNpcId()); | |
401 | + html.replace("%lvl%", getTemplate().getLevel()); | |
402 | + html.replace("%name%", getTemplate().getName()); | |
403 | + html.replace("%loc%", getX() + " " + getY() + " " + getZ()); | |
404 | + player.sendPacket(html); | |
405 | + } | |
406 | + if (player.getTarget() != this) | |
407 | + player.setTarget(this); | |
408 | + else | |
409 | + player.sendPacket(ActionFailed.STATIC_PACKET); | |
410 | + } | |
411 | @Override | |
412 | public void setChargedShot(ShotType type, boolean charged) | |
413 | { | |
414 | diff --git a/java/net/sf/l2j/gameserver/model/actor/Player.java b/java/net/sf/l2j/gameserver/model/actor/Player.java | |
415 | index 44ffc27..6b4802b 100644 | |
416 | --- a/java/net/sf/l2j/gameserver/model/actor/Player.java | |
417 | +++ b/java/net/sf/l2j/gameserver/model/actor/Player.java | |
418 | @@ -84,6 +84,7 @@ | |
419 | import net.sf.l2j.gameserver.geoengine.GeoEngine; | |
420 | import net.sf.l2j.gameserver.handler.IItemHandler; | |
421 | import net.sf.l2j.gameserver.handler.ItemHandler; | |
422 | +import net.sf.l2j.gameserver.handler.admincommandhandlers.AdminEditChar; | |
423 | import net.sf.l2j.gameserver.handler.skillhandlers.SummonFriend; | |
424 | import net.sf.l2j.gameserver.model.AccessLevel; | |
425 | import net.sf.l2j.gameserver.model.PetDataEntry; | |
426 | @@ -665,7 +666,14 @@ | |
427 | { | |
428 | return super.denyAiAction() || isInStoreMode() || _operateType == OperateType.OBSERVE; | |
429 | } | |
430 | - | |
431 | + @Override | |
432 | + public void onActionShift(Player player) | |
433 | + { | |
434 | + if (player.isGM()) | |
435 | + AdminEditChar.gatherPlayerInfo(player, this); | |
436 | + | |
437 | + super.onActionShift(player); | |
438 | + } | |
439 | @Override | |
440 | public PlayerMove getMove() | |
441 | { | |
442 | diff --git a/java/net/sf/l2j/gameserver/model/item/DropData.java b/java/net/sf/l2j/gameserver/model/item/DropData.java | |
443 | index c36b9ee..d8fde92 100644 | |
444 | --- a/java/net/sf/l2j/gameserver/model/item/DropData.java | |
445 | +++ b/java/net/sf/l2j/gameserver/model/item/DropData.java | |
446 | @@ -1,5 +1,7 @@ | |
447 | package net.sf.l2j.gameserver.model.item; | |
448 | ||
449 | +import java.util.Arrays; | |
450 | + | |
451 | /** | |
452 | * A container used by monster drops.<br> | |
453 | * <br> | |
454 | @@ -10,6 +12,8 @@ | |
455 | public static final int MAX_CHANCE = 1000000; | |
456 | ||
457 | private final int _itemId; | |
458 | + private String _questID = null; | |
459 | + private String[] _stateID = null; | |
460 | private final int _minDrop; | |
461 | private final int _maxDrop; | |
462 | private final int _chance; | |
463 | @@ -25,9 +29,28 @@ | |
464 | @Override | |
465 | public String toString() | |
466 | { | |
467 | - return "DropData =[ItemID: " + _itemId + " Min: " + _minDrop + " Max: " + _maxDrop + " Chance: " + (_chance / 10000.0) + "%]"; | |
468 | + String out = "ItemID: " + _itemId + " Min: " + _minDrop + " Max: " + _maxDrop + " Chance: " + (_chance / 10000.0) + "%"; | |
469 | + if (isQuestDrop()) | |
470 | + { | |
471 | + out = out + " QuestID: " + getQuestID() + " StateID's: " + Arrays.toString(getStateIDs()); | |
472 | + } | |
473 | + return out; | |
474 | + //return "DropData =[ItemID: " + _itemId + " Min: " + _minDrop + " Max: " + _maxDrop + " Chance: " + (_chance / 10000.0) + "%]"; | |
475 | + } | |
476 | + public String getQuestID() | |
477 | + { | |
478 | + return this._questID; | |
479 | } | |
480 | ||
481 | + public String[] getStateIDs() | |
482 | + { | |
483 | + return this._stateID; | |
484 | + } | |
485 | + | |
486 | + public boolean isQuestDrop() | |
487 | + { | |
488 | + return (this._questID != null) && (this._stateID != null); | |
489 | + } | |
490 | /** | |
491 | * @return the id of the dropped item. | |
492 | */ | |
493 | diff --git a/java/net/sf/l2j/gameserver/network/clientpackets/Action.java b/java/net/sf/l2j/gameserver/network/clientpackets/Action.java | |
494 | index e963ca2..52bfaed 100644 | |
495 | --- a/java/net/sf/l2j/gameserver/network/clientpackets/Action.java | |
496 | +++ b/java/net/sf/l2j/gameserver/network/clientpackets/Action.java | |
497 | @@ -1,63 +1,85 @@ | |
498 | package net.sf.l2j.gameserver.network.clientpackets; | |
499 | ||
500 | import net.sf.l2j.gameserver.model.World; | |
501 | import net.sf.l2j.gameserver.model.WorldObject; | |
502 | import net.sf.l2j.gameserver.model.actor.Player; | |
503 | -import net.sf.l2j.gameserver.model.entity.Duel.DuelState; | |
504 | import net.sf.l2j.gameserver.network.SystemMessageId; | |
505 | import net.sf.l2j.gameserver.network.serverpackets.ActionFailed; | |
506 | ||
507 | public final class Action extends L2GameClientPacket | |
508 | { | |
509 | private int _objectId; | |
510 | - private boolean _isShiftAction; | |
511 | + @SuppressWarnings("unused") | |
512 | + private int _originX, _originY, _originZ; | |
513 | + private int _actionId; | |
514 | ||
515 | @Override | |
516 | protected void readImpl() | |
517 | { | |
518 | _objectId = readD(); | |
519 | - readD(); // originX | |
520 | - readD(); // originY | |
521 | - readD(); // originZ | |
522 | - _isShiftAction = readC() != 0; | |
523 | + _originX = readD(); | |
524 | + _originY = readD(); | |
525 | + _originZ = readD(); | |
526 | + _actionId = readC(); | |
527 | } | |
528 | ||
529 | @Override | |
530 | protected void runImpl() | |
531 | { | |
532 | - final Player player = getClient().getPlayer(); | |
533 | - if (player == null) | |
534 | + final Player activeChar = getClient().getPlayer(); | |
535 | + if (activeChar == null) | |
536 | return; | |
537 | ||
538 | - if (player.isInObserverMode()) | |
539 | + if (activeChar.isInObserverMode()) | |
540 | { | |
541 | - player.sendPacket(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE); | |
542 | - player.sendPacket(ActionFailed.STATIC_PACKET); | |
543 | + activeChar.sendPacket(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE); | |
544 | + activeChar.sendPacket(ActionFailed.STATIC_PACKET); | |
545 | return; | |
546 | } | |
547 | ||
548 | - if (player.getActiveRequester() != null) | |
549 | + if (activeChar.getActiveRequester() != null || activeChar.isOutOfControl()) | |
550 | { | |
551 | - player.sendPacket(ActionFailed.STATIC_PACKET); | |
552 | + activeChar.sendPacket(ActionFailed.STATIC_PACKET); | |
553 | return; | |
554 | } | |
555 | ||
556 | - final WorldObject target = (player.getTargetId() == _objectId) ? player.getTarget() : World.getInstance().getObject(_objectId); | |
557 | - if (target == null) | |
558 | + final WorldObject obj = (activeChar.getTargetId() == _objectId) ? activeChar.getTarget() : World.getInstance().getObject(_objectId); | |
559 | + if (obj == null) | |
560 | { | |
561 | - player.sendPacket(ActionFailed.STATIC_PACKET); | |
562 | + activeChar.sendPacket(ActionFailed.STATIC_PACKET); | |
563 | return; | |
564 | } | |
565 | ||
566 | - final Player targetPlayer = target.getActingPlayer(); | |
567 | - if (targetPlayer != null && targetPlayer.getDuelState() == DuelState.DEAD) | |
568 | + switch (_actionId) | |
569 | { | |
570 | - player.sendPacket(SystemMessageId.OTHER_PARTY_IS_FROZEN); | |
571 | - player.sendPacket(ActionFailed.STATIC_PACKET); | |
572 | - return; | |
573 | + case 0: | |
574 | + obj.onAction(activeChar, false, false); | |
575 | + break; | |
576 | + | |
577 | + case 1: | |
578 | + obj.onActionShift(activeChar); | |
579 | + break; | |
580 | + | |
581 | + default: | |
582 | + // Invalid action detected (probably client cheating), log this | |
583 | + LOGGER.warn(activeChar.getName() + " requested invalid action: " + _actionId); | |
584 | + activeChar.sendPacket(ActionFailed.STATIC_PACKET); | |
585 | + break; | |
586 | } | |
587 | - | |
588 | - target.onAction(player, false, _isShiftAction); | |
589 | } | |
590 | ||
591 | @Override | |
592 |