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:
KimLS
2013-07-06 03:45:06 -07:00
parent 0c675c33e2
commit 63d678ce29
32 changed files with 355 additions and 663 deletions
+1 -303
View File
@@ -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);