View difference between Paste ID: qgTj9XTX and 8iLT0aEF
SHOW: | | - or go back to the newest paste.
1
Index: java/com/l2jserver/gameserver/datatables/NpcTable.java
2
===================================================================
3
--- java/com/l2jserver/gameserver/datatables/NpcTable.java	(revision 5522)
4
+++ java/com/l2jserver/gameserver/datatables/NpcTable.java	(working copy)
5
@@ -146,6 +146,7 @@
6
 		npcDat.set("baseMAtkSpd", NpcData.getInt("matkspd"));
7
 		npcDat.set("rhand", NpcData.getInt("rhand"));
8
 		npcDat.set("lhand", NpcData.getInt("lhand"));
9
+		npcDat.set("baseAttackType", NpcData.getString("baseAttackType"));
10
 		npcDat.set("enchant", NpcData.getInt("enchant"));
11
 		npcDat.set("baseWalkSpd", NpcData.getInt("walkspd"));
12
 		npcDat.set("baseRunSpd", NpcData.getInt("runspd"));
13
Index: java/com/l2jserver/gameserver/ai/L2CharacterAI.java
14
===================================================================
15
--- java/com/l2jserver/gameserver/ai/L2CharacterAI.java	(revision 5522)
16
+++ java/com/l2jserver/gameserver/ai/L2CharacterAI.java	(working copy)
17
@@ -41,10 +41,8 @@
18
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
19
 import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
20
 import com.l2jserver.gameserver.model.effects.L2Effect;
21
-import com.l2jserver.gameserver.model.items.L2Weapon;
22
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
23
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance.ItemLocation;
24
-import com.l2jserver.gameserver.model.items.type.L2WeaponType;
25
 import com.l2jserver.gameserver.model.skills.L2Skill;
26
 import com.l2jserver.gameserver.model.skills.L2SkillType;
27
 import com.l2jserver.gameserver.model.skills.targets.L2TargetType;
28
@@ -1333,8 +1331,7 @@
29
 			}
30
 			else
31
 			{
32
-				L2Weapon weapon = target.getActiveWeaponItem();
33
-				if (weapon != null && (weapon.getItemType() == L2WeaponType.BOW || weapon.getItemType() == L2WeaponType.CROSSBOW))
34
+				if (target.isUsingRangedWeapon())
35
 					isArcher = true;
36
 				else
37
 					isFighter = true;
38
Index: java/com/l2jserver/gameserver/model/conditions/ConditionUsingItemType.java
39
===================================================================
40
--- java/com/l2jserver/gameserver/model/conditions/ConditionUsingItemType.java	(revision 5528)
41
+++ java/com/l2jserver/gameserver/model/conditions/ConditionUsingItemType.java	(working copy)
42
@@ -41,16 +41,14 @@
43
 	
44
 	@Override
45
 	public boolean testImpl(Env env)
46
-	{
47
-		if (env.getCharacter() == null || !env.getCharacter().isPlayer())
48
-		{
49
+	{	
50
+		if (env.getCharacter() == null)
51
 			return false;
52
-		}
53
 		
54
-		final Inventory inv = env.getPlayer().getInventory();
55
 		// If ConditionUsingItemType is one between Light, Heavy or Magic
56
-		if (_armor)
57
+		if (_armor && env.getCharacter().isPlayer())
58
 		{
59
+			final Inventory inv = env.getPlayer().getInventory();
60
 			// Get the itemMask of the weared chest (if exists)
61
 			L2ItemInstance chest = inv.getPaperdollItem(Inventory.PAPERDOLL_CHEST);
62
 			if (chest == null)
63
@@ -83,6 +81,7 @@
64
 			// return true if legs armor matches too
65
 			return (_mask & legMask) != 0;
66
 		}
67
-		return (_mask & inv.getWearedMask()) != 0;
68
+		
69
+		return (_mask & env.getCharacter().getWeaponType().mask()) != 0;
70
 	}
71
 }
72
Index: java/com/l2jserver/gameserver/model/stats/Formulas.java
73
===================================================================
74
--- java/com/l2jserver/gameserver/model/stats/Formulas.java	(revision 5522)
75
+++ java/com/l2jserver/gameserver/model/stats/Formulas.java	(working copy)
76
@@ -1399,8 +1399,7 @@
77
 		}
