mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-13 22:01:04 -04:00
260 lines
14 KiB
Java
260 lines
14 KiB
Java
package script.ai;
|
|
|
|
import script.*;
|
|
import script.base_class.*;
|
|
import script.combat_engine.*;
|
|
import java.util.Arrays;
|
|
import java.util.Hashtable;
|
|
import java.util.Vector;
|
|
import script.base_script;
|
|
|
|
import script.library.ai_lib;
|
|
import script.library.colors;
|
|
import script.library.pet_lib;
|
|
import script.library.stealth;
|
|
import script.library.storyteller;
|
|
import script.library.utils;
|
|
|
|
public class ai_aggro extends script.base_script
|
|
{
|
|
public ai_aggro()
|
|
{
|
|
}
|
|
public static final int AGGRO_STATUS_NOT_VALID = 0;
|
|
public static final int AGGRO_STATUS_WAITING = 1;
|
|
public static final int AGGRO_STATUS_READY = 2;
|
|
public static final float AGGRO_RADIUS_INTERIOR_VERTICAL = 3.0f;
|
|
public static void requestAggroCheck(obj_id target) throws InterruptedException
|
|
{
|
|
final obj_id self = getSelf();
|
|
if (!isAttemptingAggroCheck(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::requestAggroCheck(YES) self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ")");
|
|
final int aggroStatus = ai_aggro.getAggroStatus(target);
|
|
switch (aggroStatus)
|
|
{
|
|
default:
|
|
case ai_aggro.AGGRO_STATUS_NOT_VALID:
|
|
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "creature_combat::handleAggroCheck() self(" + self + ":" + getName(self) + ") target(" + target + ") AGGRO_STATUS_NOT_VALID");
|
|
}
|
|
break;
|
|
case ai_aggro.AGGRO_STATUS_WAITING:
|
|
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "creature_combat::handleAggroCheck() self(" + self + ":" + getName(self) + ") target(" + target + ") AGGRO_STATUS_WAITING");
|
|
deltadictionary dict = self.getScriptVars();
|
|
dict.put("ai.aggrocheck." + target, true);
|
|
dictionary params = new dictionary();
|
|
params.put("target", target);
|
|
messageTo(self, "handleAggroCheck", params, rand(3.0f, 5.0f), false);
|
|
}
|
|
break;
|
|
case ai_aggro.AGGRO_STATUS_READY:
|
|
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "creature_combat::handleAggroCheck() self(" + self + ":" + getName(self) + ") target(" + target + ") AGGRO_STATUS_READY");
|
|
dictionary params = new dictionary();
|
|
params.put("target", target);
|
|
messageTo(self, "handleAggroStart", params, rand(2.5f, 4.5f), false);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::requestAggroCheck(NO) self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ")");
|
|
}
|
|
}
|
|
public static void stopAttemptingAggroCheck(obj_id target) throws InterruptedException
|
|
{
|
|
final obj_id self = getSelf();
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::stopAttemptingAggroCheck() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ")");
|
|
deltadictionary dict = self.getScriptVars();
|
|
dict.remove("ai.aggrocheck." + target);
|
|
}
|
|
public static boolean isAttemptingAggroCheck(obj_id target) throws InterruptedException
|
|
{
|
|
final obj_id self = getSelf();
|
|
deltadictionary dict = self.getScriptVars();
|
|
return dict.getBoolean("ai.aggrocheck." + target);
|
|
}
|
|
public static int getAggroStatus(obj_id target) throws InterruptedException
|
|
{
|
|
int result = AGGRO_STATUS_NOT_VALID;
|
|
final obj_id self = getSelf();
|
|
if (!isIdValid(self))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") I AM NO LONGER VALID");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") I AM NO LONGER VALID");
|
|
}
|
|
else if (isIncapacitated(self) || isDead(self))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") I AM DEAD");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") I AM DEAD");
|
|
}
|
|
else if (!isIdValid(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET NO LONGER VALID");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET NO LONGER VALID");
|
|
}
|
|
else if (isInvulnerable(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS INVULNERABLE");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS INVULNERABLE");
|
|
}
|
|
else if (ai_lib.isInCombat(self))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") I AM IN COMBAT");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") I AM IN COMBAT");
|
|
}
|
|
else if (!isInTriggerVolume(self, ai_lib.AGGRO_VOLUME_NAME, target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET OUT OF AGGRO VOLUME");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET OUT OF AGGRO VOLUME");
|
|
}
|
|
else if (!pvpCanAttack(self, target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") INVALID PVP TARGET");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") INVALID PVP TARGET");
|
|
}
|
|
else if (hasObjVar(target, "gm"))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS GM");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS GM");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else if (getState(target, STATE_FEIGN_DEATH) == 1)
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS FEIGNED");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS FEIGNED");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else if (isGameObjectTypeOf(getTopMostContainer(target), GOT_building_player))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IN PLAYER STRUCTURE");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IN PLAYER STRUCTURE");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else if (isIncapacitated(target))
|
|
{
|
|
if (isPlayer(target) || pet_lib.isCreaturePet(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") REZZURECTABLE TARGET IS INCAPACITATED");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") REZZURECTABLE TARGET IS INCAPACITATED");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS INCAPACITATED");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS INCAPACITATED");
|
|
}
|
|
}
|
|
else if (isDead(target))
|
|
{
|
|
if (isPlayer(target) || pet_lib.isCreaturePet(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") REZZURECTABLE TARGET IS DEAD");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") REZZURECTABLE TARGET IS DEAD");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS DEAD");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS DEAD");
|
|
}
|
|
}
|
|
else if (isAggroImmune(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET IS AGGRO IMMUNE");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET IS AGGRO IMMUNE");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
else
|
|
{
|
|
boolean doLosCheck = true;
|
|
boolean doDistanceCheck = true;
|
|
if ((isPlayer(target) && !pvpIsEnemy(self, target)) || pet_lib.isCreaturePet(target))
|
|
{
|
|
location here = getLocation(self);
|
|
if (isIdValid(here.cell))
|
|
{
|
|
location selfLoc = getWorldLocation(self);
|
|
location targetLoc = getWorldLocation(target);
|
|
float verticalDelta = Math.abs(targetLoc.y - selfLoc.y);
|
|
if (verticalDelta > AGGRO_RADIUS_INTERIOR_VERTICAL)
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") OUT OF VERTICAL RADIUS " + AGGRO_RADIUS_INTERIOR_VERTICAL);
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") OUT OF VERTICAL RADIUS " + AGGRO_RADIUS_INTERIOR_VERTICAL);
|
|
result = AGGRO_STATUS_WAITING;
|
|
doDistanceCheck = false;
|
|
doLosCheck = false;
|
|
}
|
|
}
|
|
if (doDistanceCheck)
|
|
{
|
|
final float respectRadius = aiGetRespectRadius(self, target);
|
|
final float distanceToTarget = getDistance(self, target);
|
|
if (distanceToTarget > respectRadius)
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") OUT OF RESPECT RADIUS " + respectRadius);
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") OUT OF RESPECT RADIUS " + respectRadius);
|
|
result = AGGRO_STATUS_WAITING;
|
|
doLosCheck = false;
|
|
}
|
|
}
|
|
}
|
|
if (doLosCheck)
|
|
{
|
|
if (canSee(self, target))
|
|
{
|
|
if (stealth.hasServerCoverState(target))
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET HAS COVER STATE (INVISIBLE)");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET HAS COVER STATE (INVISIBLE)");
|
|
if (utils.hasScriptVar(target, "sp_smoke_bomb"))
|
|
{
|
|
result = AGGRO_STATUS_NOT_VALID;
|
|
}
|
|
else
|
|
{
|
|
if (stealth.passiveDetectHiddenTarget(target, self, 100))
|
|
{
|
|
stealth.checkForAndMakeVisible(target);
|
|
result = AGGRO_STATUS_READY;
|
|
}
|
|
else
|
|
{
|
|
result = AGGRO_STATUS_NOT_VALID;
|
|
int roll = rand(1, 5);
|
|
if (roll == 1)
|
|
{
|
|
faceTo(self, target);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") TARGET ACQUIRED");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") TARGET ACQUIRED");
|
|
result = AGGRO_STATUS_READY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::getAggroStatus() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") CAN'T SEE TARGET");
|
|
debugSpeakMsgc(aiLoggingEnabled(self), self, "AggroCheck(" + target + ") CAN'T SEE TARGET");
|
|
result = AGGRO_STATUS_WAITING;
|
|
}
|
|
}
|
|
if (!storyteller.storytellerCombatCheck(self, target))
|
|
{
|
|
result = AGGRO_STATUS_NOT_VALID;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|