Files
dsrc/sku.0/sys.server/compiled/game/script/library/advanced_turret.java
2021-03-08 19:09:53 -05:00

579 lines
21 KiB
Java
Executable File

package script.library;
import script.dictionary;
import script.location;
import script.obj_id;
import java.util.Vector;
public class advanced_turret extends script.base_script
{
public advanced_turret()
{
}
public static final String ALERT_VOLUME_NAME = "turretAggroVolume";
public static final float DEFAULT_TURRET_RANGE = 64.0f;
public static final float RANGE_TOO_CLOSE = 10.0f;
public static final String VAR_TURRET_BASE = "turret";
public static final String IS_ACTIVE = VAR_TURRET_BASE + ".isActive";
public static final String TARGETS = VAR_TURRET_BASE + ".targetList";
public static final String TURRET_FRIEND = VAR_TURRET_BASE + ".isFriend";
public static final String IS_ENGAGED = VAR_TURRET_BASE + ".isTrackingTarget";
public static final String IS_OUTDOORS = VAR_TURRET_BASE + ".isOutdoors";
public static final String FACTION = VAR_TURRET_BASE + ".faction";
public static final String RANGE = VAR_TURRET_BASE + ".range";
public static final String MY_WEAPON = VAR_TURRET_BASE + ".myWeapon";
public static final int TYPE_BLOCK = 1;
public static final int TYPE_DISH = 2;
public static final int TYPE_TOWER = 3;
public static final int SIZE_SMALL = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE = 3;
public static final int SIZE_MINI = 4;
public static obj_id createTurret(location loc, float yaw, int minDamage, int maxDamage, float attackSpeed, float range) throws InterruptedException
{
return createTurret(loc, yaw, TYPE_BLOCK, SIZE_SMALL, DAMAGE_ENERGY, minDamage, maxDamage, range, attackSpeed, "");
}
public static obj_id createTurret(location loc, float yaw, int type, int size, int damageType, int minDamage, int maxDamage, float range, float attackSpeed, String faction) throws InterruptedException
{
return createTurret(loc, yaw, TYPE_BLOCK, SIZE_SMALL, DAMAGE_ENERGY, minDamage, maxDamage, 10000, range, attackSpeed, "");
}
public static obj_id createTurret(location loc, float yaw, int type, int size, int damageType, int minDamage, int maxDamage, int hitpoints, float range, float attackSpeed, String faction) throws InterruptedException
{
return createTurret(null, loc, yaw, type, size, damageType, minDamage, maxDamage, hitpoints, range, attackSpeed, faction);
}
public static obj_id createTurret(obj_id owner, location loc, float yaw, int type, int size, int damageType, int minDamage, int maxDamage, int hitpoints, float range, float attackSpeed, String faction) throws InterruptedException
{
String template = "object/installation/turret/gcw/adv_turret";
switch (type)
{
case TYPE_BLOCK:
template += "_block";
break;
case TYPE_DISH:
template += "_dish";
break;
case TYPE_TOWER:
template += "_tower";
break;
}
switch (size)
{
case SIZE_MINI:
template += "_mini";
break;
case SIZE_SMALL:
template += "_sm";
break;
case SIZE_MEDIUM:
if (type == TYPE_DISH)
{
template += "_sm";
}
else
{
template += "_med";
}
break;
case SIZE_LARGE:
template += "_large";
break;
}
switch (damageType)
{
case DAMAGE_ELEMENTAL_HEAT:
template += "_heat";
break;
case DAMAGE_ELEMENTAL_COLD:
template += "_cold";
break;
case DAMAGE_ELEMENTAL_ACID:
template += "_acid";
break;
case DAMAGE_ELEMENTAL_ELECTRICAL:
template += "_electricity";
break;
case DAMAGE_KINETIC:
template += "_kinetic";
break;
default:
template += "_energy";
break;
}
template += ".iff";
obj_id turret = createObject(template, loc);
if (!isIdValid(turret))
{
return null;
}
setYaw(turret, yaw);
if (isIdValid(owner) && exists(owner))
{
setObjVar(turret, "turret_master", owner);
}
initTurret(turret, faction, damageType, range, minDamage, maxDamage, hitpoints, attackSpeed);
return turret;
}
public static void activateTurret(obj_id turret) throws InterruptedException
{
LOG("TURRET", "activateTurret " + turret);
if (!isIdValid(turret))
{
return;
}
obj_id turretWeapon = getTurretWeapon(turret);
if (!isIdValid(turretWeapon))
{
return;
}
utils.setScriptVar(turret, IS_ACTIVE, true);
setInvulnerable(turret, false);
pvpSetAttackableOverride(turret, true);
weapons.setWeaponData(turretWeapon);
float range = getFloatObjVar(turret, RANGE);
dictionary dict = new dictionary();
dict.put("range", range);
messageTo(turret, "createTriggerVolume", dict, 0.0f, false);
}
public static void deactivateTurret(obj_id turret) throws InterruptedException
{
LOG("TURRET", "deactivateTurret " + turret);
if (!isIdValid(turret))
{
return;
}
stopTrackingTarget(turret);
utils.removeScriptVar(turret, IS_ACTIVE);
setInvulnerable(turret, true);
}
public static boolean isActive(obj_id turret) throws InterruptedException
{
if (!isIdValid(turret))
{
return false;
}
if (utils.hasScriptVar(turret, IS_ACTIVE))
{
LOG("TURRET", "Turret " + turret + " is active.");
return true;
}
LOG("TURRET", "Turret " + turret + " is not active.");
return false;
}
public static void startTrackingTarget(obj_id turret, obj_id target) throws InterruptedException
{
LOG("TURRET", "Turret " + turret + " start tracking target " + target);
if (!isIdValid(turret) || !isIdValid(target))
{
return;
}
if (!isActive(turret))
{
LOG("TURRET", "Turret " + turret + " can't track target - turret inactive.");
return;
}
utils.setScriptVar(turret, IS_ENGAGED, target);
}
public static void stopTrackingTarget(obj_id turret) throws InterruptedException
{
LOG("TURRET", "Turret " + turret + " stop tracking target.");
if (!isIdValid(turret))
{
return;
}
utils.removeScriptVar(turret, IS_ENGAGED);
}
public static boolean isEngaged(obj_id turret) throws InterruptedException
{
if (!isIdValid(turret))
{
return false;
}
return utils.hasScriptVar(turret, IS_ENGAGED);
}
public static obj_id getCurrentTarget(obj_id turret) throws InterruptedException
{
if (!isEngaged(turret))
{
return null;
}
return utils.getObjIdScriptVar(turret, IS_ENGAGED);
}
public static obj_id getTurretWeapon(obj_id turret) throws InterruptedException
{
if (!isIdValid(turret) || !exists(turret))
{
return null;
}
if (!hasObjVar(turret, MY_WEAPON))
{
return null;
}
return getObjIdObjVar(turret, MY_WEAPON);
}
public static void initTurret(obj_id turret, String faction, int damageType, float range, int minDamage, int maxDamage, int hitpoints, float attackSpeed) throws InterruptedException
{
detachScript(turret, "systems.turret.turret_ai");
attachScript(turret, "systems.turret.advanced_turret_ai");
boolean isOutdoors = getTopMostContainer(turret) == turret;
setObjVar(turret, IS_OUTDOORS, isOutdoors);
setObjVar(turret, FACTION, faction.equals("") ? "renegade" : faction);
setObjVar(turret, RANGE, range == -1.0f ? DEFAULT_TURRET_RANGE : range);
factions.setFaction(turret, faction);
setMaxHitpoints(turret, hitpoints);
setHitpoints(turret, hitpoints);
setObjVar(turret, "pvpCanAttack", 1);
setInvulnerable(turret, false);
String weaponTemplate = "object/weapon/ranged/turret/turret_block_large.iff";
obj_id objWeapon = createObject(weaponTemplate, turret, "");
if (!isIdValid(objWeapon))
{
explodeTurret(turret, turret);
return;
}
setObjVar(turret, MY_WEAPON, objWeapon);
setWeaponAttackSpeed(objWeapon, Math.max(attackSpeed, 1.0f));
int primaryType = DAMAGE_ENERGY;
int secondaryType = DAMAGE_ELEMENTAL_HEAT;
int primaryMinDamage = 0;
int primaryMaxDamage = 0;
int secondaryDamage = 0;
switch (damageType)
{
case DAMAGE_ELEMENTAL_COLD:
case DAMAGE_ELEMENTAL_ACID:
case DAMAGE_ELEMENTAL_ELECTRICAL:
case DAMAGE_ELEMENTAL_HEAT:
primaryType = DAMAGE_ENERGY;
secondaryType = damageType;
primaryMinDamage = 1;
primaryMaxDamage = 1;
secondaryDamage = (int)(minDamage + maxDamage / 2.0f);
break;
case DAMAGE_KINETIC:
case DAMAGE_ENERGY:
primaryType = damageType;
secondaryType = DAMAGE_ELEMENTAL_HEAT;
primaryMinDamage = minDamage;
primaryMaxDamage = maxDamage;
secondaryDamage = 0;
break;
}
setWeaponDamageType(objWeapon, primaryType);
setWeaponElementalType(objWeapon, secondaryType);
setWeaponMinDamage(objWeapon, minDamage);
setWeaponMaxDamage(objWeapon, maxDamage);
setWeaponElementalValue(objWeapon, secondaryDamage);
range_info ri = new range_info();
ri.maxRange = range;
setWeaponRangeInfo(objWeapon, ri);
activateTurret(turret);
}
public static boolean isValidTarget(obj_id turret, obj_id target) throws InterruptedException
{
if (!isIdValid(turret) || !isIdValid(target) || !exists(turret) || !exists(target))
{
doLogging("isValidTarget", "I or " + target + " is not valid or does not exist: " + isIdValid(turret) + "/" + isIdValid(target) + "/" + exists(turret) + "/" + exists(target));
return false;
}
if (vehicle.isVehicle(target))
{
doLogging("isValidTarget", "Target " + getName(target) + " is a vehicle");
return false;
}
if (stealth.hasInvisibleBuff(target))
{
doLogging("isValidTarget", "Target " + getName(target) + " has a stealth buff");
return false;
}
if (target == turret)
{
doLogging("isValidTarget", "I'm attempting to attack myself");
return false;
}
float range = hasObjVar(turret, RANGE) ? getFloatObjVar(turret, RANGE) : DEFAULT_TURRET_RANGE;
float dist = getDistance(target, turret);
if (dist > range + 1)
{
doLogging("isValidTarget", "Target out of range. dist: " + dist + " range: " + range);
return false;
}
if (utils.hasScriptVar(target, TURRET_FRIEND))
{
doLogging("isValidTarget", "Target is a friend.");
return false;
}
if (isDead(target) || isIncapacitated(target))
{
doLogging("isValidTarget", "Target is dead or incapped");
return false;
}
if (hasScript(turret, "systems.gcw.gcw_turret") && hasScript(target, "ai.smuggler_spawn_enemy"))
{
return false;
}
if (ai_lib.isAnimal(target) && hasScript(turret, "systems.gcw.gcw_turret"))
{
return false;
}
if (isMob(target) && isIdValid(getMaster(target)))
{
obj_id cd = callable.getCallableCD(target);
if (callable.getControlDeviceType(cd) == callable.CALLABLE_TYPE_FAMILIAR)
{
return false;
}
}
obj_id master = getObjIdObjVar(turret, "turret_master");
if (isIdValid(master) && exists(master) && !pvpCanAttack(master, target))
{
return false;
}
String turretFaction = hasObjVar(turret, FACTION) ? getStringObjVar(turret, FACTION) : getBaseFaction(turret);
if (!turretFaction.equals("renegade"))
{
obj_id pvpTarget = target;
if (isMob(target) && !isPlayer(target) && isIdValid(getMaster(target)))
{
pvpTarget = getMaster(target);
}
if (!pvpCanAttack(turret, pvpTarget))
{
doLogging("isValidTarget", "Our factions are not opposed: Self/Target: " + factions.getFaction(turret) + "/" + factions.getFaction(target));
return false;
}
}
return true;
}
public static String getBaseFaction(obj_id turret) throws InterruptedException
{
obj_id parentBase = getObjIdObjVar(turret, "hq.defense.parent");
if (!isIdValid(parentBase))
{
return "renegade";
}
return getStringObjVar(parentBase, "faction");
}
public static void addTarget(obj_id turret, obj_id target) throws InterruptedException
{
if (!isValidTarget(turret, target))
{
doLogging("addTarget", getName(target) + "/" + target + " was invalid");
return;
}
Vector targets = null;
if (!utils.hasScriptVar(turret, TARGETS))
{
targets = new Vector();
}
else
{
targets = utils.getResizeableObjIdBatchScriptVar(turret, TARGETS);
}
if (targets != null && targets.indexOf(target) == -1)
{
targets.add(target);
}
if (targets.size() > 0)
{
utils.setBatchScriptVar(turret, TARGETS, targets);
if (!isEngaged(turret))
{
attackPulse(turret);
}
}
}
public static void addTargets(obj_id turret, obj_id[] newTargets) throws InterruptedException
{
Vector targets = null;
if (!utils.hasScriptVar(turret, TARGETS))
{
targets = new Vector();
}
else
{
targets = utils.getResizeableObjIdBatchScriptVar(turret, TARGETS);
}
for (obj_id newTarget : newTargets) {
if (!isValidTarget(turret, newTarget) || targets.indexOf(newTarget) != -1) {
doLogging("addTargets", getName(newTarget) + "/" + newTarget + " was invalid or already in my target array");
continue;
}
targets.add(newTarget);
}
if (targets.size() > 0)
{
utils.setBatchScriptVar(turret, TARGETS, targets);
if (!isEngaged(turret))
{
messageTo(turret, "handleTurretAttack", null, 1, false);
}
}
}
public static void removeTarget(obj_id turret, obj_id target) throws InterruptedException
{
if (!isIdValid(turret) || !isIdValid(target))
{
doLogging("removeTarget", "Removed " + target);
return;
}
if (!utils.hasScriptVar(turret, TARGETS))
{
return;
}
Vector targets = utils.getResizeableObjIdBatchScriptVar(turret, TARGETS);
obj_id engageTarget = utils.getObjIdScriptVar(turret, IS_ENGAGED);
int idx = targets.indexOf(target);
if (idx > -1)
{
if (isIdValid(engageTarget) && target == engageTarget)
{
stopTrackingTarget(turret);
}
targets.remove(idx);
if (targets.size() == 0)
{
utils.removeBatchScriptVar(turret, TARGETS);
}
else
{
utils.setBatchScriptVar(turret, TARGETS, targets);
}
}
}
public static boolean handleTurretDamage(obj_id turret, obj_id attacker, obj_id weapon, int dmgAmount) throws InterruptedException
{
if (!validateAttacker(turret, attacker))
{
doLogging("handleTurretDamage", getName(attacker) + "/" + attacker + " was not a valid attacker.");
return false;
}
int curHP = getHitpoints(turret);
if (curHP < 1)
{
explodeTurret(turret, attacker);
return true;
}
addTarget(turret, attacker);
if (!utils.hasScriptVar(turret, "playingEffect"))
{
int smolder = 2000;
int fire = 1000;
if (curHP < smolder)
{
location death = getLocation(turret);
utils.setScriptVar(turret, "playingEffect", 1);
String effect = "";
if (curHP < fire)
{
effect = "clienteffect/lair_hvy_damage_fire.cef";
}
else
{
effect = "clienteffect/lair_med_damage_smoke.cef";
}
playClientEffectLoc(attacker, effect, death, 0);
messageTo(turret, "effectManager", null, 15, true);
}
}
return true;
}
public static boolean validateAttacker(obj_id turret, obj_id attacker) throws InterruptedException
{
obj_id master = getObjIdObjVar(turret, "turret_master");
if (isIdValid(master) && exists(master) && !pvpCanAttack(master, attacker))
{
return false;
}
return pvpIsEnemy(turret, attacker);
}
public static void explodeTurret(obj_id turret, obj_id killer) throws InterruptedException
{
location death = getLocation(turret);
deactivateTurret(turret);
playClientEffectLoc(turret, "clienteffect/combat_explosion_lair_large.cef", death, 0);
messageTo(turret, "handleDestroyTurret", null, 2, false);
}
public static obj_id getGoodTurretTarget(obj_id turret) throws InterruptedException
{
obj_id target = getCurrentTarget(turret);
if (!isValidTarget(turret, target) || isIncapacitated(target) || isDead(target) || !canSee(turret, target))
{
if (isIncapacitated(target) && !isDead(target))
{
pclib.coupDeGrace(target, turret, false);
}
target = null;
}
else
{
return target;
}
if (!utils.hasScriptVar(turret, TARGETS))
{
return null;
}
Vector targets = utils.getResizeableObjIdBatchScriptVar(turret, TARGETS);
if ((targets == null) || (targets.size() == 0))
{
doLogging("getGoodTurretTarget", "I had no target batchvar so I am returning null");
return null;
}
target = null;
while (!isIdValid(target))
{
if (targets.size() < 1)
{
break;
}
target = (obj_id)targets.get(rand(0, targets.size() - 1));
if (!isValidTarget(turret, target) || isDead(target) || isIncapacitated(target) || !canSee(turret, target) || vehicle.isVehicle(target) || stealth.hasInvisibleBuff(target))
{
targets.removeElement(target);
target = null;
continue;
}
}
if (targets.size() < 1)
{
stopTrackingTarget(turret);
utils.removeBatchScriptVar(turret, TARGETS);
}
else
{
utils.setBatchScriptVar(turret, TARGETS, targets);
}
return target;
}
public static void attackPulse(obj_id turret) throws InterruptedException
{
if (!isActive(turret))
{
return;
}
obj_id target = getGoodTurretTarget(turret);
if (!isIdValid(target))
{
stopTrackingTarget(turret);
return;
}
startTrackingTarget(turret, target);
executeAttackAction(turret, target);
}
public static void executeAttackAction(obj_id turret, obj_id target) throws InterruptedException
{
obj_id weapon = getTurretWeapon(turret);
if (!isIdValid(weapon))
{
stopTrackingTarget(turret);
}
dictionary params = new dictionary();
params.put("target", target);
messageTo(turret, "turretShot", params, getWeaponAttackSpeed(weapon), false);
}
public static void doLogging(String section, String message) throws InterruptedException
{
LOG("doLogging/advanced_turret.scriptlib/" + section, message);
}
}