78
 		if (Config.ALT_GAME_CANCEL_BOW && target.isAttackingNow())
79
 		{
80
-			L2Weapon wpn = target.getActiveWeaponItem();
81
-			if ((wpn != null) && (wpn.getItemType() == L2WeaponType.BOW))
82
+			if (target.isUsingRangedWeapon())
83
 			{
84
 				init = 15;
85
 			}
86
@@ -1661,8 +1660,7 @@
87
 		byte shldSuccess = SHIELD_DEFENSE_FAILED;
88
 		// if attacker
89
 		// if attacker use bow and target wear shield, shield block rate is multiplied by 1.3 (30%)
90
-		L2Weapon at_weapon = attacker.getActiveWeaponItem();
91
-		if ((at_weapon != null) && (at_weapon.getItemType() == L2WeaponType.BOW))
92
+		if (attacker.getWeaponType() == L2WeaponType.BOW)
93
 		{
94
 			shldRate *= 1.3;
95
 		}
96
Index: java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillChargeDmg.java
97
===================================================================
98
--- java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillChargeDmg.java	(revision 5522)
99
+++ java/com/l2jserver/gameserver/model/skills/l2skills/L2SkillChargeDmg.java	(working copy)
100
@@ -84,7 +84,6 @@
101
 			// TODO: should we use dual or not?
102
 			// because if so, damage are lowered but we don't do anything special with dual then
103
 			// like in doAttackHitByDual which in fact does the calcPhysDam call twice
104
-			//boolean dual  = caster.isUsingDualWeapon();
105
 			byte shld = Formulas.calcShldUse(caster, target, this);
106
 			boolean crit = false;
107
 			if (getBaseCritRate() > 0 && !isStaticDamage())
108
Index: java/com/l2jserver/gameserver/model/actor/stat/CharStat.java
109
===================================================================
110
--- java/com/l2jserver/gameserver/model/actor/stat/CharStat.java	(revision 5522)
111
+++ java/com/l2jserver/gameserver/model/actor/stat/CharStat.java	(working copy)
112
@@ -17,7 +17,6 @@
113
 import com.l2jserver.Config;
114
 import com.l2jserver.gameserver.model.Elementals;
115
 import com.l2jserver.gameserver.model.actor.L2Character;
116
-import com.l2jserver.gameserver.model.items.L2Weapon;
117
 import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
118
 import com.l2jserver.gameserver.model.items.type.L2WeaponType;
119
 import com.l2jserver.gameserver.model.skills.L2Skill;
120
@@ -666,8 +665,7 @@
121
 			return _activeChar.getTemplate().getBaseAtkRange();
122
 		// Polearm handled here for now. Basically L2PcInstance could have a function
123
 		// similar to FuncBowAtkRange and NPC are defined in DP.
124
-		L2Weapon weaponItem = _activeChar.getActiveWeaponItem();
125
-		if (weaponItem != null && weaponItem.getItemType() == L2WeaponType.POLE)
126-
@@ -5388,6 +5390,58 @@
126+
+		if (_activeChar.getWeaponType() == L2WeaponType.POLE)
127
 			return (int) calcStat(Stats.POWER_ATTACK_RANGE, 66, null, null);
128
 		
129
 		return (int) calcStat(Stats.POWER_ATTACK_RANGE, _activeChar.getTemplate().getBaseAtkRange(), null, null);
130
Index: java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java
131
===================================================================
132
--- java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java	(revision 5522)
133
+++ java/com/l2jserver/gameserver/model/actor/templates/L2NpcTemplate.java	(working copy)
134
@@ -19,6 +19,7 @@
135
 import java.util.List;
136
 import java.util.Map;
137
 import java.util.Map.Entry;
138
+import java.util.logging.Level;
139
 import java.util.logging.Logger;
140
 
141
 import javolution.util.FastMap;
142
@@ -31,6 +32,7 @@
143
 import com.l2jserver.gameserver.model.StatsSet;
144
 import com.l2jserver.gameserver.model.actor.instance.L2XmassTreeInstance;
145
 import com.l2jserver.gameserver.model.base.ClassId;
146
+import com.l2jserver.gameserver.model.items.type.L2WeaponType;
147
 import com.l2jserver.gameserver.model.quest.Quest;
148
 import com.l2jserver.gameserver.model.quest.Quest.QuestEventType;
149
 import com.l2jserver.gameserver.model.skills.L2Skill;
150
@@ -55,6 +57,7 @@
151
 	private final int _rewardSp;
152
 	private final int _rHand;
153
 	private final int _lHand;
154
+	private L2WeaponType _baseAttackType;
155
 	private final int _enchantEffect;
156
 	
157
 	private Race _race;
158
@@ -216,6 +219,15 @@
159
 		_rewardSp = set.getInteger("rewardSp");
160
 		_rHand = set.getInteger("rhand");
161
 		_lHand = set.getInteger("lhand");
162
+		try
163
+		{
164
+			_baseAttackType = L2WeaponType.valueOf(set.getString("baseAttackType"));
165
+		}
166
+		catch (IllegalArgumentException iae)
167
+		{
168
+			_baseAttackType = L2WeaponType.NONE;
169
+			_log.log(Level.WARNING, "Invalid baseAttackType for npcId: " + _npcId, iae);
170
+		}
171
 		_enchantEffect = set.getInteger("enchant");
172
 		_race = null;
173
 		final int herbGroup = set.getInteger("dropHerbGroup");
174
@@ -632,6 +644,14 @@
175
 	}
