From 0598f7e87ccc791223617f17f763c32729c7e614 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 25 Nov 2014 22:47:50 -0600 Subject: [PATCH] Fixed an issue that has surfaced with new code behaving how it should, breaking old code. Naked corpses were not despawning on their decay timers because of incorrect return logic on a database function Removed ClearCorpseItems as it is no longer necessary as corpses deleted items appropriately when they are removed from the corpse General cleanup of functions and variables in corpse code --- zone/corpse.cpp | 236 ++++++++++++++++++++++-------------- zone/corpse.h | 4 +- zone/lua_corpse.cpp | 2 +- zone/perl_player_corpse.cpp | 2 +- zone/zonedb.cpp | 10 -- zone/zonedb.h | 1 - 6 files changed, 150 insertions(+), 105 deletions(-) diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 8be978350..6572012bc 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -140,16 +140,58 @@ Corpse* Corpse::LoadFromDBData(uint32 in_dbid, uint32 in_charid, std::string in_ return pc; } -// To be used on NPC death and ZoneStateLoad -// Mongrel: added see_invis and see_invis_undead Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime) -// vesuvias - appearence fix -: Mob("Unnamed_Corpse","",0,0,in_npc->GetGender(),in_npc->GetRace(),in_npc->GetClass(),BT_Humanoid,//bodytype added - in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0, - in_npc->GetHeading(),in_npc->GetX(),in_npc->GetY(),in_npc->GetZ(),0, - in_npc->GetTexture(),in_npc->GetHelmTexture(), - 0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0xff,0,0,0,0,0,0,0,0,0), + : Mob("Unnamed_Corpse", // const char* in_name, + "", // const char* in_lastname, + 0, // int32 in_cur_hp, + 0, // int32 in_max_hp, + in_npc->GetGender(), // uint8 in_gender, + in_npc->GetRace(), // uint16 in_race, + in_npc->GetClass(), // uint8 in_class, + BT_Humanoid, // bodyType in_bodytype, + in_npc->GetDeity(), // uint8 in_deity, + in_npc->GetLevel(), // uint8 in_level, + in_npc->GetNPCTypeID(), // uint32 in_npctype_id, + in_npc->GetSize(), // float in_size, + 0, // float in_runspeed, + in_npc->GetHeading(), // float in_heading, + in_npc->GetX(), // float in_x_pos, + in_npc->GetY(), // float in_y_pos, + in_npc->GetZ(), // float in_z_pos, + 0, // uint8 in_light, + in_npc->GetTexture(), // uint8 in_texture, + in_npc->GetHelmTexture(), // uint8 in_helmtexture, + 0, // uint16 in_ac, + 0, // uint16 in_atk, + 0, // uint16 in_str, + 0, // uint16 in_sta, + 0, // uint16 in_dex, + 0, // uint16 in_agi, + 0, // uint16 in_int, + 0, // uint16 in_wis, + 0, // uint16 in_cha, + 0, // uint8 in_haircolor, + 0, // uint8 in_beardcolor, + 0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? + 0, // uint8 in_eyecolor2, + 0, // uint8 in_hairstyle, + 0, // uint8 in_luclinface, + 0, // uint8 in_beard, + 0, // uint32 in_drakkin_heritage, + 0, // uint32 in_drakkin_tattoo, + 0, // uint32 in_drakkin_details, + 0, // uint32 in_armor_tint[_MaterialCount], + 0xff, // uint8 in_aa_title, + 0, // uint8 in_see_invis, // see through invis/ivu + 0, // uint8 in_see_invis_undead, + 0, // uint8 in_see_hide, + 0, // uint8 in_see_improved_hide, + 0, // int32 in_hp_regen, + 0, // int32 in_mana_regen, + 0, // uint8 in_qglobal, + 0, // uint8 in_maxlevel, + 0 // uint32 in_scalerate +), corpse_decay_timer(in_decaytime), corpse_res_timer(0), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -157,7 +199,9 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP loot_cooldown_timer(10) { corpse_graveyard_timer.Disable(); + memset(item_tint, 0, sizeof(item_tint)); + is_corpse_changed = false; is_player_corpse = false; is_locked = false; @@ -396,7 +440,6 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob ( Save(); } -// solar: helper function for client corpse constructor std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot) { int bagindex; @@ -425,59 +468,59 @@ std::list Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 return returnlist; } -// To be called from LoadFromDBData -// Mongrel: added see_invis and see_invis_undead +/* Called from Database Load */ + Corpse::Corpse(uint32 in_dbid, uint32 in_charid, const char* in_charname, ItemList* in_itemlist, uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_plat, float in_x, float in_y, float in_z, float in_heading, float in_size, uint8 in_gender, uint16 in_race, uint8 in_class, uint8 in_deity, uint8 in_level, uint8 in_texture, uint8 in_helmtexture,uint32 in_rezexp, bool wasAtGraveyard) -: Mob("Unnamed_Corpse", -"", -0, -0, -in_gender, -in_race, -in_class, -BT_Humanoid, -in_deity, -in_level, -0, -in_size, -0, -in_heading, -in_x, -in_y, -in_z, -0, -in_texture, -in_helmtexture, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0xff, -0, -0, -0, -0, -0, -0, -0, -0, -0), + : Mob("Unnamed_Corpse", // const char* in_name, + "", // const char* in_lastname, + 0, // int32 in_cur_hp, + 0, // int32 in_max_hp, + in_gender, // uint8 in_gender, + in_race, // uint16 in_race, + in_class, // uint8 in_class, + BT_Humanoid, // bodyType in_bodytype, + in_deity, // uint8 in_deity, + in_level, // uint8 in_level, + 0, // uint32 in_npctype_id, + in_size, // float in_size, + 0, // float in_runspeed, + in_heading, // float in_heading, + in_x, // float in_x_pos, + in_y, // float in_y_pos, + in_z, // float in_z_pos, + 0, // uint8 in_light, + in_texture, // uint8 in_texture, + in_helmtexture, // uint8 in_helmtexture, + 0, // uint16 in_ac, + 0, // uint16 in_atk, + 0, // uint16 in_str, + 0, // uint16 in_sta, + 0, // uint16 in_dex, + 0, // uint16 in_agi, + 0, // uint16 in_int, + 0, // uint16 in_wis, + 0, // uint16 in_cha, + 0, // uint8 in_haircolor, + 0, // uint8 in_beardcolor, + 0, // uint8 in_eyecolor1, // the eyecolors always seem to be the same, maybe left and right eye? + 0, // uint8 in_eyecolor2, + 0, // uint8 in_hairstyle, + 0, // uint8 in_luclinface, + 0, // uint8 in_beard, + 0, // uint32 in_drakkin_heritage, + 0, // uint32 in_drakkin_tattoo, + 0, // uint32 in_drakkin_details, + 0, // uint32 in_armor_tint[_MaterialCount], + 0xff, // uint8 in_aa_title, + 0, // uint8 in_see_invis, // see through invis/ivu + 0, // uint8 in_see_invis_undead, + 0, // uint8 in_see_hide, + 0, // uint8 in_see_improved_hide, + 0, // int32 in_hp_regen, + 0, // int32 in_mana_regen, + 0, // uint8 in_qglobal, + 0, // uint8 in_maxlevel, + 0), // uint32 in_scalerate corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)), corpse_res_timer(RuleI(Character, CorpseResTimeMS)), corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)), @@ -487,8 +530,9 @@ in_helmtexture, LoadPlayerCorpseDecayTime(in_dbid); - if(!zone->HasGraveyard() || wasAtGraveyard) + if (!zone->HasGraveyard() || wasAtGraveyard){ corpse_graveyard_timer.Disable(); + } memset(item_tint, 0, sizeof(item_tint)); @@ -504,10 +548,12 @@ in_helmtexture, strcpy(orgname, in_charname); strcpy(name, in_charname); + this->copper = in_copper; this->silver = in_silver; this->gold = in_gold; this->platinum = in_plat; + rezzexp = in_rezexp; for (int i = 0; i < MAX_LOOTERS; i++){ @@ -757,16 +803,19 @@ void Corpse::RemoveCash() { bool Corpse::IsEmpty() const { if (copper != 0 || silver != 0 || gold != 0 || platinum != 0) return false; + return(itemlist.size() == 0); } bool Corpse::Process() { - if (player_corpse_depop) + if (player_corpse_depop){ return false; + } if(corpse_delay_timer.Check()) { - for (int i=0; iwrite(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName()); } - else - { + else { LogFile->write(EQEMuLog::Error, "Unable to bury %s player corpse.", this->GetName()); return true; } @@ -828,19 +885,22 @@ void Corpse::SetDecayTimer(uint32 decaytime) { corpse_decay_timer.Start(decaytime); } -bool Corpse::CanMobLoot(int charid) { - uint8 z=0; - for(int i=0; iCastToClient()->CharacterID(); } -// @merth: this function needs some work void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) { // Added 12/08. Started compressing loot struct on live. char tmp[10]; @@ -883,18 +942,18 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a } uint8 tCanLoot = 1; - bool lootcoin = false; - if(database.GetVariable("LootCoin", tmp, 9)) { lootcoin = (atoi(tmp) == 1); } + bool loot_coin = false; + if(database.GetVariable("LootCoin", tmp, 9)) { loot_coin = (atoi(tmp) == 1); } if(this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) { SendLootReqErrorPacket(client, 0); tCanLoot = 0; } else if(IsPlayerCorpse() && char_id == client->CharacterID()) { tCanLoot = 2; } - else if((IsNPCCorpse() || become_npc) && CanMobLoot(client->CharacterID())) { tCanLoot = 2; } - else if(GetPKItem() == -1 && CanMobLoot(client->CharacterID())) { tCanLoot = 3; } //pvp loot all items, variable cash - else if(GetPKItem() == 1 && CanMobLoot(client->CharacterID())) { tCanLoot = 4; } //pvp loot 1 item, variable cash - else if(GetPKItem() > 1 && CanMobLoot(client->CharacterID())) { tCanLoot = 5; } //pvp loot 1 set item, variable cash + else if((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) { tCanLoot = 2; } + else if(GetPKItem() == -1 && CanPlayerLoot(client->CharacterID())) { tCanLoot = 3; } //pvp loot all items, variable cash + else if(GetPKItem() == 1 && CanPlayerLoot(client->CharacterID())) { tCanLoot = 4; } //pvp loot 1 item, variable cash + else if(GetPKItem() > 1 && CanPlayerLoot(client->CharacterID())) { tCanLoot = 5; } //pvp loot 1 set item, variable cash if(tCanLoot == 1) { if(client->Admin() < 100 || !client->GetGM()) { SendLootReqErrorPacket(client, 2); } } @@ -906,7 +965,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a d->response = 1; d->unknown1 = 0x42; d->unknown2 = 0xef; - if(tCanLoot == 2 || (tCanLoot >= 3 && lootcoin)) { // dont take the coin off if it's a gm peeking at the corpse + if(tCanLoot == 2 || (tCanLoot >= 3 && loot_coin)) { // dont take the coin off if it's a gm peeking at the corpse if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) { d->copper = 0; @@ -951,8 +1010,6 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a cur = itemlist.begin(); end = itemlist.end(); - uint8 containercount = 0; - int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, client->GetClientVersion()); for(; cur != end; ++cur) { @@ -1045,7 +1102,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { SendEndLootErrorPacket(client); return; } - if (IsPlayerCorpse() && !CanMobLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) { + if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) { client->Message(13, "Error: This is a player corpse and you dont own it."); SendEndLootErrorPacket(client); return; @@ -1055,7 +1112,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) { client->Message(13, "Error: Corpse locked by GM."); return; } - if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanMobLoot(client->CharacterID()) && GetPKItem() == 0){ + if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPKItem() == 0){ client->Message(13, "Error: You cannot loot any more items from this corpse."); SendEndLootErrorPacket(client); being_looted_by = 0xFFFFFFFF; @@ -1222,7 +1279,6 @@ void Corpse::EndLoot(Client* client, const EQApplicationPacket* app) { client->QueuePacket(outapp); safe_delete(outapp); - //client->Save(); //inventory operations auto-commit this->being_looted_by = 0xFFFFFFFF; if (this->IsEmpty()) Delete(); diff --git a/zone/corpse.h b/zone/corpse.h index f365dd041..4f0e96d05 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -69,7 +69,7 @@ public: inline uint32 GetDBID() { return corpse_db_id; } inline char* GetOwnerName() { return orgname;} - void SetDecayTimer(uint32 decaytime); + void SetDecayTimer(uint32 decay_time); bool IsEmpty() const; void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0); uint32 GetWornItem(int16 equipSlot) const; @@ -99,7 +99,7 @@ public: void CompleteRezz(); void SetPKItem(int32 id) { player_kill_item = id; } int32 GetPKItem() { return player_kill_item; } - bool CanMobLoot(int charid); + bool CanPlayerLoot(int charid); void AllowMobLoot(Mob *them, uint8 slot); void AddLooter(Mob *who); bool IsRezzed() { return rez; } diff --git a/zone/lua_corpse.cpp b/zone/lua_corpse.cpp index beada7e9a..5862bbe96 100644 --- a/zone/lua_corpse.cpp +++ b/zone/lua_corpse.cpp @@ -114,7 +114,7 @@ void Lua_Corpse::SetDecayTimer(uint32 decaytime) { bool Lua_Corpse::CanMobLoot(int charid) { Lua_Safe_Call_Bool(); - return self->CanMobLoot(charid); + return self->CanPlayerLoot(charid); } void Lua_Corpse::AllowMobLoot(Lua_Mob them, uint8 slot) { diff --git a/zone/perl_player_corpse.cpp b/zone/perl_player_corpse.cpp index af5c79f16..f8b2d4388 100644 --- a/zone/perl_player_corpse.cpp +++ b/zone/perl_player_corpse.cpp @@ -687,7 +687,7 @@ XS(XS_Corpse_CanMobLoot) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->CanMobLoot(charid); + RETVAL = THIS->CanPlayerLoot(charid); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 11d76e4af..8794f3570 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3937,15 +3937,6 @@ uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { return 0; } -bool ZoneDatabase::ClearCorpseItems(uint32 db_id){ - std::string query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u", db_id); - auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0){ - return true; - } - return false; -} - bool ZoneDatabase::DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id){ std::string query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u AND equip_slot = %u AND item_id = %u", db_id, equip_slot, item_id); auto results = QueryDatabase(query); @@ -3959,7 +3950,6 @@ bool ZoneDatabase::BuryCharacterCorpse(uint32 db_id) { std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1 WHERE `id` = %u", db_id); auto results = QueryDatabase(query); if (results.Success() && results.RowsAffected() != 0){ - ClearCorpseItems(db_id); return true; } return false; diff --git a/zone/zonedb.h b/zone/zonedb.h index 33554aac3..3f8719946 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -295,7 +295,6 @@ public: bool NoRentExpired(const char* name); /* Corpses */ - bool ClearCorpseItems(uint32 db_id); bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id); uint32 GetCharacterCorpseItemCount(uint32 corpse_id); bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs);