//LMA: We export QSD Conditions here //void CWorldServer::ExportQSDData(byte* dataorg,int opcode,int size,CQuestTrigger::SQuestDatum* dataraw) void CWorldServer::ExportQSDData(byte* dataorg,int size,int opcode) { char buffero[20]; char buffera[20]; UINT itemtype=0; UINT itemnum=0; //check Quest. if(opcode==0) { STR_COND_000 * data = (STR_COND_000 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if Quest %i (%s) exists",opcode,data->iQuestSN,GServer->GetSTLQuestByID(data->iQuestSN)); return; } //check Quest Variable. if(opcode==1) { STR_COND_001 * data = (STR_COND_001 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %i Player's quest vars",opcode,data->iDataCnt); for (int i=0;i<data->iDataCnt;i++) { dword address = i * sizeof(STR_QUEST_DATA); address += (dword)dataorg; address += 4; STR_QUEST_DATA* curQst = (STR_QUEST_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Var[0x%04x (%u)][%i] %s %i",curQst->m_wVarTYPE,curQst->m_wVarTYPE,curQst->m_wVarNO,Operators(curQst->btOp,buffero),curQst->nValue); } return; } //check Quest Variable (same as opcode 1) if(opcode==2) { STR_COND_002 * data = (STR_COND_002 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %i Player's quest vars",opcode,data->iDataCnt); for (int i=0;i<data->iDataCnt;i++) { dword address = i * sizeof(STR_QUEST_DATA); address += (dword)dataorg; address += 4; STR_QUEST_DATA* curQst = (STR_QUEST_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Var[0x%04x (%u)][%i] %s %i",curQst->m_wVarTYPE,curQst->m_wVarTYPE,curQst->m_wVarNO,Operators(curQst->btOp,buffero),curQst->nValue); } return; } //check Stats if(opcode==3) { STR_COND_003 * data = (STR_COND_003 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %i Player's stats",opcode,data->iDataCnt); for(int i = 0; i < data->iDataCnt; i++) { dword address = i * 0x0C; address += (dword)dataorg; address += 4; STR_ABIL_DATA* curAbil = (STR_ABIL_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Check Stat %s %s %i",Abilities(curAbil->iType,buffera),Operators(curAbil->btOp,buffero),curAbil->iValue); } return; } //check items. if(opcode==4) { STR_COND_004 * data = (STR_COND_004 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %i Player's items",opcode,data->iDataCnt); for(int i = 0; i < data->iDataCnt; i++) { dword address = i * 0x10; address += (dword)dataorg; address += 4; STR_ITEM_DATA* curItem = (STR_ITEM_DATA*)address; itemtype=gi(curItem->uiItemSN,0); itemnum=gi(curItem->uiItemSN,1); //where not reliable... //if(curItem->iWhere!=13) if(itemtype!=13) { if (curItem->uiItemSN==0) { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Check if equipped item in slot %i is %s (0:0)",curItem->iWhere,Operators(curItem->btOp,buffero),curItem->iRequestCnt); } else { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Check Item %i (%i:%i, %s %s) %s %i, where %i",curItem->uiItemSN,itemtype,itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(itemtype,itemnum),Operators(curItem->btOp,buffero),curItem->iRequestCnt,curItem->iWhere); } } else { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Check Quest Item %i (%i:%i, %s %s) %s %i, where %i",curItem->uiItemSN,itemtype,itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(itemtype,itemnum),Operators(curItem->btOp,buffero),curItem->iRequestCnt,curItem->iWhere); } } return; } //check party if(opcode==5) { STR_COND_005 * data = (STR_COND_005 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Party btIsLeader %i, iLevel %i, btReversed %i (NOT CODED)",opcode,data->btIsLeader,data->iLevel,data->btReversed); return; } //Near point if(opcode==6) { STR_COND_006 * data = (STR_COND_006 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Player near point (%.2f,%.2f), map %i (%s), distance < %i",opcode,(float)(data->iX / 100),(float)(data->iY / 100),data->iZoneSN,GServer->GetSTLZoneNameByID(data->iZoneSN),data->iRadius); return; } //world time if(opcode==7) { STR_COND_007 * data = (STR_COND_007 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: World time (NOT CODED, begintime %u, endtime %u)",opcode,data->ulTime,data->ulEndTime); return; } //Quest Time if(opcode==8) { STR_COND_008 * data = (STR_COND_008 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Player's quest time %s %u",opcode,Operators(data->btOp,buffero),data->ulTime); return; } //Check Skill if(opcode==9) { STR_COND_009 * data = (STR_COND_009 *)dataorg; if(data->btOp) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if skill %i (%s) DOES exist (sn2: %u)",opcode,data->iSkillSN1,GServer->GetSTLSkillByID(data->iSkillSN1),data->iSkillSN2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if skill %i (%s) does NOT exist (sn2: %u)",opcode,data->iSkillSN1,GServer->GetSTLSkillByID(data->iSkillSN1),data->iSkillSN2); } return; } //Unknow if(opcode==10) { STR_COND_010 * data = (STR_COND_010 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Unknown (NOT CODED) lowpc %u, highpc %u",opcode,data->btLowPcnt,data->btHighPcnt); return; } //Object variable if(opcode==11) { STR_COND_011 * data = (STR_COND_011 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Object variable",opcode); LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Check ObjVar[%i] %s %i (btwho %u)",data->nVarNo,Operators(data->btOp,buffero),data->iValue,data->btWho); return; } //Select Object in zone. if(opcode==12) { STR_COND_012 * data = (STR_COND_012 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Select Object %i in map %i (%s), IFO %i_%i.IFO (CODED FOR MONSTERS/NPC)",opcode,data->iEventID,data->iZone,GServer->GetSTLZoneNameByID(data->iZone),data->iX,data->iY); return; } //Select NPC if(opcode==13) { STR_COND_013 * data = (STR_COND_013 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Select NPC %i (%s)",opcode,data->iNpcNo,GServer->GetSTLMonsterNameByID(data->iNpcNo)); return; } //Check Quest Flag if(opcode==14) { STR_COND_014 * data = (STR_COND_014 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Quest Flag[%i] == %i",opcode,data->nSN,data->btOp); return; } //Unknow if(opcode==15) { STR_COND_015 * data = (STR_COND_015 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Unknown %u, %u (size %i) (NOT CODED)",opcode,data->nNumber1,data->nNumber2,size); return; } //Zone Time if(opcode==16) { STR_COND_016 * data = (STR_COND_016 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Zone Time (NOT CODED) (who %u, ultime %u, ulendtime %u)",opcode,data->btWho,data->ulTime,data->ulEndTime); return; } //Compare two NPC & Obj Variables. if(opcode==17) { STR_COND_017 * data = (STR_COND_017 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Does NPC %i (%s) ObjVar[%i] %s NPC %i %(%s) ObjVar[%i], junk1 %i, junk2 %i", opcode,data->NpcVar1.iNpcNo,GServer->GetSTLMonsterNameByID(data->NpcVar1.iNpcNo),data->NpcVar1.nVarNo, Operators(data->btOp,buffero), data->NpcVar2.iNpcNo,GServer->GetSTLMonsterNameByID(data->NpcVar2.iNpcNo), data->NpcVar2.nVarNo,data->NpcVar1.unused,data->NpcVar2.unused); return; } //Time on Date if(opcode==18) { STR_COND_018 * data = (STR_COND_018 *)dataorg; if(data->btDate!=0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT 0%i: Check day == %i and %.2i:%.2i:00<=time<=%.2i:%.2i:00",opcode,data->btDate,data->btHour1,data->btMin1,data->btHour2,data->btMin2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT 0%i: Check %.2i:%.2i:00<=time<=%.2i:%.2i:00",opcode,data->btHour1,data->btMin1,data->btHour2,data->btMin2); } return; } //Time on Day if(opcode==19) { STR_COND_019 * data = (STR_COND_019 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Time on Day (NOT CODED) (weekday %u, hour1 %u, min1 %u, hour2 %u, min2 %u)",opcode,data->btWeekDay,data->btHour1,data->btMin1,data->btHour2,data->btMin2); return; } //Unknow if(opcode==20) { STR_COND_020 * data = (STR_COND_020 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Unknown (NOT CODED) (no1 %u, no2 %u)",opcode,data->iNo1,data->iNo2); return; } //Near Selected NPC if(opcode==21) { STR_COND_021 * data = (STR_COND_021 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Near Selected NPC, range %u (CODED FOR PLAYERS), (type, %u)",opcode,data->iRadius,data->btSelObjType); return; } //Check Server/Channel if(opcode==22) { STR_COND_022 * data = (STR_COND_022 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Server/Channel %u, %u (NOT CODED)",opcode,data->nX,data->nY); return; } //In Clan if(opcode==23) { STR_COND_023 * data = (STR_COND_023 *)dataorg; if(data->btReg == 1) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if in Clan",opcode); } else if (data->btReg == 0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if NOT in Clan",opcode); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: ?%i? Clan",opcode,data->btReg); } return; } //Clan Position if(opcode==24) { STR_COND_024 * data = (STR_COND_024 *)dataorg; char buffer[20]; switch(data->btOP) { case 0: sprintf(buffer,"=="); break; case 1: sprintf(buffer,">"); break; case 2: sprintf(buffer,">="); break; case 3: sprintf(buffer,"<"); break; case 4: sprintf(buffer,"<="); break; case 10: sprintf(buffer,"!="); break; default: sprintf(buffer,"?%i?",data->btOP); break; } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if Clan Position is %s %i",opcode,buffer,data->nPOS); return; } //Clan Contribution if(opcode==25) { STR_COND_025 * data = (STR_COND_025 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Clan Contribution (NOT CODED) (ncont %u, op %u)",opcode,data->nCONT,data->btOP); return; } //Clan Grade if(opcode==26) { STR_COND_026 * data = (STR_COND_026 *)dataorg; char buffer[20]; switch(data->btOP) { case 0: sprintf(buffer,"=="); break; case 1: sprintf(buffer,">"); break; case 2: sprintf(buffer,">="); break; case 3: sprintf(buffer,"<"); break; case 4: sprintf(buffer,"<="); break; case 10: sprintf(buffer,"!="); break; default: sprintf(buffer,"?%i?",data->btOP); break; } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if Clan Grade is %s %i",opcode,buffer,data->nGRD); return; } //Check Clan Points amount. if(opcode==27) { STR_COND_027 * data = (STR_COND_027 *)dataorg; char buffer[20]; switch(data->btOP) { case 0: sprintf(buffer,"=="); break; case 1: sprintf(buffer,">"); break; case 2: sprintf(buffer,">="); break; case 3: sprintf(buffer,"<"); break; case 4: sprintf(buffer,"<="); break; case 10: sprintf(buffer,"!="); break; default: sprintf(buffer,"?%i?",data->btOP); break; } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if Clan Points is %s %i",opcode,buffer,data->nPOINT); return; } //Clan Grade if(opcode==28) { STR_COND_028 * data = (STR_COND_028 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Clan Grade (NOT CODED) (money %u, op %u)",opcode,data->iMONEY,data->btOP); return; } //Clan Members if(opcode==29) { STR_COND_029 * data = (STR_COND_029 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Clan Members (NOT CODED) (membercnt %u, op %u)",opcode,data->nMemberCNT,data->btOP); return; } //Clan Skills if(opcode==30) { STR_COND_030 * data = (STR_COND_030 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Clan Skills (NOT CODED) (skiil1 %u, skill2 %u, op %u)",opcode,data->nSkill1,data->nSkill2,data->btOP); return; } //Really unknown :) LogSp(MSG_WARNING,"\t\t\t\t\t CDT %.3i: Impossible to export QSD opcode, size %u",opcode,size-8); return; }
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; }
//LMA: exporting QSD Actions void CWorldServer::ExportQSDDataA(byte* dataorg,int size,int opcode) { char buffero[20]; char buffera[20]; char buffer[100]; UINT itemtype=0; UINT itemnum=0; //Update quest if(opcode==0) { STR_REWD_000 * data = (STR_REWD_000 *)dataorg; //0 remove, 1 start, 2 replace quest keep items, 3 replace quest delete items, 4 select switch(data->btOp) { case 0: { sprintf(buffer,"delete"); } break; case 1: { sprintf(buffer,"start"); } break; case 2: { sprintf(buffer,"replace (keep items)"); } break; case 3: { sprintf(buffer,"replace (delete items)"); } break; case 4: { sprintf(buffer,"select"); } break; default: { sprintf(buffer,"?%i?",data->btOp); } break; } LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: %s quest %i (%s)",opcode,buffer,data->iQuestSN,GServer->GetSTLQuestByID(data->iQuestSN)); return; } //Update quest items if(opcode==1) { STR_REWD_001 * data = (STR_REWD_001 *)dataorg; //0 remove, 1 start, 2 replace quest keep items, 3 replace quest delete items, 4 select switch(data->btOp) { case 0: { sprintf(buffer,"delete"); } break; case 1: { sprintf(buffer,"add"); } break; default: { sprintf(buffer,"?%i?",data->btOp); } break; } itemtype=gi(data->uiItemSN,0); itemnum=gi(data->uiItemSN,1); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: current quest: %s %i items %u (%i:%i, %s %s), (partyop %u)",opcode,buffer,data->nDupCNT,data->uiItemSN,itemtype,itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(itemtype,itemnum),data->btPartyOpt); return; } //Set quest variable if(opcode==2) { STR_REWD_002 * data = (STR_REWD_002 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: set %i Quest Variables",opcode,data->iDataCnt); for(dword i = 0; i < data->iDataCnt; i++) { dword address = i * sizeof(STR_QUEST_DATA); address += (dword)dataorg; address += 4; STR_QUEST_DATA* curQst = (STR_QUEST_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Set Quest Var[0x%04x (%u)][%i] %s %i",curQst->m_wVarTYPE,curQst->m_wVarTYPE,curQst->m_wVarNO,Operators(curQst->btOp,buffero),curQst->nValue); } return; } //Udapte Stats if(opcode==3) { STR_REWD_003 * data = (STR_REWD_003 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Update %i Stats",opcode,data->iDataCnt); for(dword i = 0; i < data->iDataCnt; i++) { dword address = i * 0x0C; address += (dword)dataorg; address += 4; STR_ABIL_DATA* curAbil = (STR_ABIL_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Set Stat %s %s %i",Abilities(curAbil->iType,buffera),Operators(curAbil->btOp,buffero),curAbil->iValue); } return; } //Set quest variable if(opcode==4) { STR_REWD_004 * data = (STR_REWD_004 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: set %i Quest Variables",opcode,data->iDataCnt); for(dword i = 0; i < data->iDataCnt; i++) { dword address = i * sizeof(STR_QUEST_DATA); address += (dword)dataorg; address += 4; STR_QUEST_DATA* curQst = (STR_QUEST_DATA*)address; LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Set Quest Var[0x%04x (%u)][%i] %s %i",curQst->m_wVarTYPE,curQst->m_wVarTYPE,curQst->m_wVarNO,Operators(curQst->btOp,buffero),curQst->nValue); } return; } //Give reward if(opcode==5) { STR_REWD_005 * data = (STR_REWD_005 *)dataorg; switch(data->btTarget) { case 0://EXP { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Give %u Exp, (partyop %u, itemopt %u, nPartyOpt %u)",opcode,data->iValue,data->btPartyOpt,data->nItemOpt,data->nPartyOpt); } break; case 1://Zuly { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Give %u Zuly, (partyop %u, itemopt %u, nPartyOpt %u)",opcode,data->iValue,data->btPartyOpt,data->nItemOpt,data->nPartyOpt); } break; case 2://Item { CItem nItem; itemtype=gi(data->iItemSN,0); itemnum=gi(data->iItemSN,1); nItem.itemtype = itemtype; nItem.itemnum = itemnum; if(nItem.IsStackable()) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Give %i (+formula()) item %u (%i:%i, %s %s), (partyop %u, itemopt %u, nPartyOpt %u)",opcode,data->iValue,data->iItemSN,nItem.itemtype,nItem.itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(nItem.itemtype,nItem.itemnum),data->btPartyOpt,data->nItemOpt,data->nPartyOpt); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Give 1 item %u (%i:%i, %s %s), (partyop %u, itemopt %u, nPartyOpt %u)",opcode,data->iItemSN,nItem.itemtype,nItem.itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(nItem.itemtype,nItem.itemnum),data->btPartyOpt,data->nItemOpt,data->nPartyOpt); } } break; default: { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Give Unknown reward %i, item %u, count / value %u, (partyop %u, itemopt %u, nPartyOpt %u)",opcode,data->btTarget,data->iItemSN,data->iValue,data->btPartyOpt,data->nItemOpt,data->nPartyOpt); } break; } return; } //restore HP / MP if(opcode==6) { STR_REWD_006 * data = (STR_REWD_006 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Restore %i%% HP, %i%% MP (partyop %u)",opcode,data->iPercentOfHP, data->iPercentOfMP,data->btPartyOpt); return; } //teleport if(opcode==7) { STR_REWD_007 * data = (STR_REWD_007 *)dataorg; if(data->btPartyOpt!=0) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Teleport to map %i (%s) at (%.2f,%.2f), with party members. (partyop %u)",opcode,data->iZoneSN,GServer->GetSTLZoneNameByID(data->iZoneSN),(float)(data->iX/100),(float)(data->iY/100),data->btPartyOpt); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Teleport to map %i (%s) at (%.2f,%.2f), (partyop %u)",opcode,data->iZoneSN,GServer->GetSTLZoneNameByID(data->iZoneSN),(float)(data->iX/100),(float)(data->iY/100),data->btPartyOpt); } return; } //Spawn monster if(opcode==8) { STR_REWD_008 * data = (STR_REWD_008 *)dataorg; if(data->iX==0||data->iY==0||data->iZoneSN==0) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn %i monsters %i (%s) near me (team %i), (btwho)",opcode,data->iHowMany,data->iMonsterSN,GServer->GetSTLMonsterNameByID(data->iMonsterSN),data->iTeamNo,data->btWho); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn %i monsters %i (%s) to map %i (%s) at (%.2f,%.2f) (team %i), (btwho %u)",opcode,data->iHowMany,data->iMonsterSN,GServer->GetSTLMonsterNameByID(data->iMonsterSN),data->iZoneSN,GServer->GetSTLZoneNameByID(data->iZoneSN),(float)(data->iX/100),(float)(data->iY/100),data->iTeamNo,data->btWho); } return; } //Execute Quest Trigger if(opcode==9) { STR_REWD_009 * data = (STR_REWD_009 *)dataorg; char* tempName = reinterpret_cast<char*>(&data->szNextTriggerSN) - 2; dword hash = MakeStrHash(tempName); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Execute Quest Trigger %s (%u)",opcode,tempName,hash); return; } //Reset Stats. if(opcode==10) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Reset Stats to default values",opcode); return; } //Update Object Var.. if(opcode==11) { STR_REWD_011 * data = (STR_REWD_011 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Update variable",opcode); if(data->btWho==0) { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Update ObjVar[%i] %s %i, who=%i (NPC)",data->nVarNo,Operators(data->btOp,buffero),data->iValue,data->btWho); } else if (data->btWho==1) { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Update ObjVar[%i] %s %i, who=%i (Event Object)",data->nVarNo,Operators(data->btOp,buffero),data->iValue,data->btWho); } else { LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Update ObjVar[%i] %s %i, who=?(%i)?",data->nVarNo,Operators(data->btOp,buffero),data->iValue,data->btWho); } return; } //NPC Speak... if(opcode==12) { //Log(MSG_INFO, "NPC trying to speak"); STR_REWD_012 * data = (STR_REWD_012 *)dataorg; //Log(MSG_INFO,"\t\t\t\t\t ACT %.3i: NPC Speak (NOT CODED for Client) (CODED for Monsters / NPC)",opcode); if(data->btMsgType == 1) { //Log(MSG_INFO,"\t\t\t\t\t\t |-> NPC Shouts LTB string %i, %s",data->iStrID,GServer->LtbstringQSD[data->iStrID]->LTBstring); } else if(data->btMsgType == 2) { //Log(MSG_INFO,"\t\t\t\t\t\t |-> NPC Announces LTB string %i, %s",data->iStrID,GServer->LtbstringQSD[data->iStrID]->LTBstring); } else { //Log(MSG_INFO,"\t\t\t\t\t\t |-> NPC ?(%i)? LTB string %i, %s",data->btMsgType,data->iStrID,GServer->LtbstringQSD[data->iStrID]->LTBstring); } return; } //Unknown (execute quest trigger?) if(opcode==13) { STR_REWD_013 * data = (STR_REWD_013 *)dataorg; char* tempName = reinterpret_cast<char*>(&data->szTriggerName) - 2; dword hash = MakeStrHash(tempName); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Execute Quest Trigger %s (%u) (who %u, isec %u, nexttrigger %u)",opcode,tempName,hash,data->btWho,data->iSec,data->m_HashNextTrigger); return; } //Learn Skill if(opcode==14) { STR_REWD_014 * data = (STR_REWD_014 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Learn Skill %i (%s), (op %u)",opcode,data->iSkillNo,GServer->GetSTLSkillByID(data->iSkillNo),data->btOp); return; } //Set Quest Flag if(opcode==15) { STR_REWD_015 * data = (STR_REWD_015 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set Quest Flag[%u]=%i",opcode,data->nSN,data->btOp); return; } //Unknown... if(opcode==16) { STR_REWD_016 * data = (STR_REWD_016 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown (NOT CODED), (op %u)",opcode,data->nGroupSN); return; } //reset all quest flags... if(opcode==17) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Reset All Quest Flags",opcode); return; } //Send Announcment... if(opcode==18) { STR_REWD_018 * data = (STR_REWD_018 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Send Announcment (NOT CODED), (strid %u, ncnt %u)",opcode,data->iStrID,data->nCnt); return; } //Execute Quest Trigger in Other Map... if(opcode==19) { STR_REWD_019 * data = (STR_REWD_019 *)dataorg; char* tempName = reinterpret_cast<char*>(&data->TriggerName) - 2; dword hash = MakeStrHash(tempName); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Execute Quest %s (hash %u) in Other Map %i (%s) for team %i (NOT CODED for Client) (CODED for Monsters / NPC), (triggerlength %u)",opcode,tempName,hash,data->nZoneNo,GServer->GetSTLZoneNameByID(data->nZoneNo),data->nTeamNo,data->nTriggerLength); return; } //PvP Status... if(opcode==20) { STR_REWD_020 * data = (STR_REWD_020 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: PvP Status set to %i (for maps mainly) (CODED FOR PLAYERS)",opcode,data->btNoType); return; } //Set Respawn Position... if(opcode==21) { STR_REWD_021 * data = (STR_REWD_021 *)dataorg; float X=(float)(data->iX)/((float)100); float Y=(float)(data->iY)/((float)100); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set Respawn Position to current map [%.2f;%.2f].",opcode,X,Y); return; } //Unknown... if(opcode==22) { STR_REWD_022 * data = (STR_REWD_022 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown (NOT CODED), (op %u)",opcode,data->btOp); return; } //Raise Clan Grade if(opcode==23) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Raise clan grade (+1) (NOT FULLY CODED) ",opcode); return; } //Clan Money... if(opcode==24) { STR_REWD_024 * data = (STR_REWD_024 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Clan Money btop=%i, money %i (NOT CODED)",opcode,data->btOP,data->iMONEY); return; } //Clan Points... if(opcode==25) { STR_REWD_025 * data = (STR_REWD_025 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Clan Points %s %i",opcode,Operators(data->btOP,buffero),data->nPOINT); return; } //Clan Skill... if(opcode==26) { STR_REWD_026 * data = (STR_REWD_026 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Clan Skill (NOT CODED), (skill %u,op %u)",opcode,data->nSkillNo,data->btOP); return; } //Clan Contribution... if(opcode==27) { STR_REWD_027 * data = (STR_REWD_027 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Clan Contribution (NOT CODED), (cont %u,op %u)",opcode,data->nCONT,data->btOP); return; } //Clan teleport if(opcode==28) { STR_REWD_028 * data = (STR_REWD_028 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Teleport all me and my clan members to map %i at (%.2f,%.2f) random range %i ",opcode,data->nZoneNo,(float)(data->iX/100),(float)(data->iY/100),data->iRange); return; } //LMA: Lua? if(opcode==29) { STR_REWD_029 * data = (STR_REWD_029 *)dataorg; char* tempName = reinterpret_cast<char*>(&data->luaName)-2; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: execute Lua %s (luaLen=%u) (NOT CODED, CLIENT SIDE ONLY?)",opcode,tempName,data->luaLen); return; } //Unspawn a NPC if(opcode==34) { STR_REWD_034 * data = (STR_REWD_034 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Removing previously selected NPC. (op %u)",opcode,data->btOP); return; } //Really unknown :) LogSp(MSG_WARNING,"\t\t\t\t\t ACT %.3i: Impossible to export QSD opcode, size %u",opcode,size-8); return; }
//LMA: We export AIP Conditions here void CWorldServer::ExportAipData(byte* dataorg,int size,int opcode) { UINT itemtype=0; UINT itemnum=0; //hold or attack if(opcode==0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Hold or attack, (NOT CODED)",opcode); return; } //(Damage > iDamage) == true iDamage cRecvOrGive if(opcode==1) { STR_AI_COND_001 * data = (STR_AI_COND_001 *)dataorg; if(data->cRecvOrGive == 0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: True IF damagecounter > %u",opcode,data->iDamage); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: True IF damagecounter < %u",opcode,data->iDamage); } return; } //Check Near (1) if(opcode==2) { STR_AI_COND_002 * data2 = (STR_AI_COND_002 *)dataorg; if(data2->btIsAllied == 1) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Nb monsters=>%i distance<%i level [%i,%i], (FindChar, NearChar)",opcode,data2->wChrNum,data2->iDistance,data2->nLevelDiff,data2->nLevelDiff2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Nb Players>=%i distance<%i level [%i,%i], (FindChar, NearChar)",opcode,data2->wChrNum,data2->iDistance,data2->nLevelDiff,data2->nLevelDiff2); } return; } //Check Distance (1) if(opcode==3) { STR_AI_COND_003 * data = (STR_AI_COND_003 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Dist current to source > %i",opcode,data->iDistance); return; } //Check Distance (2) if(opcode==4) { STR_AI_COND_004 * data = (STR_AI_COND_004 *)dataorg; if(data->cMoreLess == 0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Dist current to target >= %i",opcode,data->iDistance); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Dist current to target <= %i",opcode,data->iDistance); } return; } //Check ability (1) if(opcode==5) { STR_AI_COND_005 * data = (STR_AI_COND_005 *)dataorg; char buffer[3]; if(data->cMoreLess == 0) { sprintf ( buffer, ">"); } else { sprintf ( buffer, "<"); } switch(data->cAbType) { case 0: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check lvl %s %i",opcode,buffer,data->iDiff); break; case 1: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check attack power %s %i",opcode,buffer,data->iDiff); break; case 2: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check defense %s %i",opcode,buffer,data->iDiff); break; case 3: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check MDEF %s %i",opcode,buffer,data->iDiff); break; case 4: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check HP %s %i",opcode,buffer,data->iDiff); break; default: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check ?(%i)? %s %i",opcode,data->cAbType,buffer,data->iDiff); break; } return; } //Check HP if(opcode==6) { STR_AI_COND_006 * data = (STR_AI_COND_006 *)dataorg; if(data->cMoreLess == 0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check HP >= %i",opcode,data->wHP); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check HP <= %i",opcode,data->wHP); } return; } //Random Chance if(opcode==7) { STR_AI_COND_007 * data = (STR_AI_COND_007 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Random Chance < %i",opcode,data->cPercent); return; } //Check Near (2) if(opcode==8) { STR_AI_COND_008 * data = (STR_AI_COND_008 *)dataorg; if(data->btIsAllied == 1) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check 1 monster distance<%i level [%u,%u], (FindChar, NearChar)",opcode,data->iDistance,data->nLevelDiff,data->nLevelDiff2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check 1 Player distance<%i level [%u,%u], (FindChar, NearChar)",opcode,data->iDistance,data->nLevelDiff,data->nLevelDiff2); } return; } //Is there a target? if(opcode==9) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Is there a target?",opcode); return; } //Check ability /r target (1) if(opcode==10) { STR_AI_COND_010 * data = (STR_AI_COND_010 *)dataorg; char buffer[3]; if(data->cMoreLess == 0) { sprintf ( buffer, ">"); } else { sprintf ( buffer, "<"); } switch(data->cAbType) { case 0: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target lvl",opcode,buffer); break; case 1: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target attack power",opcode,buffer); break; case 2: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target defense",opcode,buffer); break; case 3: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target MDEF",opcode,buffer); break; case 4: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target HP",opcode,buffer); break; case 5: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target Charm (NOT CODED)",opcode,buffer); break; default: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target ?(%i)? ",opcode,buffer,data->cAbType); break; } return; } //Check ability /r target or number (1) if(opcode==11) { STR_AI_COND_011 * data = (STR_AI_COND_011 *)dataorg; char buffer[3]; if(data->cMoreLess == 0) { sprintf ( buffer, ">="); } else { sprintf ( buffer, "<="); } switch(data->cAbType) { case 0: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target lvl (or %i if %i>0)",opcode,buffer,data->iValue,data->iValue); break; case 1: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target attack power or (or %i if %i>0)",opcode,buffer,data->iValue,data->iValue); break; case 2: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target defense or (or %i if %i>0)",opcode,buffer,data->iValue,data->iValue); break; case 3: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target MDEF or (or %i if %i>0)",opcode,buffer,data->iValue,data->iValue); break; case 4: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target HP or (or %i if %i>0)",opcode,buffer,data->iValue,data->iValue); break; default: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s target ?(%i) or (or %i if %i>0)",opcode,buffer,data->cAbType,data->iValue,data->iValue); break; } return; } //check time if(opcode==12) { STR_AI_COND_012 * data = (STR_AI_COND_012 *)dataorg; if (data->cWhen == 1) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: True if night in map",opcode); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: True if day in map",opcode); } return; } //Check Target (1) if(opcode==13) { STR_AI_COND_013 * data = (STR_AI_COND_013 *)dataorg; char buffer[20]; char buffer1[20]; char buffer2[20]; if(data->btCheckTarget == 1) //check enemy { sprintf ( buffer, "enemy"); } else if(data->btCheckTarget == 0) //check self { sprintf ( buffer, "self"); } if (data->btStatusType == 1) // check for buffs { sprintf ( buffer1, "buff"); } else // check for debuffs { sprintf ( buffer1, "debuff"); } if (data->btHave == 1) //True if HAS buffs { sprintf ( buffer2, "needs buff"); } else // true if NOT HAS buffs { sprintf ( buffer2, "NO buffs needed"); } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %s and %s, %s ",opcode,buffer,buffer1,buffer2); return; } //check variable if(opcode==14) { STR_AI_COND_014 * data = (STR_AI_COND_014 *)dataorg; char buffer[3]; switch(data->btOp) { case 0: sprintf ( buffer, "=="); break; case 1: sprintf ( buffer, ">"); break; case 2: sprintf ( buffer, ">="); break; case 3: sprintf ( buffer, "<"); break; case 4: sprintf ( buffer, "<="); break; case 10: sprintf ( buffer, "!="); break; default: sprintf ( buffer, "??"); break; } if(data->btVarIDX==0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Objvar[%i] (EventID) %s %i",opcode,data->btVarIDX,buffer,data->iValue); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Objvar[%i] %s %i",opcode,data->btVarIDX,buffer,data->iValue); } return; } //check variable world if(opcode==15) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check WorldVar (NOT CODED)",opcode); return; } //check variable economy if(opcode==16) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check EconomyVar (NOT CODED)",opcode); return; } //select objvar ref if(opcode==17) { STR_AI_COND_017 * data = (STR_AI_COND_017 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Select NPC %i (%s) for Objvar",opcode,data->iNpcNo,GServer->GetSTLMonsterNameByID(data->iNpcNo)); return; } //select distance (summon to summoner) if(opcode==18) { STR_AI_COND_018 * data = (STR_AI_COND_018 *)dataorg; char buffer[3]; switch(data->btOp) { case 0: sprintf ( buffer, "=="); break; case 1: sprintf ( buffer, ">"); break; case 2: sprintf ( buffer, ">="); break; case 3: sprintf ( buffer, "<"); break; case 4: sprintf ( buffer, "<="); break; case 10: sprintf ( buffer, "!="); break; default: sprintf ( buffer, "??"); break; } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check distance summoner to summon %s %i",opcode,buffer,data->iDistance); return; } //check time if(opcode==19) { STR_AI_COND_019 * data = (STR_AI_COND_019 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check %i <=time<= %i",opcode,data->ulTime,data->ulEndTime); return; } //Check target /r value if(opcode==20) { STR_AI_COND_020 * data = (STR_AI_COND_020 *)dataorg; char buffer[3]; switch(data->btOp) { case 0: sprintf ( buffer, "=="); break; case 1: sprintf ( buffer, ">"); break; case 2: sprintf ( buffer, ">="); break; case 3: sprintf ( buffer, "<"); break; case 4: sprintf ( buffer, "<="); break; case 10: sprintf ( buffer, "!="); break; default: sprintf ( buffer, "??"); break; } switch(data->btAbType) { case 0: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target lvl %s %i",opcode,buffer,data->iValue); break; case 1: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target attack power %s %i",opcode,buffer,data->iValue); break; case 2: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target defense %s %i",opcode,buffer,data->iValue); break; case 3: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target MDEF %s %i",opcode,buffer,data->iValue); break; case 4: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target HP %s %i",opcode,buffer,data->iValue); break; default: LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check target ?(%i)? %s %i",opcode,buffer,data->btAbType,data->iValue); break; } return; } //test if no owner? if(opcode==21) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if monster has no owner",opcode); return; } //does my master have a "real" target? if(opcode==22) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check if my master has a real target",opcode); return; } //game map time? if(opcode==23) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Game map time (NOT CODED)",opcode); return; } //check time if(opcode==24) { STR_AI_COND_024 * data = (STR_AI_COND_024 *)dataorg; if(data->btDate!=0) { LogSp(MSG_INFO,"\t\t\t\t\t CDT 0%i: Check day == %i and %.2i:%.2i:00<=time<=%.2i:%.2i:00",opcode,data->btDate,data->btHour1,data->btMin1,data->btHour2,data->btMin2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT 0%i: Check %.2i:%.2i:00<=time<=%.2i:%.2i:00",opcode,data->btHour1,data->btMin1,data->btHour2,data->btMin2); } return; } //Check Weekday Time (5) if(opcode==25) { STR_AI_COND_025 * data = (STR_AI_COND_025 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT 0%i: Check wDayOfWeek == %i and %.2i:%.2i:00<=time<=%.2i:%.2i:00",opcode,data->btWeekDay,data->btHour1,data->btMin1,data->btHour2,data->btMin2); return; } //check server channel if(opcode==26) { STR_AI_COND_026 * data = (STR_AI_COND_026 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check server channel %u, %u (NOT CODED)",opcode,data->nMin,data->nMax); return; } //Check Near Character if(opcode==27) { STR_AI_COND_027 * data = (STR_AI_COND_027 *)dataorg; char buffer[3]; switch(data->btOp) { case 0: sprintf ( buffer, "=="); break; case 1: sprintf ( buffer, ">"); break; case 2: sprintf ( buffer, ">="); break; case 3: sprintf ( buffer, "<"); break; case 4: sprintf ( buffer, "<="); break; case 10: sprintf ( buffer, "!="); break; default: sprintf ( buffer, "??"); break; } if(data->btIsAllied == 1) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Nb monsters %s %i distance<%i level [%i,%i], (FindChar, NearChar)",opcode,buffer,data->wChrNum,data->iDistance,data->nLevelDiff,data->nLevelDiff2); } else { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Nb Players %s %i distance<%i level [%i,%i], (FindChar, NearChar)",opcode,buffer,data->wChrNum,data->iDistance,data->nLevelDiff,data->nLevelDiff2); } return; } //check variable for this monster if(opcode==28) { STR_AI_COND_028 * data = (STR_AI_COND_028 *)dataorg; char buffer[3]; switch(data->btOp) { case 0: sprintf ( buffer, "=="); break; case 1: sprintf ( buffer, ">"); break; case 2: sprintf ( buffer, ">="); break; case 3: sprintf ( buffer, "<"); break; case 4: sprintf ( buffer, "<="); break; case 10: sprintf ( buffer, "!="); break; default: sprintf ( buffer, "??"); break; } LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check monster var[%i] %s %i",opcode,data->nVarIDX,buffer,data->iValue); return; } //Check Target (2) if(opcode==29) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Check Target (2) (NOT CODED)",opcode); return; } //Unknown //LMA: Timer? if(opcode==30) { STR_AI_COND_030 * data = (STR_AI_COND_030 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Timer since spawn %u",opcode,data->Timer); return; } //Unknown if(opcode==31) { LogSp(MSG_INFO,"\t\t\t\t\t CDT %.3i: Unknown",opcode); return; } //Really unknown :) LogSp(MSG_WARNING,"\t\t\t\t\t CDT %.3i: Impossible to export AIP opcode, size %u",opcode,size-8); return; }
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; }
//LMA: We export AIP Actions here void CWorldServer::ExportAipDataA(byte* dataorg,int size,int opcode) { UINT itemtype=0; UINT itemnum=0; //Unknown if(opcode==0) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //Action if(opcode==1) { STR_AI_ACT_001 * data = (STR_AI_ACT_001 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Action, (0x781) %i",opcode,data->cAction); return; } //Say LTB string. if(opcode==2) { STR_AI_ACT_002 * data = (STR_AI_ACT_002 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Say LTB String %i (%s) (NOT CODED but OK since client Side)",opcode,data->iStrID,GServer->Ltbstring[data->iStrID]->LTBstring); return; } //Move if(opcode==3) { STR_AI_ACT_003 * data = (STR_AI_ACT_003 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Move from current position, distance %i at stance %i",opcode,data->iDistance,data->cSpeed); return; } //Move 2 if(opcode==4) { STR_AI_ACT_004 * data = (STR_AI_ACT_004 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Move from spawn position, distance %i at stance %i",opcode,data->iDistance,data->cSpeed); return; } //Move 3 if(opcode==5) { STR_AI_ACT_005 * data = (STR_AI_ACT_005 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Move from a char's position, distance 2 at stance %i",opcode,data->cSpeed); return; } //attack a player if ok with some stuff... if(opcode==6) { STR_AI_ACT_006 * data = (STR_AI_ACT_006 *)dataorg; char buffer[20]; char buffer1[20]; if(data->cMoreLess == 0) { sprintf(buffer,"biggest"); } else { sprintf(buffer,"lowest"); } switch(data->cAbType) { case 0: //level sprintf(buffer1,"level"); break; case 1: //Attack power sprintf(buffer1,"attack power"); break; case 2: //defense sprintf(buffer1,"defense"); break; case 3: //Magic Def sprintf(buffer1,"MDEF"); break; case 4: // HP sprintf(buffer1,"HP"); break; case 5: // Charm sprintf(buffer1,"charm"); break; } LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Attacks a player within distance %i if player has %s %s",opcode,data->iDistance,buffer, buffer1); return; } //Unknown if(opcode==7) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //Move 4 if(opcode==8) { STR_AI_ACT_008 * data = (STR_AI_ACT_008 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Monster moves to %i %% between source and current position at stance %i ",opcode,data->iDistance,data->cSpeed); return; } //Convert to another monster. if(opcode==9) { STR_AI_ACT_009 * data = (STR_AI_ACT_009 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Converts to monster %i (%s)",opcode,data->wMonster,GServer->GetSTLMonsterNameByID(data->wMonster)); return; } //Spawn monsters. if(opcode==10) { STR_AI_ACT_010 * data = (STR_AI_ACT_010 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn 1 monster %i near me",opcode,data->wMonster,GServer->GetSTLMonsterNameByID(data->wMonster)); return; } //Call for backup.. if(opcode==11) { STR_AI_ACT_011 * data = (STR_AI_ACT_011 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Call for backup, range %i max %i monsters",opcode,data->iDistance,data->iNumOfMonster); return; } //Attack. if(opcode==12) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Attacks NearChar",opcode); return; } //Attack. if(opcode==13) { STR_AI_ACT_013 * data = (STR_AI_ACT_013 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Attacks FindChar",opcode); return; } //Unknown if(opcode==14) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //retaliates. if(opcode==15) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Retaliates against the last player who hit me",opcode); return; } //run away. if(opcode==16) { STR_AI_ACT_016 * data = (STR_AI_ACT_016 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Runs away, distance %i",opcode,data->iDistance); return; } //drop item. if(opcode==17) { STR_AI_ACT_017 * data17 = (STR_AI_ACT_017 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Drops 1 item amongst:",opcode); for(int k=0;k<6;k++) { int nItem = data17->items[k]; if (nItem==0) continue; if(k==5&&nItem==0xCDCD) continue; itemtype=gi(nItem,0); itemnum=gi(nItem,1); LogSp(MSG_INFO,"\t\t\t\t\t\t |-> Item %u : (%i:%i), %s %s",nItem,itemtype,itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(itemtype,itemnum)); } return; } //Unknown if(opcode==18) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //Attack (same as 12) if(opcode==19) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Attacks NearChar",opcode); return; } //Spawn monster if(opcode==20) { STR_AI_ACT_020 * data = (STR_AI_ACT_020 *)dataorg; if(data->btPos == 0) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn monster %i (%s) distance %i ",opcode,data->cMonster,GServer->GetSTLMonsterNameByID(data->cMonster),data->iDistance); } else if(data->btPos == 1) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn monster %i (%s) distance %i ",opcode,data->cMonster,GServer->GetSTLMonsterNameByID(data->cMonster),data->iDistance); } else if(data->btPos == 2) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn monster %i (%s) distance %i near target",opcode,data->cMonster,GServer->GetSTLMonsterNameByID(data->cMonster),data->iDistance); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn monster %i (%s) distance %i near ??? (%i)",opcode,data->cMonster,GServer->GetSTLMonsterNameByID(data->cMonster),data->iDistance,data->btPos); } return; } //Unknown if(opcode==21) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //Unknown if(opcode==22) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Unknown",opcode); return; } //ghostseeds and ghosts and player summons commit suicide if(opcode==23) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Time to suicide",opcode); return; } //Do Skill if(opcode==24) { STR_AI_ACT_024 * data = (STR_AI_ACT_024 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Monster does skill %i (%s) ",opcode,data->nSkill,GServer->GetSTLSkillByID(data->nSkill)); return; } //Set Variable. if(opcode==25) { STR_AI_ACT_025 * data = (STR_AI_ACT_025 *)dataorg; char buffer[3]; switch(data->btOp) { case 5: sprintf(buffer,"="); break; case 6: sprintf(buffer,"+="); break; case 7: sprintf(buffer,"-="); break; case 9: sprintf(buffer,"++"); break; default: sprintf(buffer,"??"); break; } if(data->btVarIDX==0) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set ObjVar[%i] (eventID) %s %i ",opcode,data->btVarIDX,buffer,data->iValue); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set ObjVar[%i] %s %i ",opcode,data->btVarIDX,buffer,data->iValue); } return; } //set variable 2 (world?) if(opcode==26) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set variable (world?) (NOT CODED)",opcode); return; } //set variable 2 (economy?) if(opcode==27) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set variable (economy?) (NOT CODED)",opcode); return; } //shouts / announces LTB String. if(opcode==28) { STR_AI_ACT_028 * data = (STR_AI_ACT_028 *)dataorg; switch(data->btMsgType) { case 0: //whisper to client LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Whisper LTB string %i: %s",opcode,data->iStrID,GServer->Ltbstring[data->iStrID]->LTBstring); break; case 1: //shout to map { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Shouts LTB string %i: %s",opcode,data->iStrID,GServer->Ltbstring[data->iStrID]->LTBstring); } break; case 2: //announce to server. { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Announces LTB string %i: %s",opcode,data->iStrID,GServer->Ltbstring[data->iStrID]->LTBstring); } break; default: { //? LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Tells(%i)? LTB string %i: %s (NOT CODED)",opcode,data->btMsgType,data->iStrID,GServer->Ltbstring[data->iStrID]->LTBstring); } break; } return; } //moves to my owner location.. if(opcode==29) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Moves to owner's location",opcode); return; } //Do Quest Trigger. if(opcode==30) { STR_AI_ACT_030 * data = (STR_AI_ACT_030 *)dataorg; char* tempName = reinterpret_cast<char*>(&data->szTrigger) - 2; dword hash = MakeStrHash(tempName); LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Do quest trigger %s, %u",opcode,tempName,hash); return; } //monster attacks owner's target.. if(opcode==31) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Monster attacks owner's target",opcode); return; } //Set Zone ? if(opcode==32) { STR_AI_ACT_032 * data = (STR_AI_ACT_032 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set Pvp to %i in Zone %i",opcode,data->btOnOff,data->nZoneNo); return; } //Set Zone ? if(opcode==33) { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set Zone ? (NOT CODED)",opcode); return; } //Gives Item to caller. if(opcode==34) { STR_AI_ACT_034 * data = (STR_AI_ACT_034 *)dataorg; char itemtypes[15] = {4,0,0,0,0,0,0,0,0,0,1,2,2,4,3}; //LMA: exact way. itemtype = GServer->gi(data->nItemNum,0); itemnum = GServer->gi(data->nItemNum,1); int count = data->nCount; int durability=100; if( itemtypes[itemtype] == 0 ) { durability = GServer->STB_ITEM[itemtype-1].rows[itemnum][29]; } if (durability==0) { durability=100; } LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Gives %i item %i::%i (%s %s), durability %i to master",opcode,count,itemtype,itemnum,GServer->GetSTLItemPrefix(itemtype,itemnum),GServer->GetSTLObjNameByID(itemtype,itemnum),durability); return; } //Set Variable. if(opcode==35) { STR_AI_ACT_035 * data = (STR_AI_ACT_035 *)dataorg; char buffer[3]; switch(data->btOp) { case 5: sprintf(buffer,"="); break; case 6: sprintf(buffer,"+="); break; case 7: sprintf(buffer,"-="); break; case 9: sprintf(buffer,"++"); break; default: sprintf(buffer,"?(%i)?",data->btOp); break; } LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Set monster var[%i] %s %i ",opcode,data->nVarIDX,buffer,data->iValue); return; } //spawn monster with a master? if(opcode==36) { STR_AI_ACT_036 * data = (STR_AI_ACT_036 *)dataorg; LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: Spawn monster %i (%s) with master %i near me",opcode,data->nMonster,GServer->GetSTLMonsterNameByID(data->nMonster),data->btMaster); return; } //spawn monster with btmaster? if(opcode==37) { STR_AI_ACT_037 * data = (STR_AI_ACT_037 *)dataorg; if(data->nPos == 0) //spawn monster in a circle with radius iDistance around my current position { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: spawn monster %i (%s) with master %i near me",opcode,data->nMonster,GServer->GetSTLMonsterNameByID(data->nMonster),data->btMaster); } else if(data->nPos == 1) //spawn monster in a circle with radius iDistance around my destiny position { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: spawn monster %i (%s) with master %i near master",opcode,data->nMonster,GServer->GetSTLMonsterNameByID(data->nMonster),data->btMaster); } else if(data->nPos == 2) //spawn monster in a circle with radius iDistance around my target's current position { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: spawn monster %i (%s) with master %i near target",opcode,data->nMonster,GServer->GetSTLMonsterNameByID(data->nMonster),data->btMaster); } else { LogSp(MSG_INFO,"\t\t\t\t\t ACT %.3i: spawn monster %i (%s) with master %i near ?(%i)?",opcode,data->nMonster,GServer->GetSTLMonsterNameByID(data->nMonster),data->btMaster,data->nPos); } return; } //Really unknown :) LogSp(MSG_WARNING,"\t\t\t\t\t ACT %.3i: Impossible to export AIP opcode, size %i",opcode,size-8); return; }