176
 	
177
 	/**
178
+	 * @return the weapon type this NPC is using.
179
+	 */
180
+	public L2WeaponType getBaseAttackType()
181
+	{
182
+		return _baseAttackType;
183
+	}
184
+	
185
+	/**
186
 	 * @return the enchant effect.
187
 	 */
188
 	public int getEnchantEffect()
189
Index: java/com/l2jserver/gameserver/model/actor/L2Character.java
190
===================================================================
191
--- java/com/l2jserver/gameserver/model/actor/L2Character.java	(revision 5522)
192
+++ java/com/l2jserver/gameserver/model/actor/L2Character.java	(working copy)
193
@@ -41,6 +41,7 @@
194
 import com.l2jserver.gameserver.ai.L2CharacterAI;
195
 import com.l2jserver.gameserver.datatables.DoorTable;
196
 import com.l2jserver.gameserver.datatables.ItemTable;
197
+import com.l2jserver.gameserver.datatables.NpcTable;
198
 import com.l2jserver.gameserver.datatables.SkillTable;
199
 import com.l2jserver.gameserver.handler.ISkillHandler;
200
 import com.l2jserver.gameserver.handler.SkillHandler;
201
@@ -186,6 +187,7 @@
202
 	private double _hpUpdateIncCheck = .0;
203
 	private double _hpUpdateDecCheck = .0;
204
 	private double _hpUpdateInterval = .0;
205
+	private L2WeaponType _weaponType = null; // If this is null, it will be initialized when getWeaponType() is called.
206
 	
207
 	/** Table of Calculators containing all used calculator */
208
 	private Calculator[] _calculators;
209
@@ -838,6 +840,12 @@
210
 			}
211
 		}
212
 		
213
+		if (getWeaponType() == L2WeaponType.FISHINGROD)
214
+		{
215
+			sendPacket(SystemMessageId.CANNOT_ATTACK_WITH_FISHING_POLE);
216
+			sendPacket(ActionFailed.STATIC_PACKET);
217
+			return;
218
+		}
219
 		
