浏览代码

BETA: Unhardcoding flag functionality
- Added 3 new parameters into L2Weapon isForceEquip (Cannot be disarmed), isAttackWeapon (Disables attack), useWeaponSkillsOnly (Only skills that are assigned to the weapon can be used)
Note: All checks will not work for GM!

Rumen Nikiforov 13 年之前
父节点
当前提交
536bc675c1

+ 11 - 3
L2J_Server_BETA/java/com/l2jserver/gameserver/model/L2Object.java

@@ -568,7 +568,6 @@ public abstract class L2Object
 	 */
 	public final boolean isVisible()
 	{
-		//return getPosition().getWorldRegion() != null && _IsVisible;
 		return getPosition().getWorldRegion() != null;
 	}
 	public final void setIsVisible(boolean value)
@@ -602,6 +601,7 @@ public abstract class L2Object
 	{
 		return _name;
 	}
+	
 	public void setName(String value)
 	{
 		_name = value;
@@ -614,7 +614,8 @@ public abstract class L2Object
 	
 	public final ObjectPoly getPoly()
 	{
-		if (_poly == null) _poly = new ObjectPoly(this);
+		if (_poly == null)
+			_poly = new ObjectPoly(this);
 		return _poly;
 	}
 	
@@ -689,7 +690,14 @@ public abstract class L2Object
 	{
 		// default implementation
 	}
-	
+
+	/**
+	 * Not Implemented.<BR><BR>
+	 *
+	 * <B><U> Overridden in </U> :</B><BR><BR>
+	 * <li> L2PcInstance</li><BR><BR>
+	 * @param id 
+	 */
 	public void sendPacket(SystemMessageId id)
 	{
 		// default implementation

+ 47 - 18
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/L2Character.java

@@ -98,6 +98,7 @@ import com.l2jserver.gameserver.pathfinding.PathFinding;
 import com.l2jserver.gameserver.skills.AbnormalEffect;
 import com.l2jserver.gameserver.skills.Calculator;
 import com.l2jserver.gameserver.skills.Formulas;
+import com.l2jserver.gameserver.skills.SkillHolder;
 import com.l2jserver.gameserver.skills.Stats;
 import com.l2jserver.gameserver.skills.funcs.Func;
 import com.l2jserver.gameserver.skills.l2skills.L2SkillAgathion;
@@ -786,44 +787,48 @@ public abstract class L2Character extends L2Object
 			}
 		}
 		
+		
+		// Check if attacker's weapon can attack
+		if (getActiveWeaponItem() != null)
+		{
+			L2Weapon wpn = getActiveWeaponItem();
+			if (!wpn.isAttackWeapon())
+			{
+				sendPacket(SystemMessageId.THAT_WEAPON_CANT_ATTACK);
+				sendPacket(ActionFailed.STATIC_PACKET);
+				return;
+			}
+		}
+		
 		if (isAttackingDisabled())
 			return;
 		
-		if (this instanceof L2PcInstance)
+		if (getActingPlayer() != null)
 		{
-			if (((L2PcInstance) this).inObserverMode())
+			if (getActingPlayer().inObserverMode())
 			{
-				sendPacket(SystemMessage.getSystemMessage(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE));
+				sendPacket(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE);
 				sendPacket(ActionFailed.STATIC_PACKET);
 				return;
 			}
 			
-			if (target.getActingPlayer() != null && ((L2PcInstance) this).getSiegeState() > 0 && this.isInsideZone(L2Character.ZONE_SIEGE) && target.getActingPlayer().getSiegeState() == ((L2PcInstance) this).getSiegeState() && target.getActingPlayer() != this && target.getActingPlayer().getSiegeSide() == ((L2PcInstance) this).getSiegeSide())
+			else if (target.getActingPlayer() != null && getActingPlayer().getSiegeState() > 0 && isInsideZone(L2Character.ZONE_SIEGE) && target.getActingPlayer().getSiegeState() == getActingPlayer().getSiegeState() && target.getActingPlayer() != this && target.getActingPlayer().getSiegeSide() == getActingPlayer().getSiegeSide())
 			{
-				//
 				if (TerritoryWarManager.getInstance().isTWInProgress())
-					sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_ATTACK_A_MEMBER_OF_THE_SAME_TERRITORY));
+					sendPacket(SystemMessageId.YOU_CANNOT_ATTACK_A_MEMBER_OF_THE_SAME_TERRITORY);
 				else
