mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Replaced npcspecialatk with special_attacks, needs more testing also gotta export new api for it as I can't remove the legacy one. Too many quests rely on the legacy functionality.
This commit is contained in:
+1
-303
@@ -79,9 +79,6 @@ volatile bool ZoneLoaded = false;
|
||||
extern QuestParserCollection* parse;
|
||||
extern DBAsyncFinishedQueue MTdbafq;
|
||||
extern DBAsync *dbasync;
|
||||
void CleanupLoadZoneState(uint32 spawn2_count, ZSDump_Spawn2** spawn2_dump, ZSDump_NPC** npc_dump, ZSDump_NPC_Loot** npcloot_dump, NPCType** gmspawntype_dump, Spawn2*** spawn2_loaded, NPC*** npc_loaded, MYSQL_RES** result);
|
||||
|
||||
|
||||
|
||||
bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
||||
_ZP(Zone_Bootup);
|
||||
@@ -805,14 +802,7 @@ void Zone::Shutdown(bool quite)
|
||||
if (!quite)
|
||||
LogFile->write(EQEMuLog::Normal, "Zone shutdown: going to sleep");
|
||||
ZoneLoaded = false;
|
||||
char pzs[3] = "";
|
||||
if (database.GetVariable("PersistentZoneState", pzs, 2)) {
|
||||
if (pzs[0] == '1') {
|
||||
Sleep(100);
|
||||
LogFile->write(EQEMuLog::Normal, "Saving zone state");
|
||||
database.DumpZoneState();
|
||||
}
|
||||
}
|
||||
|
||||
zone->ResetAuth();
|
||||
safe_delete(zone);
|
||||
dbasync->CommitWrites();
|
||||
@@ -1662,301 +1652,9 @@ bool ZoneDatabase::LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list,
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::DumpZoneState() {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "DELETE FROM zone_state_dump WHERE zonename='%s'", zone->GetShortName()), errbuf)) {
|
||||
std::cerr << "Error in DumpZoneState query '" << query << "' " << errbuf << std::endl;
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
|
||||
|
||||
uint32 spawn2_count = zone->CountSpawn2();
|
||||
uint32 npc_count = 0;
|
||||
uint32 npcloot_count = 0;
|
||||
uint32 gmspawntype_count = 0;
|
||||
entity_list.CountNPC(&npc_count, &npcloot_count, &gmspawntype_count);
|
||||
|
||||
std::cout << "DEBUG: spawn2count=" << spawn2_count << ", npc_count=" << npc_count << ", npcloot_count=" << npcloot_count << ", gmspawntype_count=" << gmspawntype_count << std::endl;
|
||||
|
||||
ZSDump_Spawn2* spawn2_dump = 0;
|
||||
ZSDump_NPC* npc_dump = 0;
|
||||
ZSDump_NPC_Loot* npcloot_dump = 0;
|
||||
NPCType* gmspawntype_dump = 0;
|
||||
if (spawn2_count > 0) {
|
||||
spawn2_dump = (ZSDump_Spawn2*) new uchar[spawn2_count * sizeof(ZSDump_Spawn2)];
|
||||
memset(spawn2_dump, 0, sizeof(ZSDump_Spawn2) * spawn2_count);
|
||||
}
|
||||
if (npc_count > 0) {
|
||||
npc_dump = (ZSDump_NPC*) new uchar[npc_count * sizeof(ZSDump_NPC)];
|
||||
memset(npc_dump, 0, sizeof(ZSDump_NPC) * npc_count);
|
||||
for (unsigned int i=0; i < npc_count; i++) {
|
||||
npc_dump[i].spawn2_dump_index = 0xFFFFFFFF;
|
||||
npc_dump[i].gmspawntype_index = 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
if (npcloot_count > 0) {
|
||||
npcloot_dump = (ZSDump_NPC_Loot*) new uchar[npcloot_count * sizeof(ZSDump_NPC_Loot)];
|
||||
memset(npcloot_dump, 0, sizeof(ZSDump_NPC_Loot) * npcloot_count);
|
||||
for (unsigned int k=0; k < npcloot_count; k++)
|
||||
npcloot_dump[k].npc_dump_index = 0xFFFFFFFF;
|
||||
}
|
||||
if (gmspawntype_count > 0) {
|
||||
gmspawntype_dump = (NPCType*) new uchar[gmspawntype_count * sizeof(NPCType)];
|
||||
memset(gmspawntype_dump, 0, sizeof(NPCType) * gmspawntype_count);
|
||||
}
|
||||
|
||||
entity_list.DoZoneDump(spawn2_dump, npc_dump, npcloot_dump, gmspawntype_dump);
|
||||
query = new char[512 + ((sizeof(ZSDump_Spawn2) * spawn2_count + sizeof(ZSDump_NPC) * npc_count + sizeof(ZSDump_NPC_Loot) * npcloot_count + sizeof(NPCType) * gmspawntype_count) * 2)];
|
||||
char* end = query;
|
||||
|
||||
end += sprintf(end, "Insert Into zone_state_dump (zonename, spawn2_count, npc_count, npcloot_count, gmspawntype_count, spawn2, npcs, npc_loot, gmspawntype) values ('%s', %i, %i, %i, %i, ", zone->GetShortName(), spawn2_count, npc_count, npcloot_count, gmspawntype_count);
|
||||
*end++ = '\'';
|
||||
if (spawn2_dump != 0) {
|
||||
end += DoEscapeString(end, (char*)spawn2_dump, sizeof(ZSDump_Spawn2) * spawn2_count);
|
||||
safe_delete_array(spawn2_dump);
|
||||
}
|
||||
*end++ = '\'';
|
||||
end += sprintf(end, ", ");
|
||||
*end++ = '\'';
|
||||
if (npc_dump != 0) {
|
||||
end += DoEscapeString(end, (char*)npc_dump, sizeof(ZSDump_NPC) * npc_count);
|
||||
safe_delete_array(npc_dump);
|
||||
}
|
||||
*end++ = '\'';
|
||||
end += sprintf(end, ", ");
|
||||
*end++ = '\'';
|
||||
if (npcloot_dump != 0) {
|
||||
end += DoEscapeString(end, (char*)npcloot_dump, sizeof(ZSDump_NPC_Loot) * npcloot_count);
|
||||
safe_delete_array(npcloot_dump);
|
||||
}
|
||||
*end++ = '\'';
|
||||
end += sprintf(end, ", ");
|
||||
*end++ = '\'';
|
||||
if (gmspawntype_dump != 0) {
|
||||
end += DoEscapeString(end, (char*)gmspawntype_dump, sizeof(NPCType) * gmspawntype_count);
|
||||
safe_delete_array(gmspawntype_dump);
|
||||
}
|
||||
*end++ = '\'';
|
||||
end += sprintf(end, ")");
|
||||
|
||||
uint32 affected_rows = 0;
|
||||
if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) {
|
||||
// if (DoEscapeString(query, (unsigned int) (end - query))) {
|
||||
safe_delete_array(query);
|
||||
std::cerr << "Error in ZoneDump query " << errbuf << std::endl;
|
||||
return false;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
if (affected_rows == 0) {
|
||||
std::cerr << "Zone dump failed. (affected rows = 0)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int8 ZoneDatabase::LoadZoneState(const char* zonename, LinkedList<Spawn2*>& spawn2_list) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
uint32 i;
|
||||
unsigned long* lengths;
|
||||
uint32 elapsedtime = 0;
|
||||
uint32 spawn2_count = 0;
|
||||
uint32 npc_count = 0;
|
||||
uint32 npcloot_count = 0;
|
||||
uint32 gmspawntype_count = 0;
|
||||
ZSDump_Spawn2* spawn2_dump = 0;
|
||||
ZSDump_NPC* npc_dump = 0;
|
||||
ZSDump_NPC_Loot* npcloot_dump = 0;
|
||||
NPCType* gmspawntype_dump = 0;
|
||||
Spawn2** spawn2_loaded = 0;
|
||||
NPC** npc_loaded = 0;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT spawn2_count, npc_count, npcloot_count, gmspawntype_count, spawn2, npcs, npc_loot, gmspawntype, (UNIX_TIMESTAMP()-UNIX_TIMESTAMP(time)) as elapsedtime FROM zone_state_dump WHERE zonename='%s'", zonename), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
if (mysql_num_rows(result) == 1) {
|
||||
row = mysql_fetch_row(result);
|
||||
std::cout << "Elapsed time: " << row[8] << std::endl;
|
||||
elapsedtime = atoi(row[8]) * 1000;
|
||||
lengths = mysql_fetch_lengths(result);
|
||||
spawn2_count = atoi(row[0]);
|
||||
std::cout << "Spawn2count: " << spawn2_count << std::endl;
|
||||
if (lengths[4] != (sizeof(ZSDump_Spawn2) * spawn2_count)) {
|
||||
std::cerr << "Error in LoadZoneState: spawn2_dump length mismatch l=" << lengths[4] << ", e=" << (sizeof(ZSDump_Spawn2) * spawn2_count) << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
else if (spawn2_count > 0) {
|
||||
spawn2_dump = new ZSDump_Spawn2[spawn2_count];
|
||||
spawn2_loaded = new Spawn2*[spawn2_count];
|
||||
memcpy(spawn2_dump, row[4], lengths[4]);
|
||||
for (i=0; i < spawn2_count; i++) {
|
||||
if (spawn2_dump[i].time_left == 0xFFFFFFFF) // npc spawned, timer should be disabled
|
||||
spawn2_loaded[i] = LoadSpawn2(spawn2_list, spawn2_dump[i].spawn2_id, 0xFFFFFFFF);
|
||||
else if (spawn2_dump[i].time_left <= elapsedtime)
|
||||
spawn2_loaded[i] = LoadSpawn2(spawn2_list, spawn2_dump[i].spawn2_id, 0);
|
||||
else
|
||||
spawn2_loaded[i] = LoadSpawn2(spawn2_list, spawn2_dump[i].spawn2_id, spawn2_dump[i].time_left - elapsedtime);
|
||||
if (spawn2_loaded[i] == 0) {
|
||||
std::cerr << "Error in LoadZoneState: spawn2_loaded[" << i << "] == 0" << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmspawntype_count = atoi(row[3]);
|
||||
std::cout << "gmspawntype_count: " << gmspawntype_count << std::endl;
|
||||
if (lengths[7] != (sizeof(NPCType) * gmspawntype_count)) {
|
||||
std::cerr << "Error in LoadZoneState: gmspawntype_dump length mismatch l=" << lengths[7] << ", e=" << (sizeof(NPCType) * gmspawntype_count) << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
else if (gmspawntype_count > 0) {
|
||||
gmspawntype_dump = new NPCType[gmspawntype_count];
|
||||
memcpy(gmspawntype_dump, row[7], lengths[7]);
|
||||
}
|
||||
|
||||
npc_count = atoi(row[1]);
|
||||
std::cout << "npc_count: " << npc_count << std::endl;
|
||||
if (lengths[5] != (sizeof(ZSDump_NPC) * npc_count)) {
|
||||
std::cerr << "Error in LoadZoneState: npc_dump length mismatch l=" << lengths[5] << ", e=" << (sizeof(ZSDump_NPC) * npc_count) << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
else if (npc_count > 0) {
|
||||
npc_dump = new ZSDump_NPC[npc_count];
|
||||
npc_loaded = new NPC*[npc_count];
|
||||
for (i=0; i < npc_count; i++) {
|
||||
npc_loaded[i] = 0;
|
||||
}
|
||||
memcpy(npc_dump, row[5], lengths[5]);
|
||||
for (i=0; i < npc_count; i++) {
|
||||
if (npc_loaded[i] != 0) {
|
||||
std::cerr << "Error in LoadZoneState: npc_loaded[" << i << "] != 0" << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
Spawn2* tmp = 0;
|
||||
if (!npc_dump[i].corpse && npc_dump[i].spawn2_dump_index != 0xFFFFFFFF) {
|
||||
if (spawn2_loaded == 0 || npc_dump[i].spawn2_dump_index >= spawn2_count) {
|
||||
std::cerr << "Error in LoadZoneState: (spawn2_loaded == 0 || index >= count) && npc_dump[" << i << "].spawn2_dump_index != 0xFFFFFFFF" << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
tmp = spawn2_loaded[npc_dump[i].spawn2_dump_index];
|
||||
spawn2_loaded[npc_dump[i].spawn2_dump_index] = 0;
|
||||
}
|
||||
if (npc_dump[i].npctype_id == 0) {
|
||||
if (npc_dump[i].gmspawntype_index == 0xFFFFFFFF) {
|
||||
std::cerr << "Error in LoadZoneState: gmspawntype index invalid" << std::endl;
|
||||
safe_delete(tmp);
|
||||
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
if (gmspawntype_dump == 0 || npc_dump[i].gmspawntype_index >= gmspawntype_count) {
|
||||
std::cerr << "Error in LoadZoneState: (gmspawntype_dump == 0 || index >= count) && npc_dump[" << i << "].npctype_id == 0" << std::endl;
|
||||
safe_delete(tmp);
|
||||
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
npc_loaded[i] = new NPC(&gmspawntype_dump[npc_dump[i].gmspawntype_index], tmp, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, FlyMode3, npc_dump[i].corpse);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const NPCType* crap = database.GetNPCType(npc_dump[i].npctype_id);
|
||||
if (crap != 0)
|
||||
npc_loaded[i] = new NPC(crap, tmp, npc_dump[i].x, npc_dump[i].y, npc_dump[i].z, npc_dump[i].heading, FlyMode3, npc_dump[i].corpse);
|
||||
else {
|
||||
std::cerr << "Error in LoadZoneState: Unknown npctype_id: " << npc_dump[i].npctype_id << std::endl;
|
||||
safe_delete(tmp);
|
||||
}
|
||||
}
|
||||
if (npc_loaded[i] != 0) {
|
||||
npc_loaded[i]->AddCash(npc_dump[i].copper, npc_dump[i].silver, npc_dump[i].gold, npc_dump[i].platinum);
|
||||
// if (npc_dump[i].corpse) {
|
||||
// if (npc_dump[i].decay_time_left <= elapsedtime)
|
||||
// npc_loaded[i]->SetDecayTimer(0);
|
||||
// else
|
||||
// npc_loaded[i]->SetDecayTimer(npc_dump[i].decay_time_left - elapsedtime);
|
||||
// }
|
||||
entity_list.AddNPC(npc_loaded[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
npcloot_count = atoi(row[2]);
|
||||
std::cout << "npcloot_count: " << npcloot_count << std::endl;
|
||||
if (lengths[6] != (sizeof(ZSDump_NPC_Loot) * npcloot_count)) {
|
||||
std::cerr << "Error in LoadZoneState: npcloot_dump length mismatch l=" << lengths[6] << ", e=" << (sizeof(ZSDump_NPC_Loot) * npcloot_count) << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
else if (npcloot_count > 0) {
|
||||
if (npc_loaded == 0) {
|
||||
std::cerr << "Error in LoadZoneState: npcloot_count > 0 && npc_loaded == 0" << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
npcloot_dump = new ZSDump_NPC_Loot[npcloot_count];
|
||||
memcpy(npcloot_dump, row[6], lengths[6]);
|
||||
for (i=0; i < npcloot_count; i++) {
|
||||
if (npcloot_dump[i].npc_dump_index >= npc_count) {
|
||||
std::cerr << "Error in LoadZoneState: npcloot_dump[" << i << "].npc_dump_index >= npc_count" << std::endl;
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return -1;
|
||||
}
|
||||
if (npc_loaded[npcloot_dump[i].npc_dump_index] != 0) {
|
||||
npc_loaded[npcloot_dump[i].npc_dump_index]->AddItem(npcloot_dump[i].itemid, npcloot_dump[i].charges, npcloot_dump[i].equipSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
}
|
||||
else {
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
return 0;
|
||||
}
|
||||
CleanupLoadZoneState(spawn2_count, &spawn2_dump, &npc_dump, &npcloot_dump, &gmspawntype_dump, &spawn2_loaded, &npc_loaded, &result);
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error in LoadZoneState query '" << query << "' " << errbuf << std::endl;
|
||||
|
||||
safe_delete_array(query);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CleanupLoadZoneState(uint32 spawn2_count, ZSDump_Spawn2** spawn2_dump, ZSDump_NPC** npc_dump, ZSDump_NPC_Loot** npcloot_dump, NPCType** gmspawntype_dump, Spawn2*** spawn2_loaded, NPC*** npc_loaded, MYSQL_RES** result) {
|
||||
safe_delete(*spawn2_dump);
|
||||
safe_delete(*spawn2_loaded);
|
||||
safe_delete(*gmspawntype_dump);
|
||||
safe_delete(*npc_dump);
|
||||
safe_delete(*npc_loaded);
|
||||
safe_delete(*npcloot_dump);
|
||||
if (*result) {
|
||||
mysql_free_result(*result);
|
||||
*result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::SpawnStatus(Mob* client) {
|
||||
LinkedListIterator<Spawn2*> iterator(spawn2_list);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user