220
 		// Check if attacker's weapon can attack
221
 		if (getActiveWeaponItem() != null)
222
@@ -845,10 +853,7 @@
223
 			L2Weapon wpn = getActiveWeaponItem();
224
 			if (!wpn.isAttackWeapon() && !isGM())
225
 			{
226
-				if (wpn.getItemType() == L2WeaponType.FISHINGROD)
227
-					sendPacket(SystemMessageId.CANNOT_ATTACK_WITH_FISHING_POLE);
228
-				else
229
-					sendPacket(SystemMessageId.THAT_WEAPON_CANT_ATTACK);
230
+				sendPacket(SystemMessageId.THAT_WEAPON_CANT_ATTACK);
231
 				sendPacket(ActionFailed.STATIC_PACKET);
232-
 		}
232+
 				return;
233
 			}
234
@@ -906,9 +911,9 @@
235
 		}
236
 		
237
 		// BOW and CROSSBOW checks
238
-		if (weaponItem != null && !isTransformed())
239
+		if (!isTransformed())
240
 		{
241
-			if (weaponItem.getItemType() == L2WeaponType.BOW)
242
+			if (getWeaponType() == L2WeaponType.BOW)
243
 			{
244
 				//Check for arrows and MP
245
 				if (isPlayer())
246
@@ -936,26 +941,29 @@
247
 					if (_disableBowAttackEndTime <= GameTimeController.getGameTicks())
248
 					{
249
 						// Verify if L2PcInstance owns enough MP
250
-						int mpConsume = weaponItem.getMpConsume();
251
-						if (weaponItem.getReducedMpConsume() > 0 && Rnd.get(100) < weaponItem.getReducedMpConsumeChance())
252
-						{
253
-							mpConsume = weaponItem.getReducedMpConsume();
254
-						}
255
-						mpConsume = (int) calcStat(Stats.BOW_MP_CONSUME_RATE, mpConsume, null, null);
256
-						
257
-						if (getCurrentMp() < mpConsume)
258
+						if (weaponItem != null)
259
 						{
260
-							// If L2PcInstance doesn't have enough MP, stop the attack
261
-							ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
262
-							sendPacket(SystemMessageId.NOT_ENOUGH_MP);
263
-							sendPacket(ActionFailed.STATIC_PACKET);
264
-							return;
265
+							int mpConsume = weaponItem.getMpConsume();
266
+							if (weaponItem.getReducedMpConsume() > 0 && Rnd.get(100) < weaponItem.getReducedMpConsumeChance())
267
+							{
268
+								mpConsume = weaponItem.getReducedMpConsume();
269
+							}
270
+							mpConsume = (int) calcStat(Stats.BOW_MP_CONSUME_RATE, mpConsume, null, null);
271
+							
272
+							if (getCurrentMp() < mpConsume)
273
+							{
274
+								// If L2PcInstance doesn't have enough MP, stop the attack
275
+								ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
276
+								sendPacket(SystemMessageId.NOT_ENOUGH_MP);
277
+								sendPacket(ActionFailed.STATIC_PACKET);
278
+								return;
279
+							}
280
+							
281
+							// If L2PcInstance have enough MP, the bow consumes it
282
+							if (mpConsume > 0)
283
+								getStatus().reduceMp(mpConsume);
284
 						}
285
 						
286
-						// If L2PcInstance have enough MP, the bow consumes it
287
-						if (mpConsume > 0)
288
-							getStatus().reduceMp(mpConsume);
289
-						
290
 						// Set the period of bow no re-use
291
 						_disableBowAttackEndTime = 5 * GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
292
 					}
293
@@ -968,7 +976,7 @@
294
 					}
295
 				}
296
 			}
