Here is the replacement for the method that handles the 'RespawnFromHover' issue. It is currently set to recognize SoF and
higher clients when hover is set to true. This client was noted in the PEQ database and this is coded as such.
Code:
Corpse::Corpse(Client* client, sint32 in_rezexp)
// vesuvias - appearence fix
: Mob
(
"Unnamed_Corpse",
"",
0,
0,
client->GetGender(),
client->GetRace(),
client->GetClass(),
BT_Humanoid, // bodytype added
client->GetDeity(),
client->GetLevel(),
0,
client->GetSize(),
0,
client->GetHeading(), // heading
client->GetX(),
client->GetY(),
client->GetZ(),
0,
client->GetTexture(),
client->GetHelmTexture(),
0, // AC
0,
0,
0,
0,
0,
0,
0,
0, // CHA
client->GetPP().haircolor,
client->GetPP().beardcolor,
client->GetPP().eyecolor1,
client->GetPP().eyecolor2,
client->GetPP().hairstyle,
client->GetPP().face,
client->GetPP().beard,
client->GetPP().drakkin_heritage,
client->GetPP().drakkin_tattoo,
client->GetPP().drakkin_details,
0,
0xff, // aa title
0,
0,
0,
0,
0,
0,
0, // qglobal
0, // maxlevel
0 // scalerate
),
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
corpse_res_timer(RuleI(Character, CorpseResTimeMS)),
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
corpse_graveyard_timer(RuleI(Zone, GraveyardTimeMS)),
loot_cooldown_timer(10)
{
int i;
PlayerProfile_Struct *pp = &client->GetPP();
ItemInst *item;
if(!zone->HasGraveyard()) {
corpse_graveyard_timer.Disable();
}
memset(item_tint, 0, sizeof(item_tint));
for (i=0; i<MAX_LOOTERS; i++)
looters[i] = 0;
pIsChanged = true;
rezzexp = in_rezexp;
can_rez = true;
p_PlayerCorpse = true;
pLocked = false;
BeingLootedBy = 0xFFFFFFFF;
charid = client->CharacterID();
dbid = 0;
p_depop = false;
copper = 0;
silver = 0;
gold = 0;
platinum = 0;
strcpy(orgname, pp->name);
strcpy(name, pp->name);
//become_npc was not being initialized which led to some pretty funky things with newly created corpses
become_npc = false;
SetPKItem(0);
if(!RuleB(Character, LeaveNakedCorpses) || RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) {
// cash
SetCash(pp->copper, pp->silver, pp->gold, pp->platinum);
pp->copper = 0;
pp->silver = 0;
pp->gold = 0;
pp->platinum = 0;
// need to tell client that cash has changed... issue looks like a money duplication error,
// but server value is actually correct. (think it is 'RespawnFromHover' related.)
// get their tints
memcpy(item_tint, &client->GetPP().item_tint, sizeof(item_tint));
// solar: TODO soulbound items need not be added to corpse, but they need
// to go into the regular slots on the player, out of bags
// personal and cursor bag slots (251-340) are moved to corpse..should be deleting db entries
// too. reworked code to return and merge a list for the delete query builder instead of adding
// MoveItemToCorpse code to each loop.
// worn + inventory + cursor
std::list<uint32> removed_list;
bool cursor = false;
for(i = 0; i <= 30; i++)
{
item = client->GetInv().GetItem(i);
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent))
{
removed_list.merge(MoveItemToCorpse(client, item, i));
}
}
// cursor queue // change to first client that supports 'death hover' mode, if not SoF.
if (!RuleB(Character, RespawnFromHover) || client->GetClientVersion() < EQClientSoF) {
// bumped starting assignment to 8001 because any in-memory 'slot 8000' item was moved above as 'slot 30'
// this was mainly for client profile state reflection..should match db player inventory entries now.
iter_queue it;
for(it=client->GetInv().cursor_begin(),i=8001; it!=client->GetInv().cursor_end(); it++,i++) {
item = *it;
if((item && (!client->IsBecomeNPC())) || (item && client->IsBecomeNPC() && !item->GetItem()->NoRent))
{
removed_list.merge(MoveItemToCorpse(client, item, i));
cursor = true;
}
}
}
if(removed_list.size() != 0) {
std::stringstream ss("");
ss << "DELETE FROM inventory WHERE charid=" << client->CharacterID();
ss << " AND (";
std::list<uint32>::const_iterator iter = removed_list.begin();
bool first = true;
while(iter != removed_list.end()) {
if(first) {
first = false;
} else {
ss << " OR ";
}
ss << "slotid=" << (*iter);
iter++;
}
ss << ")";
database.RunQuery(ss.str().c_str(), ss.str().length());
}
if(cursor) { // all cursor items should be on corpse (client < SoF or RespawnFromHover = false)
while(!client->GetInv().CursorEmpty())
client->DeleteItemInInventory(SLOT_CURSOR, 0, false, false);
}
else { // only visible cursor made it to corpse (client >= Sof and RespawnFromHover = true)
std::list<ItemInst*>::const_iterator start = client->GetInv().cursor_begin();
std::list<ItemInst*>::const_iterator finish = client->GetInv().cursor_end();
database.SaveCursor(client->CharacterID(), start, finish);
}
// client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead
client->Save();
} //end "not leaving naked corpses"
Rezzed(false);
Save();
}