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

493 lines
16 KiB
Java
Executable File

package script.ai;
import script.*;
import script.library.*;
public class ai_combat extends script.base_script
{
public ai_combat()
{
}
public static void doAttack(obj_id ai, obj_id target) throws InterruptedException
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::doAttack() ai(" + ai + ")");
startCombat(ai, target);
}
public static void attackBestTarget(obj_id ai, obj_id target) throws InterruptedException
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::attackBestTarget() ai(" + ai + ")");
startCombat(ai, target);
}
public static void equipRangedWeapon(obj_id ai) throws InterruptedException
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::equipRangedWeapon() ai(" + ai + ")");
aiEquipPrimaryWeapon(ai);
}
public static void equipMeleeWeapon(obj_id ai) throws InterruptedException
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::equipMeleeWeapon() ai(" + ai + ")");
aiEquipPrimaryWeapon(ai);
}
public static boolean goodFaction(obj_id npc, obj_id target) throws InterruptedException
{
PROFILER_START("goodFaction");
if (!pvpCanAttack(npc, target))
{
PROFILER_STOP("goodFaction");
return true;
}
if (isPlayer(target))
{
PROFILER_STOP("goodFaction");
return false;
}
else
{
String npcFaction = factions.getFaction(npc);
String targetFaction = factions.getFaction(target);
if (npcFaction != null && targetFaction != null)
{
if (npcFaction.equals(targetFaction))
{
PROFILER_STOP("goodFaction");
return true;
}
}
}
if (factions.getFactionReaction(npc, target) == factions.REACTION_POSITIVE)
{
PROFILER_STOP("goodFaction");
return true;
}
PROFILER_STOP("goodFaction");
return false;
}
public static boolean isGoodTarget(obj_id npc, obj_id target) throws InterruptedException
{
if (!isIdValid(target))
{
return false;
}
if (ai_lib.isAiDead(target))
{
if (isPlayer(target))
{
listenToMessage(target, "handleSawRecapacitation");
if (isObjectPersisted(npc))
{
dictionary parms = new dictionary();
parms.put("player", target);
messageTo(npc, "handleStopListening", parms, 1200, false);
}
}
return false;
}
if (!exists(target) || getDistance(npc, target) > combat_engine.getMaxCombatRange() || !isInWorld(target))
{
return false;
}
if (pet_lib.isPet(npc) && pet_lib.isMyPet(npc, target))
{
return false;
}
if (goodFaction(npc, target) || target == npc)
{
return false;
}
if (!isPlayer(target))
{
obj_id myCell = (getLocation(npc)).cell;
if (isIdValid(myCell))
{
obj_id defenderCell = (getLocation(target)).cell;
if (!isIdValid(defenderCell))
{
return false;
}
}
}
if (!pvpCanAttack(npc, target))
{
debugSpeakMsg(npc, "pvpCannotAttack");
return false;
}
return true;
}
public static void moveRandom(obj_id npc, obj_id target) throws InterruptedException
{
if (isIndoors(npc))
{
return;
}
obj_id weapon = getCurrentWeapon(npc);
int weaponType = getWeaponType(weapon);
int weaponCat = combat.getWeaponCategory(weaponType);
if (weaponCat != combat.RANGED_WEAPON)
{
PROFILER_STOP("moveRandom");
return;
}
int currentPosture = getPosture(npc);
if (currentPosture == POSTURE_KNOCKED_DOWN)
{
removeObjVar(npc, "ai.combat.moveMode");
PROFILER_STOP("moveRandom");
return;
}
else if (currentPosture != POSTURE_UPRIGHT)
{
stop(npc);
posture.stand(npc);
setObjVar(npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_PREPARING_TO_STAND);
PROFILER_STOP("moveRandom");
return;
}
location npcLoc = new location(getLocation(npc));
location targetLoc = getLocation(target);
if (targetLoc.x > npcLoc.x)
{
npcLoc.x -= rand(5, 15);
}
else
{
npcLoc.x += rand(5, 15);
}
if (targetLoc.z > npcLoc.z)
{
npcLoc.z -= rand(5, 15);
}
else
{
npcLoc.z += rand(5, 15);
}
setObjVar(npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_RANDOM);
messageTo(npc, "handleMoveRandomClear", null, 30, false);
PROFILER_START("pathTo");
pathTo(npc, npcLoc);
PROFILER_STOP("pathTo");
PROFILER_STOP("moveRandom");
}
public static void setCombatLocation(obj_id npc) throws InterruptedException
{
setObjVar(npc, "ai.combat.combatStartLoc", getLocation(npc));
}
public static location getCombatLocation(obj_id npc) throws InterruptedException
{
return getLocationObjVar(npc, "ai.combat.combatStartLoc");
}
public static boolean attackInCircleFormation(obj_id npc, obj_id target) throws InterruptedException
{
if (!hasObjVar(npc, "ai.inFormation") && (!hasObjVar(npc, "ai.combat.tempFormationCombat")))
{
return false;
}
if (hasObjVar(npc, "ai.combat.noRangedWeapon"))
{
return false;
}
obj_id weapon = getCurrentWeapon(npc);
int weaponType = getWeaponType(weapon);
int weaponCat = combat.getWeaponCategory(weaponType);
if (weaponCat != combat.RANGED_WEAPON)
{
if (getHateTarget(target) != npc)
{
}
}
weapon = getCurrentWeapon(npc);
float maxRange = getMaxRange(weapon) / 2.0f;
float offset = 20.0f;
if (maxRange < 20.0f)
{
offset = maxRange;
}
swarm(npc, target, offset);
setObjVar(npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_FOLLOW_FORMATION);
return true;
}
public static boolean hasRangedWeapon(obj_id npc) throws InterruptedException
{
obj_id weapon = getCurrentWeapon(npc);
int weaponType = getWeaponType(weapon);
int weaponCat = combat.getWeaponCategory(weaponType);
return (weaponCat == combat.RANGED_WEAPON);
}
public static void aiCombatFlee(obj_id npc, obj_id target, float minRange, float maxRange) throws InterruptedException
{
if (!isIdValid(npc) || !exists(npc))
{
return;
}
if (!isIdValid(target) || !exists(npc))
{
return;
}
location myLoc = new location(getLocation(npc));
if (myLoc == null)
{
return;
}
if (isIdValid(myLoc.cell))
{
return;
}
location destLoc = new location(myLoc);
location targetLoc = new location(getLocation(target));
if (targetLoc == null)
{
return;
}
if (targetLoc.x < destLoc.x)
{
destLoc.x += rand(minRange, maxRange);
}
else
{
destLoc.x -= rand(minRange, maxRange);
}
if (targetLoc.z < destLoc.z)
{
destLoc.z += rand(minRange, maxRange);
}
else
{
destLoc.z -= rand(minRange, maxRange);
}
pathTo(npc, destLoc);
}
public static boolean switchToFormationCombat(obj_id npc, obj_id target) throws InterruptedException
{
if (hasObjVar(npc, "ai.combat.tempFormationCombat"))
{
return true;
}
if (!isPlayer(target))
{
return false;
}
int combatRound = utils.getIntScriptVar(npc, "aiCombatRoundCounter");
if (combatRound < 5)
{
return false;
}
else if (combatRound > 10)
{
return false;
}
obj_id[] attackerList = getWhoIsTargetingMe(target);
if (attackerList == null || attackerList.length < 2)
{
return false;
}
int niche = ai_lib.aiGetNiche(npc);
if (niche != NICHE_DROID)
{
chat.setAngryMood(npc);
ai_lib.barkString(npc, "assist");
}
for (int i = 0; i < attackerList.length; i++)
{
if (!isPlayer(attackerList[i]))
{
removeObjVar(attackerList[i], "ai.combat.moveMode");
setObjVar(attackerList[i], "ai.combat.tempFormationCombat", i);
}
}
return true;
}
public static boolean doHealing(obj_id npc, obj_id target) throws InterruptedException
{
utils.setScriptVar(npc, "ai.nextHeal", (getGameTime() + 20));
obj_id[] myFriends = getWhoIsTargetingMe(target);
if (myFriends == null || myFriends.length == 0)
{
return false;
}
obj_id healTarget = getHealTarget(npc, myFriends);
if (!isIdValid(healTarget))
{
return false;
}
if (healTarget == npc)
{
executeHealingMove(npc, npc);
}
else if (getDistance(npc, healTarget) > 2.0f)
{
setObjVar(npc, "ai.combat.ignoreCombat", true);
utils.setScriptVar(npc, "ai.combat.pathingToHeal", healTarget);
follow(npc, healTarget, 1, 1.5f);
setObjVar(npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_MOVING_TO_HEAL);
}
return true;
}
public static obj_id getHealTarget(obj_id npc, obj_id[] myFriends) throws InterruptedException
{
for (int i = 0; i < myFriends.length; i++)
{
if (getDistance(npc, myFriends[i]) < 60.0f)
{
int healthDamage = getAttribDamage(myFriends[i], HEALTH);
if (healthDamage < (getMaxAttrib(myFriends[i], HEALTH) / 2))
{
healthDamage = 0;
}
int actionDamage = getAttribDamage(myFriends[i], ACTION);
if (actionDamage < (getMaxAttrib(myFriends[i], ACTION) / 2))
{
actionDamage = 0;
}
if (healthDamage != 0 || actionDamage != 0)
{
return myFriends[i];
}
}
}
return null;
}
public static void executeHealingMove(obj_id npc, obj_id target) throws InterruptedException
{
if (!isIdValid(npc) || ai_lib.aiIsDead(npc))
{
return;
}
if ((!isIdValid(target)) || ai_lib.aiIsDead(target))
{
removeObjVar(npc, "ai.combat.ignoreCombat");
utils.removeScriptVar(npc, "ai.combat.pathingToHeal");
stop(npc);
removeObjVar(npc, "ai.combat.moveMode");
return;
}
removeObjVar(npc, "ai.combat.moveMode");
stop(npc);
utils.removeScriptVar(npc, "ai.combat.pathingToHeal");
utils.setScriptVar(npc, "ai.nextHeal", (getGameTime() + 20));
if (ai_lib.aiIsDead(target) || ai_lib.aiIsDead(npc))
{
stop(npc);
removeObjVar(npc, "ai.combat.ignoreCombat");
utils.removeScriptVar(npc, "ai.combat.pathingToHeal");
return;
}
if (getDistance(npc, target) > 2.0f)
{
setObjVar(npc, "ai.combat.ignoreCombat", true);
utils.setScriptVar(npc, "ai.combat.pathingToHeal", target);
setObjVar(npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_MOVING_TO_HEAL);
follow(npc, target, 1, 2);
return;
}
removeObjVar(npc, "ai.combat.ignoreCombat");
if (target == npc)
{
doAnimationAction(npc, "heal_self");
}
else
{
doAnimationAction(npc, "heal_other");
}
location loc = getLocation(target);
obj_id[] players = getAllPlayers(loc, 45.0f);
if (players != null)
{
for (int i = 0; i < players.length; i++)
{
playClientEffectLoc(players[i], "clienteffect/healing_healdamage.cef", loc, 0);
}
}
int healthDamage = getAttribDamage(target, HEALTH);
int actionDamage = getAttribDamage(target, ACTION);
int healAmt = (ai_lib.getLevel(npc) * 20);
if (healAmt < healthDamage)
{
addToAttrib(target, HEALTH, healAmt);
}
else
{
setAttrib(target, HEALTH, getMaxAttrib(target, HEALTH));
}
if (healAmt < actionDamage)
{
addToAttrib(target, ACTION, healAmt);
}
else
{
setAttrib(target, ACTION, getMaxAttrib(target, ACTION));
}
utils.setScriptVar(npc, "ai.combat.movePause", 2);
}
public static boolean fleeFromHouse(obj_id npc, obj_id target) throws InterruptedException
{
if (!isIdValid(npc) || !isIdValid(target))
{
return false;
}
if (pet_lib.isPet(npc))
{
return false;
}
location myLoc = getLocation(npc);
if (myLoc == null)
{
return false;
}
location yourLoc = getLocation(target);
if (yourLoc == null)
{
return false;
}
obj_id myCell = myLoc.cell;
obj_id yourCell = yourLoc.cell;
if (isIdValid(myCell) == false && isIdValid(yourCell))
{
int niche = ai_lib.aiGetNiche(npc);
if (niche == NICHE_NPC || niche == NICHE_DROID || niche == NICHE_ANDROID)
{
if (permissionsIsAllowed(yourCell, npc))
{
return false;
}
}
pathTo(npc, aiGetHomeLocation(npc));
messageTo(npc, "redoYaw", null, 30, false);
setAttrib(npc, HEALTH, getUnmodifiedMaxAttrib(npc, HEALTH));
setAttrib(npc, ACTION, getUnmodifiedMaxAttrib(npc, ACTION));
if (isPlayer(target))
{
if (getHateTarget(target) == npc)
{
}
queueCommand(target, (1098448234), npc, "", COMMAND_PRIORITY_IMMEDIATE);
}
return true;
}
return false;
}
public static boolean doInteriorPathFinding(obj_id npc, obj_id target) throws InterruptedException
{
location npcLoc = getLocation(npc);
if (!isIdValid(npcLoc.cell))
{
return false;
}
return (getDistance(npc, target) > 6.0f);
}
public static boolean isIndoors(obj_id npc) throws InterruptedException
{
location npcLoc = getLocation(npc);
return (isIdValid(npcLoc.cell));
}
public static boolean isInCombat(obj_id ai) throws InterruptedException
{
boolean result = (getState(ai, STATE_COMBAT) == 1);
if (!result)
{
deltadictionary dict = ai.getScriptVars();
result = (dict.getObjVar("ai.combat.pendingCombat") != null);
}
return result;
}
}