297
-			if (weaponItem.getItemType() == L2WeaponType.CROSSBOW)
298
+			if (getWeaponType() == L2WeaponType.CROSSBOW)
299
 			{
300
 				//Check for bolts
301
 				if (isPlayer())
302
@@ -996,26 +1004,29 @@
303
 					if (_disableCrossBowAttackEndTime <= GameTimeController.getGameTicks())
304
 					{
305
 						// Verify if L2PcInstance owns enough MP
306
-						int mpConsume = weaponItem.getMpConsume();
307
-						if (weaponItem.getReducedMpConsume() > 0 && Rnd.get(100) < weaponItem.getReducedMpConsumeChance())
308
+						if (weaponItem != null)
309
 						{
310
-							mpConsume = weaponItem.getReducedMpConsume();
311
-						}
312
-						mpConsume = (int) calcStat(Stats.BOW_MP_CONSUME_RATE, mpConsume, null, null);
313
-						
314
-						if (getCurrentMp() < mpConsume)
315
-						{
316
-							// If L2PcInstance doesn't have enough MP, stop the attack
317
-							ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
318
-							sendPacket(SystemMessageId.NOT_ENOUGH_MP);
319
-							sendPacket(ActionFailed.STATIC_PACKET);
320
-							return;
321
+							int mpConsume = weaponItem.getMpConsume();
322
+							if (weaponItem.getReducedMpConsume() > 0 && Rnd.get(100) < weaponItem.getReducedMpConsumeChance())
323
+							{
324
+								mpConsume = weaponItem.getReducedMpConsume();
325
+							}
326
+							mpConsume = (int) calcStat(Stats.BOW_MP_CONSUME_RATE, mpConsume, null, null);
327
+							
328
+							if (getCurrentMp() < mpConsume)
329
+							{
330
+								// If L2PcInstance doesn't have enough MP, stop the attack
331
+								ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
332
+								sendPacket(SystemMessageId.NOT_ENOUGH_MP);
333
+								sendPacket(ActionFailed.STATIC_PACKET);
334
+								return;
335
+							}
336
+							
337
+							// If L2PcInstance have enough MP, the bow consumes it
338
+							if (mpConsume > 0)
339
+								getStatus().reduceMp(mpConsume);
340
 						}
341
 						
342
-						// If L2PcInstance have enough MP, the bow consumes it
343
-						if (mpConsume > 0)
344
-							getStatus().reduceMp(mpConsume);
345
-						
346
 						// Set the period of crossbow no re-use
347
 						_disableCrossBowAttackEndTime = 5 * GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
348
 					}
349
@@ -1063,7 +1074,7 @@
350
 		}
351
 		
352
 		// Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
353
-		int timeAtk = calculateTimeBetweenAttacks(target, weaponItem);
354
+		int timeAtk = calculateTimeBetweenAttacks(target);
355
 		
356
 		// the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case
357
 		int timeToHit = timeAtk / 2;
358
@@ -1089,18 +1100,31 @@
359
 		int reuse = calculateReuseTime(target, weaponItem);
360
 		boolean hitted;
361
 		// Select the type of attack to start
362
-		if (weaponItem == null || isTransformed())
363
+		if (isTransformed())
364
 			hitted = doAttackHitSimple(attack, target, timeToHit);
365
-		else if (weaponItem.getItemType() == L2WeaponType.BOW)
366
-			hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
367
-		else if (weaponItem.getItemType() == L2WeaponType.CROSSBOW)
368
-			hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
369
-		else if (weaponItem.getItemType() == L2WeaponType.POLE)
370
-			hitted = doAttackHitByPole(attack, target, timeToHit);
371
-		else if (isUsingDualWeapon())
372
-			hitted = doAttackHitByDual(attack, target, timeToHit);
373
 		else
