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; } }