bool LoadSTB(char* path) { CleanUp(); CRoseFile* fh = new CRoseFile(path, FM_READ | FM_BINARY); if(!fh->IsOpen()) { delete fh; return false; } // if is open fh->Seek(4, SEEK_CUR); dword offset = fh->Get<dword>(); _Rows = fh->Get<dword>(); _Columns = fh->Get<dword>(); _Rows--; _Columns--; fh->SetAbsPos(offset); _Data = new char**[_Rows]; for(dword i = 0; i < _Rows; i++) _Data[i] = new char*[_Columns]; for(dword i = 0; i < _Rows; i++) { for(dword j = 0; j < _Columns; j++) { dword len = fh->Get<word>(); if(len == 0) { _Data[i][j] = NULL; continue; } // if len _Data[i][j] = new char[len+1]; fh->Read(_Data[i][j], len, 1); _Data[i][j][len] = 0; } // for j } // for i fh->Close(); delete fh; return true; } // bool
void CWorldServer::ReadQSD(strings path, dword index) { //LMA: mass exporter. bool lma_export=false; if(Config.massexport) lma_export=true; CRoseFile* fh = new CRoseFile(path, FM_READ | FM_BINARY); if(fh->IsOpen()) { // goto done; // Log(MSG_LOAD, "Loading %s", path); /* Commenting out this line, replacing MSG_LOAD with MSG_DEBUG -Terr0risT */ //Log(MSG_DEBUG, "Loading %s", path); fh->Seek(4, SEEK_CUR); dword BlockCount = fh->Get<dword>(); if(lma_export) { LogSp(MSG_INFO, " "); LogSp(MSG_INFO, " "); if(BlockCount==0) { //LogSp(MSG_INFO, "Exporting %s :: 0 block", path); } else if (BlockCount==1) { //LogSp(MSG_INFO, "Exporting %s :: 1 block", path); } else { //LogSp(MSG_INFO, "Exporting %s :: %i blocks", path,BlockCount); } //LogSp(MSG_INFO, "{"); } fh->Seek(fh->Get<word>(), SEEK_CUR); for(dword i = 0; i < BlockCount; i++) { dword RecordCount = fh->Get<dword>(); if(lma_export) { if(i>0) //LogSp(MSG_INFO, "\t "); if(RecordCount==0) { //LogSp(MSG_INFO, "\t Block %i / %i :: 0 Function",i+1,BlockCount); } else if (RecordCount==1) { //LogSp(MSG_INFO, "\t Block %i / %i :: 1 Function",i+1,BlockCount); } else { // LogSp(MSG_INFO, "\t Block %i / %i :: %i Functions",i+1,BlockCount,RecordCount); } //LogSp(MSG_INFO, "\t {"); } fh->Seek(fh->Get<word>(), SEEK_CUR); for(dword j = 0; j < RecordCount; j++) { CQuestTrigger* trigger = new CQuestTrigger(); trigger->id=((index*0x10000)+(i*0x100)+j); trigger->CheckNext = fh->Get<byte>(); trigger->ConditionCount = fh->Get<dword>(); trigger->ActionCount = fh->Get<dword>(); dword len = fh->Get<word>(); trigger->TriggerName = new char[len+1]; fh->Read(trigger->TriggerName, len, 1); trigger->TriggerName[len] = 0; if(lma_export) { char bactions[20]; char bconditions[20]; if(trigger->ConditionCount==0) { sprintf(bconditions,"0 condition"); } else if(trigger->ConditionCount==1) { sprintf(bconditions,"1 condition"); } else { sprintf(bconditions,"%i conditions",trigger->ConditionCount); } if(trigger->ActionCount==0) { sprintf(bactions,"0 action"); } else if(trigger->ActionCount==1) { sprintf(bactions,"1 action"); } else { sprintf(bactions,"%i actions",trigger->ActionCount); } // if(j>0) //LogSp(MSG_INFO, "\t\t "); //LogSp(MSG_INFO, "\t\t Function %i / %i (%s / %u) :: %s, %s",j+1,RecordCount,trigger->TriggerName,MakeStrHash(trigger->TriggerName),bconditions,bactions); //if(trigger->CheckNext) //LogSp(MSG_INFO, "\t\t\t <If Function %s returns False, we'll check the next Function (check_next activated)>",trigger->TriggerName); // LogSp(MSG_INFO, "\t\t {"); } if(trigger->ConditionCount > 0) { if(lma_export) { // LogSp(MSG_INFO, "\t\t\t Conditions (%i)",trigger->ConditionCount); // LogSp(MSG_INFO, "\t\t\t {"); } trigger->Conditions = new CQuestTrigger::SQuestDatum*[trigger->ConditionCount]; for(dword k = 0; k < trigger->ConditionCount; k++) { CQuestTrigger::SQuestDatum* data = new CQuestTrigger::SQuestDatum(); data->size = fh->Get<int>(); data->opcode = fh->Get<int>(); data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); trigger->Conditions[k] = data; //LMA: Export if (lma_export) { //ExportQSDData(data->data,data->opcode,data->size,data); ExportQSDData(data->data,data->size,data->opcode); } } if(lma_export) { // LogSp(MSG_INFO, "\t\t\t }"); } } else { if(lma_export) { // LogSp(MSG_INFO, "\t\t\t 0 Condition"); } trigger->Conditions = NULL; } if(trigger->ActionCount > 0) { trigger->Actions = new CQuestTrigger::SQuestDatum*[trigger->ActionCount]; if(lma_export) { //LogSp(MSG_INFO, "\t\t\t Actions (%i)",trigger->ActionCount); //LogSp(MSG_INFO, "\t\t\t {"); } for(dword k = 0; k < trigger->ActionCount; k++) { CQuestTrigger::SQuestDatum* data = new CQuestTrigger::SQuestDatum(); data->size = fh->Get<int>(); data->opcode = fh->Get<int>() - 0x01000000; data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); trigger->Actions[k] = data; //LMA: Export if (lma_export) { ExportQSDDataA(data->data,data->size,data->opcode); } } if(lma_export) { // LogSp(MSG_INFO, "\t\t\t }"); } } else { if(lma_export) { // LogSp(MSG_INFO, "\t\t\t 0 Action"); } trigger->Actions = NULL; } trigger->TriggerHash = MakeStrHash(trigger->TriggerName); TriggerList.push_back( trigger ); if(lma_export) { // LogSp(MSG_INFO, "\t\t "); // LogSp(MSG_INFO, "\t\t }"); } } if(lma_export) { // LogSp(MSG_INFO, "\t "); // LogSp(MSG_INFO, "\t }"); } } if(lma_export) { // LogSp(MSG_INFO, " "); // LogSp(MSG_INFO, "}"); } } else { //Log( MSG_ERROR, "QSD File: '%s'", path ); //Log( MSG_WARNING, "QSD File: '%s'", path ); Log( MSG_ERROR, "Could not open QSD File: '%s'", path ); } fh->Close(); delete fh; }
void CWorldServer::ReadAIP(strings path, dword index) { //LMA: mass exporter. bool lma_export=false; if(Config.massexport) lma_export=true; char titlegen[20]; CRoseFile* fh = new CRoseFile(path, FM_READ | FM_BINARY); if(fh->IsOpen()) { // goto done; Log(MSG_LOAD, "Loading %s", path); if(lma_export) { LogSp(MSG_INFO, " "); LogSp(MSG_INFO, " "); if(NPC_AIP.find(index)!=NPC_AIP.end()) { //LogSp(MSG_INFO, "Exporting %s (AIP index %i, NPC %i (%s))",path,index,NPC_AIP[index],GetSTLMonsterNameByID(NPC_AIP[index])); if(NPC_AIP[index].size()==1) { LogSp(MSG_INFO, "Exporting %s (AIP index %i for NPC/monster %i (%s) )",path,index,NPC_AIP[index].at(0),GetSTLMonsterNameByID(NPC_AIP[index].at(0))); } else { LogSp(MSG_INFO, "Exporting %s (AIP index %i for %i monsters:",path,index,NPC_AIP[index].size()); for(int k=0;k<NPC_AIP[index].size();k++) { if(k!=(NPC_AIP[index].size()-1)) { LogSp(MSG_INFO, "\t-> NPC/monster %i (%s),",NPC_AIP[index].at(k),GetSTLMonsterNameByID(NPC_AIP[index].at(k))); } else { LogSp(MSG_INFO, "\t-> NPC/monster %i (%s))",NPC_AIP[index].at(k),GetSTLMonsterNameByID(NPC_AIP[index].at(k))); } } } } else { LogSp(MSG_INFO, "Exporting %s (AIP index %i, not used by NPC/monsters?)",path,index); } } dword BlockCount = fh->Get<dword>(); dword mintime = fh->Get<dword>(); dword mindamage = fh->Get<dword>(); dword titlestringlength = fh->Get<dword>(); strings title = new char[titlestringlength+1]; strings title2 = new char[32+1]; fh->Read(title, titlestringlength, 1); for(dword i = 0; i < BlockCount; i++) { titlestringlength = 32; fh->Read(title2, titlestringlength, 1);//on spawn-idle-attack-attacked-killed target-dead dword RecordCount = fh->Get<dword>(); if(lma_export) { //Log(MSG_INFO, "--%s", title2); bool extra_rl=true; switch(i) { case 0: { extra_rl=false; sprintf(titlegen,"On Spawn"); } break; case 1: { sprintf(titlegen,"Idle"); } break; case 2: { sprintf(titlegen,"In Combat"); } break; case 3: { sprintf(titlegen,"Is attacked"); } break; case 4: { sprintf(titlegen,"Killed enemy"); } break; case 5: { sprintf(titlegen,"Dead"); } break; default: { sprintf(titlegen,"??Unknown??"); } break; } if(extra_rl) LogSp(MSG_INFO, "\t "); if(RecordCount==0) { LogSp(MSG_INFO, "\t %s :: 0 Block",titlegen); } else if(RecordCount==1) { LogSp(MSG_INFO, "\t %s :: 1 Block",titlegen); } else { LogSp(MSG_INFO, "\t %s :: %i Blocks",titlegen,RecordCount); } LogSp(MSG_INFO, "\t {"); } for(dword j = 0; j < RecordCount; j++) { if(lma_export) { if(j>0) LogSp(MSG_INFO, "\t\t "); LogSp(MSG_INFO, "\t\t Block %i / %i", j+1,RecordCount); LogSp(MSG_INFO, "\t\t {"); } CAip* script = new CAip(); fh->Read(title2, titlestringlength, 1);// 00 ============================== script->ConditionCount = fh->Get<dword>(); if(script->ConditionCount > 0) { if(lma_export) { if(script->ConditionCount==1) { LogSp(MSG_INFO, "\t\t\t IF (1 condition)"); } else { LogSp(MSG_INFO, "\t\t\t IF (%i conditions)",script->ConditionCount); } LogSp(MSG_INFO, "\t\t\t {"); } script->Conditions = new CAip::SAipDatum*[script->ConditionCount]; for(dword k = 0; k < script->ConditionCount; k++) { CAip::SAipDatum* data = new CAip::SAipDatum(); data->size = fh->Get<dword>(); data->opcode = fh->Get<dword>() - 0x04000001; data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); script->Conditions[k] = data; //LMA: exporting... if(lma_export) { ExportAipData(data->data,data->size,data->opcode); } //LMA: END exporting... } if(lma_export) { LogSp(MSG_INFO, "\t\t\t }"); } } else { script->Conditions = NULL; if(lma_export) { LogSp(MSG_INFO, "\t\t\t IF (0 condition)"); } } script->ActionCount = fh->Get<dword>(); if(script->ActionCount > 0) { if(lma_export) { if(script->ActionCount==1) { LogSp(MSG_INFO, "\t\t\t THEN (1 action)"); } else { LogSp(MSG_INFO, "\t\t\t THEN (%i actions)",script->ActionCount); } LogSp(MSG_INFO, "\t\t\t {"); } //LMA: In some special cases, we "invert" the LTB (28) and the executeqsdtrigger (30) script->offset_ltb=-1; script->offset_qsd_trigger=-1; script->Actions = new CAip::SAipDatum*[script->ActionCount]; for(dword k = 0; k < script->ActionCount; k++) { CAip::SAipDatum* data = new CAip::SAipDatum(); data->size = fh->Get<dword>(); data->opcode = fh->Get<dword>() - 0x0B000001; data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); script->Actions[k] = data; if (data->opcode==28) { script->offset_ltb=k; } if(data->opcode==30) { script->offset_qsd_trigger=k; } //LMA: export. if(lma_export) { ExportAipDataA(data->data,data->size,data->opcode); } } if(lma_export) { LogSp(MSG_INFO, "\t\t\t }"); } } else { script->Actions = NULL; if(lma_export) { LogSp(MSG_INFO, "\t\t\t THEN (0 action) "); LogSp(MSG_INFO, "\t\t\t {}"); } } script->AipID=((index*0x10000)+(i*0x100)+j); script->minDamage = mindamage; script->minTime = mintime; script->recordcount[i] = RecordCount; //LMA: testing maps. //AipList.push_back( script ); if(AipListMap.find(script->AipID)!=AipListMap.end()) { Log(MSG_WARNING,"Script ID %u already done!",script->AipID); } else { //AipListMap[script->AipID]=script; AipListMap.insert ( pair<dword,CAip*>(script->AipID,script) ); } if(lma_export) { LogSp(MSG_INFO, "\t\t }"); } } if (lma_export) { if(RecordCount>0) LogSp(MSG_INFO, "\t"); LogSp(MSG_INFO, "\t }"); } } } else Log( MSG_ERROR, "AIP File: '%s'", path ); fh->Close(); delete fh; }
void CWorldServer::ReadQSD(strings path, dword index){ string tmp("3DData/QUESTDATA/"); while (*++path != '\\'); while (*++path != '\\'); while (*path != 0) tmp.push_back(tolower(*++path)); /* Log(MSG_INFO, "Openning : %s", tmp.c_str()); */ CRoseFile* fh = new CRoseFile(tmp.c_str(), FM_READ | FM_BINARY); if(fh->IsOpen()) { // goto done; Log(MSG_LOAD, "Loading %s ", tmp.c_str()); fh->Seek(4, SEEK_CUR); dword BlockCount = fh->Get<dword>(); fh->Seek(fh->Get<word>(), SEEK_CUR); for(dword i = 0; i < BlockCount; i++){ dword RecordCount = fh->Get<dword>(); fh->Seek(fh->Get<word>(), SEEK_CUR); for(dword j = 0; j < RecordCount; j++){ CQuestTrigger* trigger = new CQuestTrigger(); trigger->id=((index*0x10000)+(i*0x100)+j); trigger->CheckNext = fh->Get<byte>(); trigger->ConditionCount = fh->Get<dword>(); trigger->ActionCount = fh->Get<dword>(); dword len = fh->Get<word>(); trigger->TriggerName = new char[len+1]; fh->Read(trigger->TriggerName, len, 1); trigger->TriggerName[len] = 0; if(trigger->ConditionCount > 0){ trigger->Conditions = new CQuestTrigger::SQuestDatum*[trigger->ConditionCount]; for(dword k = 0; k < trigger->ConditionCount; k++){ CQuestTrigger::SQuestDatum* data = new CQuestTrigger::SQuestDatum(); data->size = fh->Get<int>(); data->opcode = fh->Get<int>(); data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); trigger->Conditions[k] = data; } }else{ trigger->Conditions = NULL; } if(trigger->ActionCount > 0){ trigger->Actions = new CQuestTrigger::SQuestDatum*[trigger->ActionCount]; for(dword k = 0; k < trigger->ActionCount; k++){ CQuestTrigger::SQuestDatum* data = new CQuestTrigger::SQuestDatum(); data->size = fh->Get<int>(); data->opcode = fh->Get<int>() - 0x01000000; data->data = new byte[data->size - 8]; fh->Read(data->data, data->size - 8, 1); trigger->Actions[k] = data; } }else{ trigger->Actions = NULL; } trigger->TriggerHash = MakeStrHash(trigger->TriggerName); TriggerList.push_back( trigger ); } } }else Log( MSG_ERROR, "QSD File: '%s'", tmp.c_str() ); fh->Close(); delete fh; }