void Corpse::RemoveItem(ServerLootItem_Struct* item_data) { for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) { auto sitem = *iter; if (sitem != item_data) { continue; } is_corpse_changed = true; itemlist.erase(iter); uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char if (material != _MaterialInvalid) SendWearChange(material); UpdateEquipmentLight(); if (UpdateActiveLight()) SendAppearancePacket(AT_Light, GetActiveLightType()); safe_delete(sitem); return; } }
//if itemlist is null, just send wear changes void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6) { if(item2 == nullptr) return; //make sure we are doing something... if(!itemlist && !wearchange) return; auto item = new ServerLootItem_Struct; #if EQDEBUG>=11 Log(Logs::General, Logs::None, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID); #endif EQApplicationPacket* outapp = nullptr; WearChange_Struct* wc = nullptr; if(wearchange) { outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); wc = (WearChange_Struct*)outapp->pBuffer; wc->spawn_id = GetID(); wc->material=0; } item->item_id = item2->ID; item->charges = charges; item->aug_1 = aug1; item->aug_2 = aug2; item->aug_3 = aug3; item->aug_4 = aug4; item->aug_5 = aug5; item->aug_6 = aug6; item->attuned = 0; item->min_level = minlevel; item->max_level = maxlevel; item->equip_slot = EQEmu::inventory::slotInvalid; if (equipit) { uint8 eslot = 0xFF; char newid[20]; const EQEmu::ItemData* compitem = nullptr; bool found = false; // track if we found an empty slot we fit into int32 foundslot = -1; // for multi-slot items // Equip rules are as follows: // If the item has the NoPet flag set it will not be equipped. // An empty slot takes priority. The first empty one that an item can // fit into will be the one picked for the item. // AC is the primary choice for which item gets picked for a slot. // If AC is identical HP is considered next. // If an item can fit into multiple slots we'll pick the last one where // it is an improvement. if (!item2->NoPet) { for (int i = 0; !found && i < EQEmu::legacy::EQUIPMENT_SIZE; i++) { uint32 slots = (1 << i); if (item2->Slots & slots) { if(equipment[i]) { compitem = database.GetItem(equipment[i]); if (item2->AC > compitem->AC || (item2->AC == compitem->AC && item2->HP > compitem->HP)) { // item would be an upgrade // check if we're multi-slot, if yes then we have to keep // looking in case any of the other slots we can fit into are empty. if (item2->Slots != slots) { foundslot = i; } else { equipment[i] = item2->ID; foundslot = i; found = true; } } // end if ac } else { equipment[i] = item2->ID; foundslot = i; found = true; } } // end if (slots) } // end for } // end if NoPet // Possible slot was found but not selected. Pick it now. if (!found && foundslot >= 0) { equipment[foundslot] = item2->ID; found = true; } // @merth: IDFile size has been increased, this needs to change uint16 emat; if(item2->Material <= 0 || item2->Slots & (1 << EQEmu::inventory::slotPrimary | 1 << EQEmu::inventory::slotSecondary)) { memset(newid, 0, sizeof(newid)); for(int i=0;i<7;i++){ if (!isalpha(item2->IDFile[i])){ strn0cpy(newid, &item2->IDFile[i],6); i=8; } } emat = atoi(newid); } else { emat = item2->Material; } if (foundslot == EQEmu::inventory::slotPrimary) { if (item2->Proc.Effect != 0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); eslot = EQEmu::textures::weaponPrimary; if (item2->Damage > 0) { SendAddPlayerState(PlayerState::PrimaryWeaponEquipped); SetFacestab(true); } if (item2->IsType2HWeapon()) SetTwoHanderEquipped(true); } else if (foundslot == EQEmu::inventory::slotSecondary && (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) && (item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield)) { if (item2->Proc.Effect!=0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); eslot = EQEmu::textures::weaponSecondary; if (item2->Damage > 0) SendAddPlayerState(PlayerState::SecondaryWeaponEquipped); } else if (foundslot == EQEmu::inventory::slotHead) { eslot = EQEmu::textures::armorHead; } else if (foundslot == EQEmu::inventory::slotChest) { eslot = EQEmu::textures::armorChest; } else if (foundslot == EQEmu::inventory::slotArms) { eslot = EQEmu::textures::armorArms; } else if (foundslot == EQEmu::inventory::slotWrist1 || foundslot == EQEmu::inventory::slotWrist2) { eslot = EQEmu::textures::armorWrist; } else if (foundslot == EQEmu::inventory::slotHands) { eslot = EQEmu::textures::armorHands; } else if (foundslot == EQEmu::inventory::slotLegs) { eslot = EQEmu::textures::armorLegs; } else if (foundslot == EQEmu::inventory::slotFeet) { eslot = EQEmu::textures::armorFeet; } /* what was this about??? if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->Slots==24576) || (item2->Slots==8192) || (item2->Slots==16384)){ npc->d_melee_texture2=atoi(newid); wc->wear_slot_id=8; if (item2->Material >0) wc->material=item2->Material; else wc->material=atoi(newid); npc->AC+=item2->AC; npc->STR+=item2->STR; npc->INT+=item2->INT; } */ //if we found an open slot it goes in... if(eslot != 0xFF) { if(wearchange) { wc->wear_slot_id = eslot; wc->material = emat; } } if (found) { CalcBonuses(); // This is less than ideal for bulk adding of items item->equip_slot = foundslot; } } if(itemlist != nullptr) itemlist->push_back(item); else safe_delete(item); if(wearchange && outapp) { entity_list.QueueClients(this, outapp); safe_delete(outapp); } UpdateEquipmentLight(); if (UpdateActiveLight()) SendAppearancePacket(AT_Light, GetActiveLightType()); }