Files
dsrc/sku.0/sys.server/compiled/game/script/ai/ai_combat_movement.java
T
2018-06-07 00:32:29 +01:00

342 lines
13 KiB
Java
Executable File

package script.ai;
import script.deltadictionary;
import script.library.utils;
import script.location;
import script.obj_id;
public class ai_combat_movement extends script.base_script
{
public ai_combat_movement()
{
}
public static final int MOVEMODE_INVALID = 0;
public static final int MOVEMODE_FOLLOW = 1;
public static final int MOVEMODE_RANDOM = 2;
public static final int MOVEMODE_PREPARING_TO_MOVE = 3;
public static final int MOVEMODE_PATHING_HOME = 4;
public static final int MOVEMODE_PREPARING_TO_STAND = 5;
public static final int MOVEMODE_MOVING_TO_HEAL = 7;
public static final int MOVEMODE_IDLE = 9;
public static final int MOVEMODE_FLEE = 10;
public static final int MOVEMODE_FOLLOW_FORMATION = 11;
public static final int MOVEMODE_MOVING_TO_SEE = 12;
public static final int MOVEMODE_MOVING_TO_DEATHBLOW = 13;
public static final int MOVEMODE_SWARM = 14;
public static final int MOVEMOVE_EVADE = 15;
public static void aiClearMoveMode() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_INVALID);
}
public static void aiIdle() throws InterruptedException
{
if (aiIsIdle())
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_IDLE);
stop(self);
}
public static boolean aiIsIdle() throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_IDLE);
}
public static void aiMoveToSee(obj_id target) throws InterruptedException
{
if (aiIsMovingToSee(target))
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_MOVING_TO_SEE);
dict.put("ai.combat.moveToSee.target", target);
pathTo(self, getLocation(target));
}
public static boolean aiIsMovingToSee(obj_id target) throws InterruptedException
{
if (aiIsMovingToSee() && aiGetMoveToSeeTarget() == target)
{
return true;
}
return false;
}
public static boolean aiIsMovingToSee() throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_MOVING_TO_SEE);
}
public static obj_id aiGetMoveToSeeTarget() throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
return dict.getObjId("ai.combat.moveToSee.target");
}
public static void aiMoveToDeathBlow(obj_id target) throws InterruptedException
{
if (aiIsMovingToDeathBlow(target) || !isIncapacitated(target))
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
LOGC(aiLoggingEnabled(self) && !isIncapacitated(target), "debug_ai", "ai_combat_movement::aiMoveToDeathBlow() self(" + self + ":" + getName(self) + ") target(" + target + ") Trying to death blow a non-incapacitated target.");
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_MOVING_TO_DEATHBLOW);
dict.put("ai.combat.moveToDeathBlow.target", target);
pathTo(self, getLocation(target));
}
public static boolean aiIsMovingToDeathBlow(obj_id target) throws InterruptedException
{
if ((aiIsMovingToDeathBlow()) && (aiGetMoveToDeathBlowTarget() == target))
{
return true;
}
return false;
}
public static boolean aiIsMovingToDeathBlow() throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_MOVING_TO_DEATHBLOW);
}
public static obj_id aiGetMoveToDeathBlowTarget() throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
return dict.getObjId("ai.combat.moveToDeathBlow.target");
}
public static void aiFollow(obj_id target, float minDistance, float maxDistance) throws InterruptedException
{
if (aiIsFollowing(target, minDistance, maxDistance))
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_FOLLOW);
dict.put("ai.combat.follow.target", target);
dict.put("ai.combat.follow.minDistance", minDistance);
dict.put("ai.combat.follow.maxDistance", maxDistance);
follow(self, target, minDistance, maxDistance);
}
public static void aiSwarm(obj_id target, float minDistance, float maxDistance) throws InterruptedException
{
if (aiIsSwarming(target, minDistance, maxDistance))
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_SWARM);
dict.put("ai.combat.follow.target", target);
dict.put("ai.combat.follow.minDistance", minDistance);
dict.put("ai.combat.follow.maxDistance", maxDistance);
swarm(self, target);
}
public static boolean aiIsFollowing(obj_id target, float minDistance, float maxDistance) throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
if ((dict.getInt("ai.combat.moveMode") == MOVEMODE_FOLLOW) && (dict.getObjId("ai.combat.follow.target") == target) && (dict.getFloat("ai.combat.follow.minDistance") == minDistance) && (dict.getFloat("ai.combat.follow.maxDistance") == maxDistance))
{
return true;
}
return false;
}
public static boolean aiIsSwarming(obj_id target, float minDistance, float maxDistance) throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
if ((dict.getInt("ai.combat.moveMode") == MOVEMODE_SWARM) && (dict.getObjId("ai.combat.follow.target") == target) && (dict.getFloat("ai.combat.follow.minDistance") == minDistance) && (dict.getFloat("ai.combat.follow.maxDistance") == maxDistance))
{
return true;
}
return false;
}
public static float getActualEvadeChance(obj_id ai, float min, float max) throws InterruptedException
{
float rslt = max;
float difference = max - min;
float maxHealth = (float)getMaxHealth(ai);
float curHealth = (float)getHealth(ai);
rslt -= (difference * (curHealth / maxHealth));
return rslt;
}
public static boolean aiEvade(obj_id target, obj_id ai, range_info aiWeaponRanges, float minChance, float maxChance) throws InterruptedException
{
obj_id primaryWeapon = aiGetPrimaryWeapon(ai);
obj_id secondaryWeapon = aiGetSecondaryWeapon(ai);
float primaryRange = 0;
float secondaryRange = 0;
obj_id master = getMaster(ai);
if (isIdValid(master))
{
return false;
}
if (hasScript(ai, "systems.dungeon_sequencer.ai_controller"))
{
return false;
}
if (isIdValid(primaryWeapon) && exists(primaryWeapon))
{
final range_info primaryWeaponRange = aiGetWeaponRangeInfo(primaryWeapon);
primaryRange = primaryWeaponRange.maxRange;
}
if (isIdValid(secondaryWeapon) && exists(secondaryWeapon))
{
final range_info secondaryWeaponRange = aiGetWeaponRangeInfo(secondaryWeapon);
secondaryRange = secondaryWeaponRange.maxRange;
}
if (primaryRange <= 10f && secondaryRange <= 10f)
{
return false;
}
final int now = getGameTime();
final int then = utils.getIntScriptVar(ai, "aiIsEvading");
if (then != 0 && (now - then) < 15)
{
return false;
}
float minDistance = 0;
float maxDistance = 1f;
if (getTopMostContainer(ai) == ai)
{
minDistance = 15f;
maxDistance = 20f;
}
else
{
minDistance = 4f;
maxDistance = 10f;
}
if (isPlayer(target))
{
float mod = 0;
range_info playerRange = getWeaponRangeInfo(getCurrentWeapon(target));
if (playerRange != null && playerRange.maxRange < 10)
{
if (minChance == 1f)
{
mod = 0.985f;
}
else
{
mod = 0.9f;
}
minDistance = 5f;
if (rand(1, 100) < 30)
{
maxDistance = playerRange.maxRange + 5;
}
else
{
maxDistance = playerRange.maxRange - 1;
}
if (minDistance > maxDistance)
{
minDistance = maxDistance;
}
}
maxChance -= (maxChance * mod);
if (minChance > maxChance)
{
minChance = maxChance;
}
}
float chance = getActualEvadeChance(ai, minChance, maxChance);
if (chance < 1f && rand(0.0f, 1.0f) > chance)
{
return false;
}
location evasionTargetLoc = getValidAwayLocation(target, minDistance, maxDistance);
if (evasionTargetLoc == null || getLocation(ai).cell != evasionTargetLoc.cell)
{
return false;
}
if (!canSee(ai, evasionTargetLoc))
{
return false;
}
utils.setScriptVar(ai, "aiIsEvading", getGameTime());
pathTo(ai, evasionTargetLoc);
faceTo(ai, target);
return true;
}
public static location getValidAwayLocation(obj_id mob, float minDistance, float maxDistance) throws InterruptedException
{
location from = getLocation(mob);
location evasionTarget = utils.getRandomAwayLocation(from, minDistance, maxDistance);
evasionTarget.y += 0.5f;
if (!canSee(mob, evasionTarget))
{
return null;
}
evasionTarget.y -= 0.5f;
return evasionTarget;
}
public static void aiFlee(obj_id target, float distance) throws InterruptedException
{
if (aiIsFleeing(target, distance))
{
return;
}
final obj_id self = getSelf();
if (aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self))
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_FLEE);
dict.put("ai.combat.flee.target", target);
dict.put("ai.combat.flee.distance", distance);
flee(self, target, distance, distance);
messageTo(self, "redoYaw", null, 30, false);
}
public static boolean aiIsFleeing(obj_id ai) throws InterruptedException
{
final deltadictionary dict = ai.getScriptVars();
return dict.getInt("ai.combat.moveMode") == MOVEMODE_FLEE;
}
public static boolean aiIsFleeing(obj_id target, float distance) throws InterruptedException
{
final obj_id self = getSelf();
final deltadictionary dict = self.getScriptVars();
if ((dict.getInt("ai.combat.moveMode") == MOVEMODE_FLEE) && (dict.getObjId("ai.combat.flee.target") == target) && (dict.getFloat("ai.combat.flee.distance") == distance))
{
return true;
}
return false;
}
public static boolean isAiImmobile(obj_id subject) throws InterruptedException
{
return hasObjVar(subject, "isImmobile") ? getBooleanObjVar(subject, "isImmobile") : false;
}
}