374
-			hitted = doAttackHitSimple(attack, target, timeToHit);
375
+		{
376
+			switch (getWeaponType())
377
+			{
378
+				case BOW:
379
+					hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
380
+					break;
381
+				case CROSSBOW:
382
+					hitted = doAttackHitByCrossBow(attack, target, timeAtk, reuse);
383
+					break;
384
+				case POLE:
385
+					hitted = doAttackHitByPole(attack, target, timeToHit);
386
+					break;
387
+				case DUAL:
388
+				case DUALFIST:
389
+				case DUALDAGGER:
390
+					hitted = doAttackHitByDual(attack, target, timeToHit);
391
+					break;
392
+				default:
393
+					hitted = doAttackHitSimple(attack, target, timeToHit);
394
+					break;
395
+			}
396
+		}
397
 		
398
 		// Flag the attacker if it's a L2PcInstance outside a PvP area
399
 		L2PcInstance player = getActingPlayer();
400
@@ -5388,6 +5412,58 @@
401
 		// Dummy method (overridden by players and pets)
402
 	}
403
 	
404
+	public L2WeaponType getWeaponType()
405
+	{
406
+		if (_weaponType == null)
407
+		{
408
+			synchronized (this)
409
+			{
410
+				if (_weaponType == null)
411
+					setWeaponType();
412
+			}
413
+		}
414
+		
415
+		return _weaponType;
416
+	}
417
+	
418
+	/**
419
+	 * Sets the weapon type to the default weapon type of this character.
420
+	 */
421
+	public void setWeaponType()
422
+	{
423
+		if (isPlayer())
424
+			_weaponType = getActingPlayer().getActiveWeaponItem().getItemType();
425
+		else if (isNpc())
426
+		{
427
+			L2NpcTemplate tmpl = NpcTable.getInstance().getTemplate(((L2Npc)this).getNpcId());
428
+			if (tmpl != null)
429
+				_weaponType = tmpl.getBaseAttackType();
430
+		}
431
+		else if (isSummon())
432
+		{
433
+			L2NpcTemplate tmpl = NpcTable.getInstance().getTemplate(((L2Summon)this).getNpcId());
434
+			if (tmpl != null)
435
+				_weaponType = tmpl.getBaseAttackType();
436
+		}
437
+		
438
+		// If the weapon type is still somehow null.
439
+		if (_weaponType == null)
440
+			_weaponType = L2WeaponType.NONE;
441
+	}
442
+	
443
+	public void setWeaponType(L2WeaponType weaponType)
444
+	{
445
+		_weaponType = weaponType;
446
+	}
447
+	
448
+	public void setWeaponType(L2ItemInstance item)
449
+	{
450
+		if (item != null && item.isWeapon())
451
+			_weaponType = (L2WeaponType)item.getItemType();
452
+		else
453
+			_weaponType = null;
454
+	}
455
+	
456
 	/**
457
 	 * <B><U> Overridden in </U> :</B><BR><BR>
458
 	 * <li> L2PcInstance</li><BR><BR>
459
@@ -5512,8 +5588,7 @@
460
 			
461
 			if (!miss && damage > 0)
462
 			{
463
-				L2Weapon weapon = getActiveWeaponItem();
464
-				boolean isBow = (weapon != null && (weapon.getItemType() == L2WeaponType.BOW || weapon.getItemType() == L2WeaponType.CROSSBOW));
465
+				boolean isBow = isUsingRangedWeapon();
466
 				int reflectedDamage = 0;
467
 				
468
 				if (!isBow && !target.isInvul()) // Do not reflect if weapon is of type bow or target is invunlerable
469
@@ -5854,16 +5929,15 @@
470
 	}
471
 	
472
 	/**
473
-	 * @param target 
474
-	 * @param weapon 
475
+	 * @param target
476
 	 * @return the Attack Speed of the L2Character (delay (in milliseconds) before next attack).
477
 	 */
