// //InspectCreatureDefMessage // int InspectCreatureDefMessage::handleMessage(SimulatorThread *sim, CharacterServerData *pld, SimulatorQuery *query, CreatureInstance *creatureInstance) { int CDefID = GetInteger(&sim->readPtr[sim->ReadPos], sim->ReadPos); g_CharacterManager.GetThread("SimulatorThread::handle_inspectCreatureDef"); CharacterData *charData = g_CharacterManager.GetPointerByID(CDefID); g_CharacterManager.ReleaseThread(); if (charData != NULL) { /* Is a player, is it for a player in the current active instance? If so, we need * appearance modifiers so use the creature instance's calculated appearance. * * TODO Em - I don't really like this. It makes me wonder if modifiers should * be on the creature def. */ CreatureInstance* cInst = creatureInstance == NULL || creatureInstance->actInst == NULL ? NULL : creatureInstance->actInst->GetPlayerByCDefID( charData->cdef.CreatureDefID); if (cInst != NULL) { CreatureDefinition cd(charData->cdef); cd.css.SetAppearance(cInst->PeekAppearance().c_str()); cd.css.SetEqAppearance(cInst->PeekAppearanceEq().c_str()); return PrepExt_CreatureDef(sim->SendBuf, &cd); // std::string currentAppearance = charData->cdef.css.appearance; // std::string currentEqAppearance = charData->cdef.css.eq_appearance; // charData->cdef.css.SetAppearance(cInst->PeekAppearance().c_str()); // charData->cdef.css.SetEqAppearance(cInst->PeekAppearanceEq().c_str()); // // AttemptSend(SendBuf, PrepExt_CreatureDef(SendBuf, &charData->cdef)); // // charData->cdef.css.SetAppearance(currentAppearance.c_str()); // charData->cdef.css.SetEqAppearance(currentEqAppearance.c_str()); } else return PrepExt_CreatureDef(sim->SendBuf, &charData->cdef); } else { CreatureDefinition *target = CreatureDef.GetPointerByCDef(CDefID); if (target != NULL) return PrepExt_CreatureDef(sim->SendBuf, target); else g_Logs.simulator->warn( "[%d] inspectCreatureDef: could not find ID [%d]", sim->InternalID, CDefID); } return 0; }
int QuestActionContainer :: ExecuteSingleCommand(SimulatorThread *caller, ExtendedQuestAction &e) { CreatureInstance *cInst = caller->creatureInst; switch(e.opCode) { case COMMAND_NONE: return 0; case CONDITION_HEROISM: { int value = cInst->css.heroism; if(Compare(value, e.param[0], e.param[1]) == true) return 0; caller->SendInfoMessage("You don't meet the heroism requirement.", INFOMSG_ERROR); return -1; } break; case CONDITION_HAS_ITEM: { int itemID = e.param[0]; int itemCount = e.param[1]; int count = caller->pld.charPtr->inventory.GetItemCount(INV_CONTAINER, itemID); if(count >= itemCount) return 0; caller->SendInfoMessage("You don't have the required items in your backpack inventory.", INFOMSG_ERROR); return -1; } break; case CONDITION_HAS_QUEST: { int questID = e.param[0]; if(caller->pld.charPtr->questJournal.activeQuests.HasQuestID(questID) > -1) return 0; return -1; } break; case CONDITION_BELOW_LEVEL: { int maxLevel = e.param[0]; if(caller->pld.charPtr->cdef.css.level < maxLevel) return 0; caller->SendInfoMessage("You are too high a level to accept this quest.", INFOMSG_ERROR); return -1; } break; case CONDITION_TRANSFORMED: { int creatureDefID = e.param[0]; if(cInst->IsTransformed() && cInst->transformCreatureId == creatureDefID) return 0; CreatureDefinition *def = CreatureDef.GetPointerByCDef(creatureDefID); char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), "You must be transformed into %s to continue with this quest.", def->css.display_name); caller->SendInfoMessage(buffer, INFOMSG_INFO); return -1; } case CONDITION_UNTRANSFORMED: { if(!cInst->IsTransformed()) return 0; CreatureDefinition *def = CreatureDef.GetPointerByCDef(cInst->transformCreatureId); char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), "You cannot be transformed into %s to continue with this quest.", def->css.display_name); caller->SendInfoMessage(buffer, INFOMSG_INFO); return -1; } break; case ACTION_CHANGE_HEROISM: cInst->css.heroism += e.param[0]; cInst->OnHeroismChange(); break; case ACTION_REMOVE_ITEM: { int itemID = e.param[0]; int itemCount = e.param[1]; char buffer[2048]; int len = caller->pld.charPtr->inventory.RemoveItemsAndUpdate(INV_CONTAINER, itemID, itemCount, buffer); if(len > 0) caller->AttemptSend(buffer, len); } break; case ACTION_SEND_TEXT: caller->SendInfoMessage(e.paramStr.c_str(), INFOMSG_INFO); break; case ACTION_PLAY_SOUND: { STRINGLIST sub; Util::Split(e.paramStr, "|", sub); while(sub.size() < 2) { sub.push_back(""); } caller->SendPlaySound(sub[0].c_str(), sub[1].c_str()); } break; case ACTION_BROADCAST: { char buffer[128]; Util::SafeFormat(buffer, sizeof(buffer), e.paramStr.c_str(), cInst->css.display_name); g_SimulatorManager.BroadcastMessage(buffer); } break; case ACTION_JOIN_GUILD: { int guildDefID = e.param[0]; GuildDefinition *gDef = g_GuildManager.GetGuildDefinition(guildDefID); if(gDef == NULL) caller->SendInfoMessage("Hrmph. This guild does not exist, please report a bug!", INFOMSG_INFO); else { caller->SendInfoMessage("Joining guild ..", INFOMSG_INFO); caller->JoinGuild(gDef, 0); char buffer[64]; Util::SafeFormat(buffer, sizeof(buffer), "You have joined %s", gDef->defName.c_str()); caller->SendInfoMessage(buffer, INFOMSG_INFO); } } break; case ACTION_TRANSFORM: { int creatureDefID = e.param[0]; g_Logs.data->debug("Transform: %v", creatureDefID); cInst->CAF_Transform(creatureDefID, 0, -1); } break; case ACTION_UNTRANSFORM: { g_Logs.data->debug("Untransform"); cInst->CAF_Untransform(); } break; default: return -1; } return 0; }
void InstanceScriptPlayer::RunImplementationCommands(int opcode) { ScriptCore::OpData *instr = &def->instr[curInst]; switch(opcode) { case OP_DESPAWN_ALL: { while(true) { CreatureInstance *source = actInst->GetNPCInstanceByCDefID(GetVarValue(instr->param1)); if(source == NULL) break; else { g_Log.AddMessageFormat("Despawn: %d (%d)", GetVarValue(instr->param1), source->CreatureID); actInst->spawnsys.Despawn(source->CreatureID); } } break; } case OP_DESPAWN: { CreatureInstance *source = actInst->GetInstanceByCID(GetVarValue(instr->param1)); g_Log.AddMessageFormat("Despawn: %d (%d)", GetVarValue(instr->param1), source->CreatureDefID); if(source == NULL) g_Log.AddMessageFormat("Despawn failed, %d does not exist.", GetVarValue(instr->param1)); else actInst->spawnsys.Despawn(GetVarValue(instr->param1)); break; } case OP_SPAWN: actInst->spawnsys.TriggerSpawn(instr->param1, 0, 0); //g_Log.AddMessageFormat("Fired spawn: %d", def->instr[curInst].param1); break; case OP_SPAWNAT: actInst->spawnsys.TriggerSpawn(instr->param1, instr->param2, 0); //g_Log.AddMessageFormat("Fired spawn: %d, creature: %d", def->instr[curInst].param1, def->instr[curInst].param2); break; case OP_SPAWNFLAG: actInst->spawnsys.TriggerSpawn(instr->param1, instr->param2, instr->param3); //g_Log.AddMessageFormat("Fired spawn: %d, creature: %d", def->instr[curInst].param1, def->instr[curInst].param2); break; case OP_SPAWNLOC: { //Pop in reverse order int x = PopVarStack(); int y = PopVarStack(); int z = PopVarStack(); if(x != 0 && y != 0 && z != 0) actInst->SpawnGeneric(instr->param1, x, y, z, 0); } break; case OP_COUNTALIVE: vars[instr->param2] = actInst->CountAlive(instr->param1); break; case OP_GETNPCID: { int creatureID = 0; CreatureInstance *search = actInst->GetNPCInstanceByCDefID(instr->param1); if(search != NULL) creatureID = search->CreatureID; vars[instr->param2] = creatureID; } break; case OP_SETTARGET: { CreatureInstance *source = actInst->GetInstanceByCID(GetVarValue(instr->param1)); CreatureInstance *target = actInst->GetInstanceByCID(GetVarValue(instr->param2)); if(source != NULL && target != NULL) source->SelectTarget(target); } break; case OP_SCAN_NPC_CID: { InstanceLocation *loc = GetLocationByName(GetStringPtr(instr->param1)); int index = VerifyIntArrayIndex(instr->param2); if(index >= 0) ScanNPCCID(loc, intArray[index].arrayData); } break; case OP_SCAN_NPC_CID_FOR: { InstanceLocation *loc = GetLocationByName(GetStringPtr(instr->param1)); int index = VerifyIntArrayIndex(instr->param2); if(index >= 0) ScanNPCCIDFor(loc, instr->param3, intArray[index].arrayData); } break; case OP_GET_CDEF: { int cdef = 0; CreatureInstance *ci = GetNPCPtr(GetVarValue(instr->param1)); if(ci) cdef = ci->CreatureDefID; SetVar(instr->param2, cdef); } break; case OP_GET_HEALTH_PERCENT: { CreatureInstance *ci = GetNPCPtr(GetVarValue(instr->param1)); int health = 0; if(ci) health = static_cast<int>(ci->GetHealthRatio() * 100.0F); SetVar(instr->param2, health); } break; case OP_ORDER_WALK: { CreatureInstance *ci = GetNPCPtr(GetVarValue(instr->param1)); if(ci) { ci->SetServerFlag(ServerFlags::ScriptMovement, true); ci->previousPathNode = 0; //Disable any path links. ci->nextPathNode = 0; ci->tetherNodeX = instr->param2; ci->tetherNodeZ = instr->param3; ci->CurrentTarget.DesLocX = instr->param2; ci->CurrentTarget.DesLocZ = instr->param3; ci->CurrentTarget.desiredRange = 30; ci->Speed = 20; } } break; case OP_GET_TARGET: { int targetID = 0; CreatureInstance *ci = GetNPCPtr(GetVarValue(instr->param1)); if(ci) { if(ci->CurrentTarget.targ != NULL) targetID = ci->CurrentTarget.targ->CreatureID; } SetVar(instr->param2, targetID); } break; case OP_AI_SCRIPT_JUMP: { CreatureInstance *ci = GetNPCPtr(GetVarValue(instr->param1)); if(ci) { if(ci->aiScript) ci->aiScript->JumpToLabel(GetStringPtr(instr->param2)); } } break; case OP_INFO: { char buffer[4096]; int wpos = PrepExt_SendInfoMessage(buffer, GetStringPtr(instr->param1), INFOMSG_INFO); actInst->LSendToAllSimulator(buffer, wpos, -1); } break; case OP_CHAT: { char buffer[4096]; int wpos = PrepExt_GenericChatMessage(buffer, 0, GetStringPtr(instr->param1), GetStringPtr(instr->param2), GetStringPtr(instr->param3)); actInst->LSendToAllSimulator(buffer, wpos, -1); } break; case OP_BROADCAST: { char buffer[4096]; if(actInst->mZoneDefPtr->mGrove) { int wpos = PrepExt_SendInfoMessage(buffer, GetStringPtr(instr->param1), INFOMSG_INFO); actInst->LSendToAllSimulator(buffer, wpos, -1); } else { int wpos = PrepExt_Broadcast(buffer, GetStringPtr(instr->param1)); actInst->LSendToAllSimulator(buffer, wpos, -1); } } break; default: g_Log.AddMessageFormat("Unidentified InstanceScriptPlayer OpCode: %d", instr->opCode); break; } }
bool AINutPlayer::IsCIDBusy(int CID) { CreatureInstance *targ = ResolveCreatureInstance(CID); return targ == NULL ? 0 : targ->AICheckIfAbilityBusy(); }
void AIScriptPlayer :: RunImplementationCommands(int opcode) { ScriptCore::OpData *in = &def->instr[curInst]; switch(opcode) { case OP_USE: if(attachedCreature->ab[0].bPending == false) { //DEBUG OUTPUT if(g_Config.DebugLogAIScriptUse == true) { const Ability2::AbilityEntry2* abptr = g_AbilityManager.GetAbilityPtrByID(in->param1); g_Logs.script->debug("Using: %v", abptr->GetRowAsCString(Ability2::ABROW::NAME)); } //END DEBUG OUTPUT int r = attachedCreature->CallAbilityEvent(in->param1, EventType::onRequest); if(r != 0) { //Notify the creature we failed, may need a distance check. //The script should wait and retry soon. attachedCreature->AICheckAbilityFailure(r); nextFire = g_ServerTime + USE_FAIL_DELAY; if(g_Config.DebugLogAIScriptUse == true) { const Ability2::AbilityEntry2* abptr = g_AbilityManager.GetAbilityPtrByID(in->param1); g_Logs.script->debug("Using: %v Failed: %v", abptr->GetRowAsCString(Ability2::ABROW::NAME), g_AbilityManager.GetAbilityErrorCode(r)); } if(attachedCreature->AIAbilityFailureAllowRetry(r) == true) { advance = 0; //Don't advance the instruction so that we can retry this command. } } } else { advance = 0; nextFire = g_ServerTime + USE_FAIL_DELAY; } break; case OP_GETWILL: SetVar(def->instr[curInst].param1, attachedCreature->css.will); break; case OP_GETWILLCHARGE: SetVar(def->instr[curInst].param1, attachedCreature->css.will_charges); break; case OP_GETMIGHT: SetVar(def->instr[curInst].param1, attachedCreature->css.might); break; case OP_GETMIGHTCHARGE: SetVar(def->instr[curInst].param1, attachedCreature->css.might_charges); break; case OP_HASTARGET: SetVar(def->instr[curInst].param1, (attachedCreature->CurrentTarget.targ != NULL) ? 1 : 0); break; case OP_GETLEVEL: SetVar(def->instr[curInst].param1, attachedCreature->css.level); break; case OP_DEBUGPRINT: g_Logs.script->debug("[DEBUGPRINT] (%v) %v", def->scriptName, def->stringList[def->instr[curInst].param1].c_str()); break; case OP_GETCOOLDOWN: { const char *cooldownName = GetStringTableEntry(def->instr[curInst].param1); int cooldownID = g_AbilityManager.ResolveCooldownCategoryID(cooldownName); int result = (attachedCreature->HasCooldown(cooldownID) == true) ? 1 : 0; SetVar(in->param2, result); } break; case OP_ISBUSY: { int result = (attachedCreature->AICheckIfAbilityBusy() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_COUNTENEMYNEAR: { float x = (float)attachedCreature->CurrentX; float z = (float)attachedCreature->CurrentZ; SetVar(in->param2, attachedCreature->AICountEnemyNear(in->param1, x, z)); } break; case OP_COUNTENEMYAT: { float x = (float)attachedCreature->CurrentX; float z = (float)attachedCreature->CurrentZ; if(attachedCreature->CurrentTarget.targ != NULL) { x = (float)attachedCreature->CurrentTarget.targ->CurrentX; z = (float)attachedCreature->CurrentTarget.targ->CurrentZ; } SetVar(in->param2, attachedCreature->AICountEnemyNear(in->param1, x, z)); } break; case OP_HEALTHPERCENT: SetVar(in->param1, static_cast<int>(attachedCreature->GetHealthRatio() * 100.0F)); break; case OP_TARGETHEALTHPERCENT: { int health = 0; if(attachedCreature->CurrentTarget.targ != NULL) health = static_cast<int>(attachedCreature->CurrentTarget.targ->GetHealthRatio() * 100.0F); SetVar(in->param1, health); } break; case OP_SETELAPSEDTIME: SetVar(in->param1, static_cast<int>(g_PlatformTime.getElapsedMilliseconds())); break; case OP_TIMEOFFSET: { unsigned long offset = g_PlatformTime.getElapsedMilliseconds() - static_cast<unsigned long>(GetVarValue(in->param1)); SetVar(in->param2, static_cast<int>(offset)); } break; case OP_VISUALEFFECT: attachedCreature->SendEffect(GetStringTableEntry(in->param1), 0); break; case OP_VISUALEFFECTT: { int targID = 0; if(attachedCreature->CurrentTarget.targ != NULL) targID = attachedCreature->CurrentTarget.targ->CreatureID; attachedCreature->SendEffect(GetStringTableEntry(in->param1), targID); } break; case OP_SAY: attachedCreature->SendSay(GetStringTableEntry(in->param1)); break; case OP_INSTANCECALL: attachedCreature->actInst->ScriptCall(GetStringTableEntry(in->param1)); break; case OP_GETIDLEMOB: { int creatureDefID = in->param1; int creatureID = attachedCreature->AIGetIdleMob(creatureDefID); SetVar(in->param2, creatureID); } break; case OP_GETTARGET: { int creatureID = 0; if(attachedCreature->CurrentTarget.targ != NULL) creatureID = attachedCreature->CurrentTarget.targ->CreatureID; SetVar(in->param1, creatureID); } break; case OP_GETSELF: SetVar(in->param1, attachedCreature->CreatureID); break; case OP_SETOTHERTARGET: { int creatureID = GetVarValue(in->param1); int creatureIDTarg = GetVarValue(in->param2); attachedCreature->AIOtherSetTarget(creatureID, creatureIDTarg); } break; case OP_AISCRIPTCALL: { int creatureID = GetVarValue(in->param1); attachedCreature->AIOtherCallLabel(creatureID, GetStringTableEntry(in->param2)); } break; case OP_ISTARGETENEMY: { int result = (attachedCreature->AIIsTargetEnemy() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_ISTARGETFRIENDLY: { int result = (attachedCreature->AIIsTargetFriend() == true) ? 1 : 0; SetVar(in->param1, result); } break; case OP_SETSPEED: attachedCreature->Speed = in->param1; break; case OP_GETTARGETCDEF: { int targCDef = 0; if(attachedCreature->CurrentTarget.targ != NULL) targCDef = attachedCreature->CurrentTarget.targ->CreatureDefID; SetVar(in->param1, targCDef); } break; case OP_GETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); SetVar(in->param2, static_cast<int>(attachedCreature->AIGetProperty(propName, false))); } break; case OP_GETTARGETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); SetVar(in->param2, static_cast<int>(attachedCreature->AIGetProperty(propName, true))); } break; case OP_DISPELTARGETPROPERTY: { const char *propName = GetStringTableEntry(in->param1); int sign = in->param2; attachedCreature->AIDispelTargetProperty(propName, sign); } break; case OP_RANDOMIZE: SetVar(in->param2, randint(1, in->param1)); break; case OP_FINDCDEF: { int creatureID = 0; CreatureInstance *targ = attachedCreature->actInst->GetNPCInstanceByCDefID(in->param1); if(targ != NULL) creatureID = targ->CreatureID; SetVar(in->param2, creatureID); } break; case OP_PLAYSOUND: { STRINGLIST sub; Util::Split(GetStringTableEntry(in->param1), "|", sub); while(sub.size() < 2) { sub.push_back(""); } attachedCreature->SendPlaySound(sub[0].c_str(), sub[1].c_str()); } break; case OP_GETBUFFTIER: SetVar(in->param2, attachedCreature->AIGetBuffTier(in->param1, false)); break; case OP_GETTARGETBUFFTIER: SetVar(in->param2, attachedCreature->AIGetBuffTier(in->param1, true)); break; case OP_TARGETINRANGE: SetVar(in->param2, (attachedCreature->InRange_Target((float)in->param1) == true) ? 1 : 0); break; case OP_GETTARGETRANGE: SetVar(in->param1, attachedCreature->AIGetTargetRange()); break; case OP_SETGTAE: attachedCreature->AISetGTAE(); break; case OP_GETSPEED: { int result = 0; int creatureID = GetVarValue(in->param1); CreatureInstance *targ = ResolveCreatureInstance(creatureID); if(targ != NULL) { result = targ->Speed; } SetVar(in->param2, result); } break; case OP_CIDISBUSY: { int result = 0; CreatureInstance *targ = ResolveCreatureInstance(GetVarValue(in->param1)); if(targ != NULL) { result = (targ->AICheckIfAbilityBusy() == true) ? 1 : 0; } SetVar(in->param2, result); } break; default: g_Logs.script->error("Unidentified op type: %v", in->opCode); break; } }
void QuestScriptPlayer::RunImplementationCommands(int opcode) { ScriptCore::OpData *instr = &def->instr[curInst]; switch(instr->opCode) { case OP_INFO: { char Buffer[1024]; int size = PrepExt_SendInfoMessage(Buffer, def->stringList[instr->param1].c_str(), INFOMSG_INFO); simCall->AttemptSend(Buffer, size); } break; case OP_EFFECT: { char Buffer[1024]; int size = PrepExt_SendEffect(Buffer, targetID, def->stringList[instr->param1].c_str(), 0); actInst->LSendToAllSimulator(Buffer, size, -1); } break; case OP_WAITFINISH: if(!(RunFlags & FLAG_FINISHED)) advance = 0; break; case OP_NPCUNUSABLE: CreatureInstance *targ; targ = actInst->GetNPCInstanceByCID(targetID); if(targ != NULL) { targ->SetServerFlag(ServerFlags::IsUnusable, true); //Trigger for deletion if(def->instr[curInst].param1 != 0) { //targ->_AddStatusList(StatusEffects::DEAD, -1); targ->SetServerFlag(ServerFlags::TriggerDelete, true); targ->deathTime = g_ServerTime + def->instr[curInst].param1; } } break; case OP_NPCREMOVE: actInst->RemoveNPCInstance(targetID); break; case OP_REQUIRECDEF: if(targetCDef != instr->param1) active = false; break; case OP_SPAWN: actInst->spawnsys.TriggerSpawn(instr->param1, 0, 0); break; case OP_SPAWNAT: actInst->SpawnAtProp(instr->param1, instr->param2, RunTimeVar[0], RunTimeVar[1]); break; case OP_WARPZONE: simCall->MainCallSetZone(instr->param1, 0, true); break; case OP_JMPCDEF: if(targetCDef == instr->param1) { curInst = instr->param2; advance = 0; } break; case OP_SETVAR: int index; index = Util::ClipInt(instr->param1, 0, MAX_VAR - 1); RunTimeVar[index] = instr->param2; break; case OP_EMOTE: { char Buffer[1024]; int size = PrepExt_GenericChatMessage(Buffer, sourceID, "", "emote", def->stringList[instr->param1].c_str()); actInst->LSendToAllSimulator(Buffer, size, -1); } break; default: g_Log.AddMessageFormat("Unidentified op type: %d", instr->opCode); break; } }