-					sendPacket(SystemMessage.getSystemMessage(SystemMessageId.FORCED_ATTACK_IS_IMPOSSIBLE_AGAINST_SIEGE_SIDE_TEMPORARY_ALLIED_MEMBERS));
+					sendPacket(SystemMessageId.FORCED_ATTACK_IS_IMPOSSIBLE_AGAINST_SIEGE_SIDE_TEMPORARY_ALLIED_MEMBERS);
 				sendPacket(ActionFailed.STATIC_PACKET);
 				return;
 			}
 			
 			// Checking if target has moved to peace zone
-			if (target.isInsidePeaceZone((L2PcInstance) this))
+			else if (target.isInsidePeaceZone(getActingPlayer()))
 			{
 				getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
 				sendPacket(ActionFailed.STATIC_PACKET);
 				return;
 			}
-			// TODO: unhardcode this to support boolean if with that weapon u can attack or not (for ex transform weapons)
-			if (((L2PcInstance) this).getActiveWeaponItem() != null && ((L2PcInstance) this).getActiveWeaponItem().getItemId() == 9819)
-			{
-				sendPacket(SystemMessage.getSystemMessage(SystemMessageId.THAT_WEAPON_CANT_ATTACK));
-				sendPacket(ActionFailed.STATIC_PACKET);
-				return;
-			}
-			
 		}
 		else if (isInsidePeaceZone(this, target))
 		{
@@ -843,7 +848,7 @@ public abstract class L2Character extends L2Object
 		if (weaponItem != null && weaponItem.getItemType() == L2WeaponType.FISHINGROD)
 		{
 			//	You can't make an attack with a fishing pole.
-			sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANNOT_ATTACK_WITH_FISHING_POLE));
+			sendPacket(SystemMessageId.CANNOT_ATTACK_WITH_FISHING_POLE);
 			getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
 			
 			sendPacket(ActionFailed.STATIC_PACKET);
@@ -853,7 +858,7 @@ public abstract class L2Character extends L2Object
 		// GeoData Los Check here (or dz > 1000)
 		if (!GeoData.getInstance().canSeeTarget(this, target))
 		{
-			sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_SEE_TARGET));
+			sendPacket(SystemMessageId.CANT_SEE_TARGET);
 			getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
 			sendPacket(ActionFailed.STATIC_PACKET);
 			return;
@@ -2140,6 +2145,30 @@ public abstract class L2Character extends L2Object
 			return false;
 		}
 		
+		// Check if the caster's weapon is limited to use only its own skills
+		if (getActiveWeaponItem() != null)
+		{
+			L2Weapon wep = getActiveWeaponItem();
+			if (wep.useWeaponSkillsOnly() && !isGM())
+			{
+				boolean found = false;
+				for (SkillHolder sh : wep.getSkills())
+				{
+					if (sh.getSkillId() == skill.getId())
+					{
+						found = true;
+					}
+				}
+				
+				if (!found)
+				{
+					if (getActingPlayer() != null)
+						sendPacket(SystemMessageId.WEAPON_CAN_USE_ONLY_WEAPON_SKILL);
+					return false;
+				}
+			}
+		}
+		
 		// Check if the spell consumes an Item
 		// TODO: combine check and consume
 		if (skill.getItemConsumeId() > 0 && getInventory() != null)

+ 13 - 9
L2J_Server_BETA/java/com/l2jserver/gameserver/model/actor/instance/L2PcInstance.java

@@ -6603,14 +6603,24 @@ public final class L2PcInstance extends L2Playable
 	public boolean disarmWeapons()
 	{
 		// Don't allow disarming a cursed weapon
-		if (isCursedWeaponEquipped()) return false;
+		if (isCursedWeaponEquipped()) 
+			return false;
 		
 		// Don't allow disarming a Combat Flag or Territory Ward
-		if (isCombatFlagEquipped()) return false;
+		else if (isCombatFlagEquipped()) 
+			return false;
 		
 		// Unequip the weapon
 		L2ItemInstance wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
-		if (wpn != null)
+		if (wpn == null)
+		{
+			return false;
+		}
+		else if (wpn.getWeaponItem().isForceEquip())
+		{
+			return false;
+		}
+		else
 		{
 			L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
 			InventoryUpdate iu = new InventoryUpdate();
@@ -12935,12 +12945,6 @@ public final class L2PcInstance extends L2Playable
 		return _cursedWeaponEquippedId;
 	}
 	
-	@Override
-	public boolean isAttackingDisabled()
-	{
-		return (super.isAttackingDisabled() || _combatFlagEquippedId);
-	}
-	
 	public boolean isCombatFlagEquipped()
 	{
 		return _combatFlagEquippedId ;

+ 13 - 12
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestDestroyItem.java

@@ -33,7 +33,6 @@ import com.l2jserver.gameserver.util.Util;
 
 /**
  * This class ...
- *
  * @version $Revision: 1.7.2.4.2.6 $ $Date: 2005/03/27 15:29:30 $
  */
 public final class RequestDestroyItem extends L2GameClientPacket
@@ -58,10 +57,10 @@ public final class RequestDestroyItem extends L2GameClientPacket
 		if (activeChar == null)
 			return;
 		
-		if(_count <= 0)
+		if (_count <= 0)
 		{
 			if (_count < 0)
-				Util.handleIllegalPlayerAction(activeChar,"[RequestDestroyItem] Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " tried to destroy item with oid " + _objectId + " but has count < 0!", Config.DEFAULT_PUNISH);
+				Util.handleIllegalPlayerAction(activeChar, "[RequestDestroyItem] Character " + activeChar.getName() + " of account " + activeChar.getAccountName() + " tried to destroy item with oid " + _objectId + " but has count < 0!", Config.DEFAULT_PUNISH);
 			return;
 		}
 		
@@ -80,6 +79,7 @@ public final class RequestDestroyItem extends L2GameClientPacket
 		}
 		
 		L2ItemInstance itemToRemove = activeChar.getInventory().getItemByObjectId(_objectId);
+		
 		// if we can't find the requested item, its actually a cheat
 		if (itemToRemove == null)
 		{
@@ -132,13 +132,11 @@ public final class RequestDestroyItem extends L2GameClientPacket
 		if (_count > itemToRemove.getCount())
 			count = itemToRemove.getCount();
 		
-		
 		if (itemToRemove.isEquipped())
 		{
-			L2ItemInstance[] unequiped =
-				activeChar.getInventory().unEquipItemInSlotAndRecord(itemToRemove.getLocationSlot());
+			L2ItemInstance[] unequiped = activeChar.getInventory().unEquipItemInSlotAndRecord(itemToRemove.getLocationSlot());
 			InventoryUpdate iu = new InventoryUpdate();
-			for (L2ItemInstance item: unequiped)
+			for (L2ItemInstance item : unequiped)
 			{
 				activeChar.checkSShotsMatch(null, item);
 				
@@ -176,21 +174,24 @@ public final class RequestDestroyItem extends L2GameClientPacket
 		}
 		if (itemToRemove.isTimeLimitedItem())
 			itemToRemove.endOfLife();
+		
 		L2ItemInstance removedItem = activeChar.getInventory().destroyItem("Destroy", _objectId, count, activeChar, null);
 		
-		if(removedItem == null)
+		if (removedItem == null)
 			return;
 		
 		if (!Config.FORCE_INVENTORY_UPDATE)
 		{
 			InventoryUpdate iu = new InventoryUpdate();
-			if (removedItem.getCount() == 0) iu.addRemovedItem(removedItem);
-			else iu.addModifiedItem(removedItem);
+			if (removedItem.getCount() == 0)
+				iu.addRemovedItem(removedItem);
+			else
+				iu.addModifiedItem(removedItem);
 			
-			//client.getConnection().sendPacket(iu);
 			activeChar.sendPacket(iu);
 		}
-		else sendPacket(new ItemList(activeChar, true));
+		else
+			sendPacket(new ItemList(activeChar, true));
 		
 		StatusUpdate su = new StatusUpdate(activeChar);
 		su.addAttribute(StatusUpdate.CUR_LOAD, activeChar.getCurrentLoad());

+ 10 - 8
L2J_Server_BETA/java/com/l2jserver/gameserver/network/clientpackets/RequestUnEquipItem.java

@@ -27,7 +27,6 @@ import com.l2jserver.gameserver.templates.item.L2Item;
 
 /**
  * This class ...
- *
  * @version $Revision: 1.8.2.3.2.7 $ $Date: 2005/03/27 15:29:30 $
  */
 public class RequestUnEquipItem extends L2GameClientPacket
@@ -39,8 +38,7 @@ public class RequestUnEquipItem extends L2GameClientPacket
 	private int _slot;
 	
 	/**
-	 * packet type id 0x11
-	 * format:		cd
+	 * packet type id 0x11 format: cd
 	 */
 	@Override
 	protected void readImpl()
@@ -80,8 +78,7 @@ public class RequestUnEquipItem extends L2GameClientPacket
 		}
 		
 		// Prevent player from unequipping items in special conditions
-		if (activeChar.isStunned() || activeChar.isSleeping()
-				|| activeChar.isParalyzed() || activeChar.isAlikeDead())
+		if (activeChar.isStunned() || activeChar.isSleeping() || activeChar.isParalyzed() || activeChar.isAlikeDead())
 		{
 			activeChar.sendMessage("Your status does not allow you to do that.");
 			return;
@@ -95,13 +92,18 @@ public class RequestUnEquipItem extends L2GameClientPacket
 			return;
 		}
 		
-		L2ItemInstance[] unequiped =
-			activeChar.getInventory().unEquipItemInBodySlotAndRecord(_slot);
+		if (item.isWeapon() && item.getWeaponItem().isForceEquip() && !activeChar.isGM())
+		{
+			activeChar.sendPacket(SystemMessageId.ITEM_CANNOT_BE_TAKEN_OFF);
+			return;
+		}
+		
+		L2ItemInstance[] unequiped = activeChar.getInventory().unEquipItemInBodySlotAndRecord(_slot);
 		
 		// show the update in the inventory
 		InventoryUpdate iu = new InventoryUpdate();
 		
-		for (L2ItemInstance itm: unequiped)
+		for (L2ItemInstance itm : unequiped)
 		{
 			activeChar.checkSShotsMatch(null, itm);
 			

+ 23 - 0
L2J_Server_BETA/java/com/l2jserver/gameserver/templates/item/L2Weapon.java

@@ -66,6 +66,10 @@ public final class L2Weapon extends L2Item
 	
 	private final int _reuseDelay;
 	
+	private final boolean _isForceEquip;
+	private final boolean _isAttackWeapon;
+	private final boolean _useWeaponSkillsOnly;
+	
 	/**
 	 * Constructor for Weapon.<BR><BR>
 	 * <U><I>Variables filled :</I></U><BR>
@@ -181,6 +185,10 @@ public final class L2Weapon extends L2Item
 		}
 		
 		_changeWeaponId = set.getInteger("change_weaponId", 0);
+		
+		_isForceEquip = set.getBool("isForceEquip", false);
+		_isAttackWeapon = set.getBool("isAttackWeapon", true);
+		_useWeaponSkillsOnly = set.getBool("useWeaponSkillsOnly", false);
 	}
 	
 	/**
@@ -278,6 +286,21 @@ public final class L2Weapon extends L2Item
 		return _changeWeaponId;
 	}
 	
+	public boolean isForceEquip()
+	{
+		return _isForceEquip;
+	}
+	
+	public boolean isAttackWeapon()
+	{
+		return _isAttackWeapon;
+	}
+	
+	public boolean useWeaponSkillsOnly()
+	{
+		return _useWeaponSkillsOnly;
+	}
+	
 	/**
 	 * Returns array of Func objects containing the list of functions used by the weapon
 	 * @param instance : L2ItemInstance pointing out the weapon