478
-	public int calculateTimeBetweenAttacks(L2Character target, L2Weapon weapon)
479
+	public int calculateTimeBetweenAttacks(L2Character target)
480
 	{
481
 		double atkSpd = 0;
482
-		if (weapon != null && !isTransformed())
483
+		if (!isTransformed())
484
 		{
485
-			switch (weapon.getItemType())
486
+			switch (target.getWeaponType())
487
 			{
488
 				case BOW:
489
 					atkSpd = getStat().getPAtkSpd();
490
@@ -5912,7 +5986,31 @@
491
 	 */
492
 	public boolean isUsingDualWeapon()
493
 	{
494
-		return false;
495
+		switch (getWeaponType())
496
+		{
497
+			case DUAL:
498
+			case DUALFIST:
499
+			case DUALDAGGER:
500
+				return true;
501
+			default:
502
+				return false;
503
+		}
504
+	}
505
+	
506
+	/**
507
+	 * @return True if the L2Character use BOW or CROSSBOW
508
+	 */
509
+	public boolean isUsingRangedWeapon()
510
+	{
511
+		switch (getWeaponType())
512
+		{
513
+			case DUAL:
514
+			case DUALFIST:
515
+			case DUALDAGGER:
516
+				return true;
517
+			default:
518
+				return false;
519
+		}
520
 	}
521
 	
522
 	/**
523
Index: java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java
524
===================================================================
525
--- java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(revision 5522)
526
+++ java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
527
@@ -6906,25 +6906,6 @@
528
 		return false;
529
 	}
530
 	
531
-	/**
532
-	 * Return True if the L2PcInstance use a dual weapon.<BR><BR>
533
-	 */
534
-	@Override
535
-	public boolean isUsingDualWeapon()
536
-	{
537
-		L2Weapon weaponItem = getActiveWeaponItem();
538
-		if (weaponItem == null) return false;
539
-		
540
-		if (weaponItem.getItemType() == L2WeaponType.DUAL)
541
-			return true;
542
-		else if (weaponItem.getItemType() == L2WeaponType.DUALFIST)
543
-			return true;
544
-		else if (weaponItem.getItemType() == L2WeaponType.DUALDAGGER)
545
-			return true;
546
-		else
547
-			return false;
548
-	}
549
-	
550
 	public void setUptime(long time)
551
 	{
552
 		_uptime = time;
553
Index: java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java
554
===================================================================
555
--- java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java	(revision 5522)
556
+++ java/com/l2jserver/gameserver/model/itemcontainer/Inventory.java	(working copy)
557
@@ -152,11 +152,11 @@
558
 		}
559
 	}
560
 	
561
-	private static final class BowCrossRodListener implements PaperdollListener
562
+	private static final class WeaponListener implements PaperdollListener
563
 	{
564
-		private static BowCrossRodListener instance = new BowCrossRodListener();
565
+		private static WeaponListener instance = new WeaponListener();
566
 		
567
-		public static BowCrossRodListener getInstance()
568
+		public static WeaponListener getInstance()
569
 		{
570
 			return instance;
571
 		}
572
@@ -188,6 +188,9 @@
573
 				if (lure != null)
574
 					inventory.setPaperdollItem(PAPERDOLL_LHAND, null);
575
 			}
576
+			
577
+			// Reset the weapon type to the default weapon type.
578
+			inventory.getOwner().setWeaponType();
579
 		}
580
 		
581
 		@Override
582
@@ -210,6 +213,9 @@
583
 				if (bolts != null)
584
 					inventory.setPaperdollItem(PAPERDOLL_LHAND, bolts);
585
 			}
586
+			
587
+			// Update the weapon type the owner is wearing.
588
+			inventory.getOwner().setWeaponType(item);
589
 		}
590
 	}
591
 	
592
@@ -729,7 +735,7 @@
593
 		if (this instanceof PcInventory)
594
 		{
595
 			addPaperdollListener(ArmorSetListener.getInstance());
596
-			addPaperdollListener(BowCrossRodListener.getInstance());
597
+			addPaperdollListener(WeaponListener.getInstance());
598
 			addPaperdollListener(ItemSkillsListener.getInstance());
599
 			addPaperdollListener(BraceletListener.getInstance());
600
 		}
