Selaa lähdekoodia

Fix for non-dual wielding classes being able to dual wield. Fixes issue #482

devn00b 1 vuosi sitten
vanhempi
commit
8827b79dcb

+ 49 - 1
EQ2/source/WorldServer/Items/Items.cpp

@@ -40,6 +40,7 @@ extern MasterRecipeList master_recipe_list;
 extern ConfigReader configReader;
 extern LuaInterface* lua_interface;
 extern RuleManager rule_manager;
+extern Classes classes;
 
 MasterItemList::MasterItemList(){
 	AddMappedItemStat(ITEM_STAT_ADORNING, std::string("adorning"));
@@ -1271,6 +1272,53 @@ bool Item::IsWeapon(){
 	return generic_info.item_type == ITEM_TYPE_WEAPON; 
 }
 
+bool Item::IsDualWieldAble(Client* client, Item* item, int8 slot) {
+
+	if (!item || !client || slot < 0) {
+		LogWrite(ITEM__DEBUG, 0, "Items", "Error in IsDualWieldAble. No Item, Client, or slot Passed");
+		return 0;
+	}
+
+	Player* player = client->GetPlayer();
+	int8 base_class = classes.GetBaseClass(player->GetAdventureClass());
+
+	//map out classes that can dw vs those that cant (did it this way so its easier to expand should we need to add classes later
+	int8 can_dw;
+	switch ((int)base_class) {
+	case 1:
+		can_dw = 1;
+		break;
+	case 5:
+		can_dw = 1;
+		break;
+	case 31:
+		can_dw = 1;
+		break;
+	case 35:
+		can_dw = 1;
+		break;
+	case 41:
+		can_dw = 1;
+		break;
+
+	default :
+		can_dw = 0;
+	}
+
+	//if mage, item is dw, and they are trying to put offhand. Not sure this will ever happen but figured I should cover it.
+	if (base_class == 21 && item->weapon_info->wield_type == ITEM_WIELD_TYPE_DUAL && slot == 1) {
+		return 0;
+	}
+
+	//if the item is main hand (single) and they are trying to put in in offhand.
+	//exceptions are classes 1, 5, 31, 35, 42 (fighter/brawler/rogue/bard/beastlord)
+	if (item->weapon_info->wield_type == ITEM_WIELD_TYPE_SINGLE && slot == 1 && can_dw != 1) {
+		return 0;
+	}
+//assume its safe if the above 2 if's arent hit.
+return 1;
+}
+
 bool Item::IsArmor(){ 
 	return generic_info.item_type == ITEM_TYPE_ARMOR || generic_info.item_type == ITEM_TYPE_SHIELD; 
 }
@@ -4355,4 +4403,4 @@ std::string MasterItemList::GetItemStatNameByID(int32 id)
 		return itr->second;
 
 	return std::string("");
-}
+}

+ 1 - 0
EQ2/source/WorldServer/Items/Items.h

@@ -985,6 +985,7 @@ public:
 	bool IsNormal();
 	bool IsWeapon();
 	bool IsArmor();
+	bool IsDualWieldAble(Client* client, Item* item, int8 slot = -1);
 	bool IsRanged();
 	bool IsBag();
 	bool IsFood();

+ 11 - 3
EQ2/source/WorldServer/Player.cpp

@@ -1670,10 +1670,18 @@ EQ2Packet* Player::SwapEquippedItems(int8 slot1, int8 slot2, int16 version, int1
 	}
 	return 0;
 }
-bool Player::CanEquipItem(Item* item) {
+bool Player::CanEquipItem(Item* item, int8 slot) {
 	if (item) {
 		Client* client = GetZone()->GetClientBySpawn(this);
 		if (client) {
+			if (item->IsWeapon() && slot == 1) {
+				bool dwable = item->IsDualWieldAble(client, item, slot);
+
+				if (dwable == 0) {
+					return false;
+				}
+			}
+
 			if (item->CheckFlag(EVIL_ONLY) && GetAlignment() != ALIGNMENT_EVIL) {
 					client->Message(0, "%s requires an evil race.", item->name.c_str());
 			}
@@ -1728,7 +1736,7 @@ vector<EQ2Packet*> Player::EquipItem(int16 index, int16 version, int8 appearance
 			return packets;
 		}
 		int8 slot = equipList->GetFreeSlot(item, slot_id);
-		bool canEquip = CanEquipItem(item);
+		bool canEquip = CanEquipItem(item,slot);
 		int32 conflictSlot = 0;
 		
 		if(canEquip && !appearance_type && item->CheckFlag2(APPEARANCE_ONLY))
@@ -6910,4 +6918,4 @@ void Player::GetSpellBookSlotSort(int32 pattern, int32* i, int8* page_book_count
 			break;
 		}
 	}
-}
+}

+ 1 - 1
EQ2/source/WorldServer/Player.h

@@ -496,7 +496,7 @@ public:
 	PlayerSkillList* GetSkills();
 	bool DamageEquippedItems(int8 amount = 10, Client* client = 0);
 	vector<EQ2Packet*>	EquipItem(int16 index, int16 version, int8 appearance_type, int8 slot_id = 255);
-	bool CanEquipItem(Item* item);
+	bool CanEquipItem(Item* item, int8 slot);
 	void SetEquippedItemAppearances();
 	vector<EQ2Packet*>	UnequipItem(int16 index, sint32 bag_id, int8 slot, int16 version, int8 appearance_type = 0, bool send_item_updates = true);
 	int8 ConvertSlotToClient(int8 slot, int16 version);