mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-03 23:03:51 +00:00
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
This commit is contained in:
parent
b4862dea45
commit
0598f7e87c
236
zone/corpse.cpp
236
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<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16 equipslot)
|
||||
{
|
||||
int bagindex;
|
||||
@ -425,59 +468,59 @@ std::list<uint32> 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; i<MAX_LOOTERS; i++)
|
||||
for (int i = 0; i < MAX_LOOTERS; i++){
|
||||
allowed_looters[i] = 0;
|
||||
}
|
||||
corpse_delay_timer.Disable();
|
||||
return true;
|
||||
}
|
||||
@ -798,9 +847,18 @@ bool Corpse::Process() {
|
||||
corpse_res_timer.Disable();
|
||||
}
|
||||
*/
|
||||
|
||||
/* This is when a corpse hits decay timer and does checks*/
|
||||
if(corpse_decay_timer.Check()) {
|
||||
if(!RuleB(Zone, EnableShadowrest))
|
||||
/* NPC */
|
||||
if (IsNPCCorpse()){
|
||||
corpse_decay_timer.Disable();
|
||||
return false;
|
||||
}
|
||||
/* Client */
|
||||
if (!RuleB(Zone, EnableShadowrest)){
|
||||
Delete();
|
||||
}
|
||||
else {
|
||||
if(database.BuryCharacterCorpse(corpse_db_id)) {
|
||||
Save();
|
||||
@ -808,8 +866,7 @@ bool Corpse::Process() {
|
||||
corpse_db_id = 0;
|
||||
LogFile->write(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; i<MAX_LOOTERS; i++) {
|
||||
if(allowed_looters[i] != 0)
|
||||
z++;
|
||||
bool Corpse::CanPlayerLoot(int charid) {
|
||||
uint8 looters = 0;
|
||||
for(int i = 0; i < MAX_LOOTERS; i++) {
|
||||
if (allowed_looters[i] != 0){
|
||||
looters++;
|
||||
}
|
||||
|
||||
if (allowed_looters[i] == charid)
|
||||
if (allowed_looters[i] == charid){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(z == 0)
|
||||
/* If we have no looters, obviously client can loot */
|
||||
if (looters == 0){
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Corpse::AllowMobLoot(Mob *them, uint8 slot) {
|
||||
@ -852,7 +912,6 @@ void Corpse::AllowMobLoot(Mob *them, uint8 slot) {
|
||||
allowed_looters[slot] = them->CastToClient()->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();
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user