601
Index: java/com/l2jserver/gameserver/network/clientpackets/MoveToLocationInAirShip.java
602
===================================================================
603
--- java/com/l2jserver/gameserver/network/clientpackets/MoveToLocationInAirShip.java	(revision 5522)
604
+++ java/com/l2jserver/gameserver/network/clientpackets/MoveToLocationInAirShip.java	(working copy)
605
@@ -17,7 +17,6 @@
606
 import com.l2jserver.gameserver.TaskPriority;
607
 import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
608
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
609
-import com.l2jserver.gameserver.model.items.type.L2WeaponType;
610
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
611
 import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationInAirShip;
612
 import com.l2jserver.gameserver.network.serverpackets.StopMoveInVehicle;
613
@@ -68,9 +67,7 @@
614
 			return;
615
 		}
616
 
617
-		if (activeChar.isAttackingNow()
618
-				&& activeChar.getActiveWeaponItem() != null
619
-				&& (activeChar.getActiveWeaponItem().getItemType() == L2WeaponType.BOW))
620
+		if (activeChar.isAttackingNow() && activeChar.isUsingRangedWeapon())
621
 		{
622
 			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
623
 			return;
624
Index: java/com/l2jserver/gameserver/network/clientpackets/UseItem.java
625
===================================================================
626
--- java/com/l2jserver/gameserver/network/clientpackets/UseItem.java	(revision 5522)
627
+++ java/com/l2jserver/gameserver/network/clientpackets/UseItem.java	(working copy)
628
@@ -337,8 +337,7 @@
629
 				return;
630
 			}
631
 			
632
-			final L2Weapon weaponItem = activeChar.getActiveWeaponItem();
633
-			if ((weaponItem != null && weaponItem.getItemType() == L2WeaponType.FISHINGROD) && ((_itemId >= 6519 && _itemId <= 6527) || (_itemId >= 7610 && _itemId <= 7613) || (_itemId >= 7807 && _itemId <= 7809) || (_itemId >= 8484 && _itemId <= 8486) || (_itemId >= 8505 && _itemId <= 8513)))
634
+			if ((activeChar.getWeaponType() == L2WeaponType.FISHINGROD) && ((_itemId >= 6519 && _itemId <= 6527) || (_itemId >= 7610 && _itemId <= 7613) || (_itemId >= 7807 && _itemId <= 7809) || (_itemId >= 8484 && _itemId <= 8486) || (_itemId >= 8505 && _itemId <= 8513)))
635
 			{
636
 				activeChar.getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, item);
637
 				activeChar.broadcastUserInfo();
638
Index: java/com/l2jserver/gameserver/network/clientpackets/RequestMoveToLocationInVehicle.java
639
===================================================================
640
--- java/com/l2jserver/gameserver/network/clientpackets/RequestMoveToLocationInVehicle.java	(revision 5522)
641
+++ java/com/l2jserver/gameserver/network/clientpackets/RequestMoveToLocationInVehicle.java	(working copy)
642
@@ -19,7 +19,6 @@
643
 import com.l2jserver.gameserver.instancemanager.BoatManager;
644
 import com.l2jserver.gameserver.model.actor.instance.L2BoatInstance;
645
 import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
646
-import com.l2jserver.gameserver.model.items.type.L2WeaponType;
647
 import com.l2jserver.gameserver.network.SystemMessageId;
648
 import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
649
 import com.l2jserver.gameserver.network.serverpackets.MoveToLocationInVehicle;
650
@@ -74,9 +73,7 @@
651
 			return;
652
 		}
653
 
654
-		if (activeChar.isAttackingNow()
655
-				&& activeChar.getActiveWeaponItem() != null
656
-				&& (activeChar.getActiveWeaponItem().getItemType() == L2WeaponType.BOW))
657
+		if (activeChar.isAttackingNow() && activeChar.isUsingRangedWeapon())
658
 		{
659
 			activeChar.sendPacket(ActionFailed.STATIC_PACKET);
660
 			return;