Rest of ZoneDB Corpse functions converted to new API

This commit is contained in:
Akkadius 2014-11-23 22:33:57 -06:00
parent ce248d83d6
commit c30850f00a
3 changed files with 73 additions and 141 deletions

View File

@ -183,19 +183,18 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
break; break;
} }
} }
if(IsEmpty()) if(IsEmpty()) {
{
corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000); corpse_decay_timer.SetTimer(RuleI(NPC,EmptyNPCCorpseDecayTimeMS)+1000);
} }
if(in_npc->HasPrivateCorpse()) if(in_npc->HasPrivateCorpse()) {
{
corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000); corpse_delay_timer.SetTimer(corpse_decay_timer.GetRemainingTime() + 1000);
} }
// Added By Hogie -- End // Added By Hogie -- End
for (int i=0; i<MAX_LOOTERS; i++) for (int i = 0; i < MAX_LOOTERS; i++){
looters[i] = 0; allowed_looters[i] = 0;
}
this->rezzexp = 0; this->rezzexp = 0;
} }
@ -262,13 +261,16 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
PlayerProfile_Struct *pp = &client->GetPP(); PlayerProfile_Struct *pp = &client->GetPP();
ItemInst *item; ItemInst *item;
/* Check if Zone has Graveyard First */
if(!zone->HasGraveyard()) { if(!zone->HasGraveyard()) {
corpse_graveyard_timer.Disable(); corpse_graveyard_timer.Disable();
} }
memset(item_tint, 0, sizeof(item_tint)); memset(item_tint, 0, sizeof(item_tint));
for (i=0; i < MAX_LOOTERS; i++)
looters[i] = 0; for (i = 0; i < MAX_LOOTERS; i++){
allowed_looters[i] = 0;
}
is_corpse_changed = true; is_corpse_changed = true;
rezzexp = in_rezexp; rezzexp = in_rezexp;
@ -283,14 +285,16 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
silver = 0; silver = 0;
gold = 0; gold = 0;
platinum = 0; platinum = 0;
strcpy(orgname, pp->name); strcpy(orgname, pp->name);
strcpy(name, 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 was not being initialized which led to some pretty funky things with newly created corpses */
become_npc = false; become_npc = false;
SetPKItem(0); SetPKItem(0);
/* Check Rule to see if we can leave corpses */
if(!RuleB(Character, LeaveNakedCorpses) || if(!RuleB(Character, LeaveNakedCorpses) ||
RuleB(Character, LeaveCorpses) && RuleB(Character, LeaveCorpses) &&
GetLevel() >= RuleI(Character, DeathItemLossLevel)) { GetLevel() >= RuleI(Character, DeathItemLossLevel)) {
@ -405,16 +409,13 @@ std::list<uint32> Corpse::MoveItemToCorpse(Client *client, ItemInst *item, int16
returnlist.push_back(equipslot); returnlist.push_back(equipslot);
// Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea. // Qualified bag slot iterations. processing bag slots that don't exist is probably not a good idea.
if(item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) // Limit the bag check to inventory and cursor slots. if(item->IsType(ItemClassContainer) && ((equipslot >= EmuConstants::GENERAL_BEGIN && equipslot <= MainCursor))) {
{ for(bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++) {
for(bagindex = SUB_BEGIN; bagindex <= EmuConstants::ITEM_CONTAINER_SIZE; bagindex++)
{
// For empty bags in cursor queue, slot was previously being resolved as SLOT_INVALID (-1) // For empty bags in cursor queue, slot was previously being resolved as SLOT_INVALID (-1)
interior_slot = Inventory::CalcSlotId(equipslot, bagindex); interior_slot = Inventory::CalcSlotId(equipslot, bagindex);
interior_item = client->GetInv().GetItem(interior_slot); interior_item = client->GetInv().GetItem(interior_slot);
if(interior_item) if(interior_item) {
{
AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4)); AddItem(interior_item->GetItem()->ID, interior_item->GetCharges(), interior_slot, interior_item->GetAugmentItemID(0), interior_item->GetAugmentItemID(1), interior_item->GetAugmentItemID(2), interior_item->GetAugmentItemID(3), interior_item->GetAugmentItemID(4));
returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex)); returnlist.push_back(Inventory::CalcSlotId(equipslot, bagindex));
client->DeleteItemInInventory(interior_slot, 0, true, false); client->DeleteItemInInventory(interior_slot, 0, true, false);
@ -485,13 +486,13 @@ in_helmtexture,
loot_cooldown_timer(10) loot_cooldown_timer(10)
{ {
//we really should be loading the decay timer here...
LoadPlayerCorpseDecayTime(in_dbid); LoadPlayerCorpseDecayTime(in_dbid);
if(!zone->HasGraveyard() || wasAtGraveyard) if(!zone->HasGraveyard() || wasAtGraveyard)
corpse_graveyard_timer.Disable(); corpse_graveyard_timer.Disable();
memset(item_tint, 0, sizeof(item_tint)); memset(item_tint, 0, sizeof(item_tint));
is_corpse_changed = false; is_corpse_changed = false;
is_player_corpse = true; is_player_corpse = true;
is_locked = false; is_locked = false;
@ -509,8 +510,10 @@ in_helmtexture,
this->gold = in_gold; this->gold = in_gold;
this->platinum = in_plat; this->platinum = in_plat;
rezzexp = in_rezexp; rezzexp = in_rezexp;
for (int i=0; i<MAX_LOOTERS; i++)
looters[i] = 0; for (int i = 0; i < MAX_LOOTERS; i++){
allowed_looters[i] = 0;
}
SetPKItem(0); SetPKItem(0);
} }
@ -535,10 +538,12 @@ the client does this too, so it's unchangable
void Corpse::CalcCorpseName() { void Corpse::CalcCorpseName() {
EntityList::RemoveNumbers(name); EntityList::RemoveNumbers(name);
char tmp[64]; char tmp[64];
if (is_player_corpse) if (is_player_corpse){
snprintf(tmp, sizeof(tmp), "'s corpse%d", GetID()); snprintf(tmp, sizeof(tmp), "'s corpse%d", GetID());
else }
else{
snprintf(tmp, sizeof(tmp), "`s_corpse%d", GetID()); snprintf(tmp, sizeof(tmp), "`s_corpse%d", GetID());
}
name[(sizeof(name) - 1) - strlen(tmp)] = 0; name[(sizeof(name) - 1) - strlen(tmp)] = 0;
strcat(name, tmp); strcat(name, tmp);
} }
@ -552,9 +557,6 @@ bool Corpse::Save() {
uint32 tmp = this->CountItems(); uint32 tmp = this->CountItems();
uint32 tmpsize = sizeof(PlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct)); uint32 tmpsize = sizeof(PlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct));
std::cout << "tmp: " << tmp << std::endl;
std::cout << "tmpsize: " << tmpsize << std::endl;
PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize]; PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize];
memset(dbpc, 0, tmpsize); memset(dbpc, 0, tmpsize);
dbpc->itemcount = tmp; dbpc->itemcount = tmp;
@ -594,9 +596,11 @@ bool Corpse::Save() {
memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct)); memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(ServerLootItem_Struct));
} }
/* Create New Corpse*/
if (corpse_db_id == 0) { if (corpse_db_id == 0) {
corpse_db_id = database.SaveCharacterCorpse(char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading); corpse_db_id = database.SaveCharacterCorpse(char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading);
} }
/* Update Corpse Data */
else{ else{
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed()); corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed());
} }
@ -661,23 +665,20 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct**
cur = itemlist.begin(); cur = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
for(; cur != end; ++cur) { for(; cur != end; ++cur) {
if((*cur)->lootslot == lootslot) if((*cur)->lootslot == lootslot) {
{
sitem = *cur; sitem = *cur;
break; break;
} }
} }
if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) {
{
int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN); int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_BEGIN);
cur = itemlist.begin(); cur = itemlist.begin();
end = itemlist.end(); end = itemlist.end();
for(; cur != end; ++cur) { for(; cur != end; ++cur) {
sitem2 = *cur; sitem2 = *cur;
if(sitem2->equip_slot >= bagstart && sitem2->equip_slot < bagstart + 10) if(sitem2->equip_slot >= bagstart && sitem2->equip_slot < bagstart + 10) {
{
bag_item_data[sitem2->equip_slot - bagstart] = sitem2; bag_item_data[sitem2->equip_slot - bagstart] = sitem2;
} }
} }
@ -692,8 +693,7 @@ uint32 Corpse::GetWornItem(int16 equipSlot) const {
end = itemlist.end(); end = itemlist.end();
for(; cur != end; ++cur) { for(; cur != end; ++cur) {
ServerLootItem_Struct* item = *cur; ServerLootItem_Struct* item = *cur;
if (item->equip_slot == equipSlot) if (item->equip_slot == equipSlot) {
{
return item->item_id; return item->item_id;
} }
} }
@ -710,8 +710,7 @@ void Corpse::RemoveItem(uint16 lootslot) {
end = itemlist.end(); end = itemlist.end();
for(; cur != end; ++cur) { for(; cur != end; ++cur) {
ServerLootItem_Struct* sitem = *cur; ServerLootItem_Struct* sitem = *cur;
if (sitem->lootslot == lootslot) if (sitem->lootslot == lootslot) {
{
RemoveItem(sitem); RemoveItem(sitem);
return; return;
} }
@ -725,8 +724,7 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data){
end = itemlist.end(); end = itemlist.end();
for(; cur != end; ++cur) { for(; cur != end; ++cur) {
ServerLootItem_Struct* sitem = *cur; ServerLootItem_Struct* sitem = *cur;
if (sitem == item_data) if (sitem == item_data) {
{
is_corpse_changed = true; is_corpse_changed = true;
itemlist.erase(cur); itemlist.erase(cur);
@ -769,7 +767,7 @@ bool Corpse::Process() {
if(corpse_delay_timer.Check()) { if(corpse_delay_timer.Check()) {
for (int i=0; i<MAX_LOOTERS; i++) for (int i=0; i<MAX_LOOTERS; i++)
looters[i] = 0; allowed_looters[i] = 0;
corpse_delay_timer.Disable(); corpse_delay_timer.Disable();
return true; return true;
} }
@ -834,10 +832,10 @@ void Corpse::SetDecayTimer(uint32 decaytime) {
bool Corpse::CanMobLoot(int charid) { bool Corpse::CanMobLoot(int charid) {
uint8 z=0; uint8 z=0;
for(int i=0; i<MAX_LOOTERS; i++) { for(int i=0; i<MAX_LOOTERS; i++) {
if(looters[i] != 0) if(allowed_looters[i] != 0)
z++; z++;
if (looters[i] == charid) if (allowed_looters[i] == charid)
return true; return true;
} }
if(z == 0) if(z == 0)
@ -852,7 +850,7 @@ void Corpse::AllowMobLoot(Mob *them, uint8 slot) {
if(them == nullptr || !them->IsClient()) if(them == nullptr || !them->IsClient())
return; return;
looters[slot] = them->CastToClient()->CharacterID(); allowed_looters[slot] = them->CastToClient()->CharacterID();
} }
// @merth: this function needs some work // @merth: this function needs some work
@ -1390,8 +1388,8 @@ uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
void Corpse::AddLooter(Mob* who) { void Corpse::AddLooter(Mob* who) {
for (int i=0; i<MAX_LOOTERS; i++) { for (int i=0; i<MAX_LOOTERS; i++) {
if (looters[i] == 0) { if (allowed_looters[i] == 0) {
looters[i] = who->CastToClient()->CharacterID(); allowed_looters[i] = who->CastToClient()->CharacterID();
break; break;
} }
} }

View File

@ -26,13 +26,12 @@ class NPC;
#define MAX_LOOTERS 72 #define MAX_LOOTERS 72
class Corpse : public Mob class Corpse : public Mob {
{
public: public:
static void SendEndLootErrorPacket(Client* client); static void SendEndLootErrorPacket(Client* client);
static void SendLootReqErrorPacket(Client* client, uint8 response = 2); static void SendLootReqErrorPacket(Client* client, uint8 response = 2);
Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000); Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000);
Corpse(Client* client, int32 in_rezexp); Corpse(Client* client, int32 in_rezexp);
Corpse(uint32 in_corpseid, 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 = false); Corpse(uint32 in_corpseid, 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 = false);
@ -137,7 +136,7 @@ private:
bool rez; bool rez;
bool can_rez; bool can_rez;
bool become_npc; bool become_npc;
int looters[MAX_LOOTERS]; // People allowed to loot the corpse, character id int allowed_looters[MAX_LOOTERS]; // People allowed to loot the corpse, character id
Timer corpse_decay_timer; Timer corpse_decay_timer;
Timer corpse_res_timer; Timer corpse_res_timer;
Timer corpse_delay_timer; Timer corpse_delay_timer;

View File

@ -3320,115 +3320,50 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::list<struct NPCFactio
return true; return true;
} }
/* /* Corpse Queries */
Corpse Queries
*/
bool ZoneDatabase::DeleteGraveyard(uint32 zone_id, uint32 graveyard_id) { bool ZoneDatabase::DeleteGraveyard(uint32 zone_id, uint32 graveyard_id) {
char errbuf[MYSQL_ERRMSG_SIZE]; std::string query = StringFormat( "UPDATE `zone` SET `graveyard_id` = 0 WHERE `zone_idnumber` = %u AND `version` = 0", zone_id);
char* query = new char[256]; auto results = QueryDatabase(query);
uint32 query_length = 0;
uint32 affected_rows = 0;
query_length = sprintf(query, "UPDATE zone SET graveyard_id=0 WHERE zone_idnumber=%u AND version=0", zone_id); query = StringFormat("DELETE FROM `graveyard` WHERE `id` = %u", graveyard_id);
auto results2 = QueryDatabase(query);
if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) {
safe_delete_array(query);
std::cerr << "Error1 in DeleteGraveyard query " << errbuf << std::endl;
return false;
}
if (affected_rows == 0) {
std::cerr << "Error2 in DeleteGraveyard query: affected_rows = 0" << std::endl;
return false;
}
query_length = sprintf(query, "DELETE FROM graveyard WHERE id=%u", graveyard_id);
if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) {
safe_delete_array(query);
std::cerr << "Error3 in DeleteGraveyard query " << errbuf << std::endl;
return false;
}
safe_delete_array(query);
if (affected_rows == 0) {
std::cerr << "Error4 in DeleteGraveyard query: affected_rows = 0" << std::endl;
return false;
}
if (results.Success() && results2.Success()){
return true; return true;
}
return false;
} }
uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) { uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) {
char errbuf[MYSQL_ERRMSG_SIZE]; std::string query = StringFormat(
char* query = new char[256]; "UPDATE `zone` SET `graveyard_id` = %u WHERE `zone_idnumber` = %u AND `version` = 0",
char* end = query; graveyard_id, zone_id
uint32 affected_rows = 0; );
auto results = QueryDatabase(query);
end += sprintf(end, "UPDATE zone SET graveyard_id=%u WHERE zone_idnumber=%u AND version=0", graveyard_id, zone_id);
if (!RunQuery(query, (uint32)(end - query), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
std::cerr << "Error1 in AddGraveyardIDToZone query " << errbuf << std::endl;
return 0;
}
safe_delete_array(query);
if (affected_rows == 0) {
std::cerr << "Error2 in AddGraveyardIDToZone query: affected_rows = 0" << std::endl;
return 0;
}
return zone_id; return zone_id;
} }
uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) { uint32 ZoneDatabase::CreateGraveyardRecord(uint32 graveyard_zone_id, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) {
char errbuf[MYSQL_ERRMSG_SIZE]; std::string query = StringFormat(
char* query = new char[256]; "INSERT INTO `graveyard` SET `zone_id` = %u, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f",
char* end = query; graveyard_zone_id, graveyard_x, graveyard_y, graveyard_z, graveyard_heading
uint32 affected_rows = 0; );
uint32 new_graveyard_id = 0; auto results = QueryDatabase(query);
if (results.Success()){
end += sprintf(end, "INSERT INTO graveyard SET zone_id=%u, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f", graveyard_zone_id, graveyard_x, graveyard_y, graveyard_z, graveyard_heading); return results.LastInsertedID();
if (!RunQuery(query, (uint32)(end - query), errbuf, 0, &affected_rows, &new_graveyard_id)) {
safe_delete_array(query);
std::cerr << "Error1 in NewGraveyardRecord query " << errbuf << std::endl;
return 0;
} }
safe_delete_array(query);
if (affected_rows == 0) {
std::cerr << "Error2 in NewGraveyardRecord query: affected_rows = 0" << std::endl;
return 0; return 0;
}
if (new_graveyard_id <= 0) {
std::cerr << "Error3 in NewGraveyardRecord query: new_graveyard_id <= 0" << std::endl;
return 0;
}
return new_graveyard_id;
} }
uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, float x, float y, float z, float heading) { uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, float x, float y, float z, float heading) {
char errbuf[MYSQL_ERRMSG_SIZE]; std::string query = StringFormat(
char* query = new char[256]; "UPDATE `character_corpses` "
char* end = query; "SET `zone_id` = %u, `instance_id` = 0, `x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, `was_at_graveyard` = 1 "
uint32 affected_rows = 0; "WHERE `id` = %d",
zone_id, x, y, z, heading, dbid
// We probably don't want a graveyard located in an instance. );
end += sprintf(end, "Update character_corpses SET zone_id=%u, instance_id=0, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, was_at_graveyard=1 WHERE id=%d", zone_id, x, y, z, heading, dbid); QueryDatabase(query);
if (!RunQuery(query, (uint32)(end - query), errbuf, 0, &affected_rows)) {
safe_delete_array(query);
std::cerr << "Error1 in GraveyardPlayerCorpse query " << errbuf << std::endl;
return 0;
}
safe_delete_array(query);
if (affected_rows == 0) {
std::cerr << "Error2 in GraveyardPlayerCorpse query: affected_rows = 0" << std::endl;
return 0;
}
return dbid; return dbid;
} }