who isn't sick of converting the freaking scripts? this negates the need

This commit is contained in:
DarthArgus
2015-11-24 09:27:45 -06:00
parent 2e64106bc8
commit bbee2d328c
11077 changed files with 2604347 additions and 3425075 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,259 @@
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;
}
}
@@ -1,273 +0,0 @@
include library.ai_lib;
include library.colors;
include library.pet_lib;
include library.stealth;
include library.storyteller;
include library.utils;
const int AGGRO_STATUS_NOT_VALID = 0;
const int AGGRO_STATUS_WAITING = 1;
const int AGGRO_STATUS_READY = 2;
const float AGGRO_RADIUS_INTERIOR_VERTICAL = 3.0f;
void requestAggroCheck(obj_id target)
{
const obj_id self = getSelf();
if (!isAttemptingAggroCheck(target))
{
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_aggro::requestAggroCheck(YES) self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ")");
const 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");
// Not interested in this target anymore
}
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");
//showFlyText(self, new string_id("npc_reaction/flytext", "alert"), 2.0f, colors.ORANGERED);
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) + ")");
}
}
void stopAttemptingAggroCheck(obj_id target)
{
const 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);
}
boolean isAttemptingAggroCheck(obj_id target)
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getBoolean("ai.aggrocheck." + target);
}
int getAggroStatus(obj_id target)
{
int result = AGGRO_STATUS_NOT_VALID;
const 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);
// In interiors, vertical aggro radius is capped at 3m (minimum door height).
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)
{
const float respectRadius = aiGetRespectRadius(self, target);
const 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;
}
@@ -0,0 +1,512 @@
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.chat;
import script.library.colors;
import script.library.combat;
import script.library.combat_consts;
import script.library.dot;
import script.library.factions;
import script.library.group;
import script.library.locations;
import script.library.pet_lib;
import script.library.pet_lib;
import script.library.posture;
import script.library.scout;
import script.library.utils;
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;
}
}
@@ -1,588 +0,0 @@
include library.ai_lib;
include library.chat;
include library.colors;
include library.combat;
include library.combat_consts;
include library.dot;
include library.factions;
include library.group;
include library.locations;
include library.pet_lib;
include library.pet_lib;
include library.posture;
include library.scout;
include library.utils;
// @TODO: Remove me
void doAttack(obj_id ai, obj_id target)
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::doAttack() ai(" + ai + ")");
startCombat(ai, target);
}
// @TODO: Remove me
void attackBestTarget(obj_id ai, obj_id target)
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::attackBestTarget() ai(" + ai + ")");
startCombat(ai, target);
}
// @TODO: Remove me
void equipRangedWeapon(obj_id ai)
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::equipRangedWeapon() ai(" + ai + ")");
aiEquipPrimaryWeapon(ai);
}
// @TODO: Remove me
void equipMeleeWeapon(obj_id ai)
{
LOGC(aiLoggingEnabled(ai), "debug_ai", "ai_combat::equipMeleeWeapon() ai(" + ai + ")");
aiEquipPrimaryWeapon(ai);
}
boolean goodFaction( obj_id npc, obj_id target )
{
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;
}
boolean isGoodTarget( obj_id npc, obj_id target )
{
if ( !isIdValid(target) )
{
return false;
}
if ( ai_lib.isAiDead( target ) )
{
//if this is a player, we want to know if/when he recapacitates:
if ( isPlayer( target ) )
{
listenToMessage(target, "handleSawRecapacitation");
//but if I am a persisted object, I'll quit listening after a bit:
if ( isObjectPersisted(npc) )
{
dictionary parms = new dictionary();
parms.put( "player", target );
messageTo( npc, "handleStopListening", parms, 1200, false );
}
}
//debugSpeakMsg( npc, "too far to shoot");
return false;
}
if ( !exists( target ) || getDistance( npc, target ) > combat_engine.getMaxCombatRange() || !isInWorld( target ) )
{
//debugSpeakMsg( npc, "too far to shoot");
return false;
}
if ( pet_lib.isPet(npc) && pet_lib.isMyPet( npc, target ))
{
return false;
}
if ( goodFaction( npc, target ) || target == npc )
{
//debugSpeakMsg( npc, "same faction");
return false;
}
//I'm inside, he's outside, NPCs can't follow each other properly
if ( !isPlayer(target) )
{
obj_id myCell = ( getLocation(npc)).cell;
if ( isIdValid(myCell))
{
obj_id defenderCell = ( getLocation(target) ).cell;
if ( !isIdValid(defenderCell))
{
//debugSpeakMsg( npc, "i am inside and he is outside" );
return false;
}
}
}
if ( !pvpCanAttack(npc,target))
{
debugSpeakMsg( npc, "pvpCannotAttack");
return false;
}
return true;
}
void moveRandom( obj_id npc, obj_id target )
{
if ( isIndoors( npc ))
return;//never do this indoors
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 )
{
//debugSpeakMsg( npc, "stopping to stand so I can move randomly" );
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");
}
//void aiThrowGrenade( obj_id npc, obj_id target )
//{
// int niche = ai_lib.aiGetNiche( npc );
// if ( niche != NICHE_NPC )
// {
// removeObjVar( npc, "ai.grenade" );
// removeObjVar( npc, "ai.grenadeType" );
// return;
// }
// obj_id grenade = getObjIdObjVar( npc, "ai.grenade" );
// if ( grenade == null )
// {
// removeObjVar( npc, "ai.grenade" );
// removeObjVar( npc, "ai.grenadeType" );
// return;
// }
// string parms = grenade.toString();
// queueCommand(npc, ##"throwGrenade", target , parms, COMMAND_PRIORITY_FRONT);
//}
void setCombatLocation( obj_id npc )
{
setObjVar( npc, "ai.combat.combatStartLoc", getLocation( npc ));
}
location getCombatLocation( obj_id npc )
{
return getLocationObjVar( npc, "ai.combat.combatStartLoc");
}
boolean attackInCircleFormation( obj_id npc, obj_id target )
{
//debugSpeakMsg( npc, "1" );
//if ( isRooted( npc ) )
//{
// //debugSpeakMsg( npc, "i am rooted" );
// return false;
//}
//debugSpeakMsg( npc, "2" );
if (!hasObjVar( npc, "ai.inFormation") && ( !hasObjVar( npc, "ai.combat.tempFormationCombat" )))
{
//debugSpeakMsg( npc, "i am not in a formation" );
return false;
}
/*
4 1 5
2 x 0
6 3 7
*/
//debugSpeakMsg( npc, "3" );
if (hasObjVar( npc, "ai.combat.noRangedWeapon"))
{
//debugSpeakMsg( npc, "i have no ranged weapon" );
return false;
}
//debugSpeakMsg( npc, "4" );
//if you're in Melee combat but your opponent is not targetting you
// then equip a ranged weapon and get back in formation:
obj_id weapon = getCurrentWeapon( npc );
int weaponType = getWeaponType( weapon);
int weaponCat = combat.getWeaponCategory( weaponType );
if ( weaponCat != combat.RANGED_WEAPON )
{
if ( getHateTarget( target ) != npc )
{
//debugSpeakMsg( npc, "xx: 100" );
//unequipWeapon( npc );
}
}
weapon = getCurrentWeapon( npc );
float maxRange = getMaxRange( weapon )/2.0f;
float offset = 20.0f;
if ( maxRange < 20.0f )
offset = maxRange;
//debugSpeakMsg( npc, "best distance is " + offset );
swarm(npc, target, offset);
setObjVar( npc, "ai.combat.moveMode", ai_combat_movement.MOVEMODE_FOLLOW_FORMATION );
//debugSpeakMsg( npc, "i am now in formation!" );
return true;
}
boolean hasRangedWeapon( obj_id npc )
{
obj_id weapon = getCurrentWeapon( npc );
int weaponType = getWeaponType( weapon);
int weaponCat = combat.getWeaponCategory( weaponType );
return ( weaponCat == combat.RANGED_WEAPON );
}
void aiCombatFlee( obj_id npc, obj_id target, float minRange, float maxRange )
{
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 );
}
boolean switchToFormationCombat( obj_id npc, obj_id target )
{
if ( hasObjVar( npc, "ai.combat.tempFormationCombat" ))
return true;
if ( !isPlayer( target ) )
return false;//NPCs really suck when they try this on each other
int combatRound = utils.getIntScriptVar( npc, "aiCombatRoundCounter" );
if ( combatRound < 5 )
{
//debugSpeakMsg( npc, "waiting..." );
return false;//don't make this check for at least 5 rounds:
}
else if ( combatRound > 10 )
{
//debugSpeakMsg( npc, "not checking any more" );
return false;//stop checking after 10 rounds
}
// Decide whether to switch:
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" );//droid slang variants dont have this
}
for ( int i = 0; i < attackerList.length; i++ )
{
//flag them all, including me!
if ( !isPlayer( attackerList[i] ) )
{
removeObjVar( attackerList[i], "ai.combat.moveMode" );
setObjVar( attackerList[i], "ai.combat.tempFormationCombat", i );
}
}
return true;
}
boolean doHealing( obj_id npc, obj_id target )
{
utils.setScriptVar( npc, "ai.nextHeal", (getGameTime()+20) );
//obj_id yourTarget = getHateTarget( target );
//if ( yourTarget == npc )
// return false;// I'm busy being shot
obj_id[] myFriends = getWhoIsTargetingMe( target );
if ( myFriends == null || myFriends.length == 0 )
return false;// There's no way this could possible happen
//choose someone to heal:
obj_id healTarget = getHealTarget( npc, myFriends );
if ( !isIdValid( healTarget ))
return false;
if ( healTarget == npc )
{
//debugSpeakMsg( npc, "i heal myself!");
executeHealingMove( npc, npc );
}
else if ( getDistance( npc, healTarget ) > 2.0f )
{
//debugSpeakMsg( npc, "i heal " + getName(healTarget));
//debugSpeakMsg( npc, "not close enough, so I follow healTarget" );
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;
}
obj_id getHealTarget( obj_id npc, obj_id[] myFriends )
{
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];//you're wounded so I'll heal you
}
}
}
return null;//found no one to heal
}
void executeHealingMove( obj_id npc, obj_id target )
{
if (!isIdValid(npc) || ai_lib.aiIsDead(npc))
return;
if ( (!isIdValid( target )) || ai_lib.aiIsDead(target) )
{
//debugSpeakMsg( npc, "stopping because healing target is gone" );
removeObjVar( npc, "ai.combat.ignoreCombat" );
utils.removeScriptVar( npc, "ai.combat.pathingToHeal" );
stop(npc);
removeObjVar( npc, "ai.combat.moveMode" );
return;
}
//debugSpeakMsg( npc, "stopping to execute healing move" );
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) )
{
//debugSpeakMsg( npc, "stopping because healing target is dead" );
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;
}
//debugSpeakMsg( npc, "healing " + getName( target ) );
removeObjVar( npc, "ai.combat.ignoreCombat" );
if ( target == npc )
{
doAnimationAction( npc, "heal_self" );
}
else
{
//faceTo(npc,target);
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 );
}
boolean fleeFromHouse( obj_id npc, obj_id target )
{
if ( !isIdValid(npc) || !isIdValid( target ) )
return false;
if ( pet_lib.isPet(npc) )
return false;//pets don't do this
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 ) )
{
//debugSpeakMsg( npc, "I am outside and you are inside" );
int niche = ai_lib.aiGetNiche( npc );
if ( niche == NICHE_NPC || niche == NICHE_DROID || niche == NICHE_ANDROID)
{
if (permissionsIsAllowed(yourCell, npc))
return false;//npcs and droids will follow into the building, if they can
}
//ai_combat.fleeFromCombat( npc, target );
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, ##"peace", npc, "", COMMAND_PRIORITY_IMMEDIATE);
}
return true;
}
return false;
}
boolean doInteriorPathFinding( obj_id npc, obj_id target )
{
location npcLoc = getLocation( npc );
if (!isIdValid( npcLoc.cell ))
return false;//outdoors, so do the normal shit
return ( getDistance( npc, target ) > 6.0f );//too far away to trust the
// can-see check, so
}
boolean isIndoors( obj_id npc )
{
location npcLoc = getLocation( npc );
return (isIdValid( npcLoc.cell ));
}
boolean isInCombat(obj_id ai)
{
boolean result = (getState(ai, STATE_COMBAT) == 1);
if (!result)
{
deltadictionary dict = ai.getScriptVars();
result = (dict.getObjVar("ai.combat.pendingCombat") != null);
}
return result;
}
@@ -0,0 +1,148 @@
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.beast_lib;
import script.library.colors;
import script.library.factions;
public class ai_combat_assist extends script.base_script
{
public ai_combat_assist()
{
}
public static void clearAssist() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
dict.remove("ai.combat.assist");
}
public static void clearNoAssistCall() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
dict.remove("ai.combat.assist.noAssistCall");
}
public static boolean isWaiting() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getBoolean("ai.combat.assist");
}
public static int getWaitTime() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getInt("ai.combat.assist.waitTime");
}
public static void assist(obj_id defender, obj_id target) throws InterruptedException
{
}
public static boolean canCallForAssist() throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return !dict.getBoolean("ai.combat.assist.noAssistCall");
}
public static boolean callForAssist() throws InterruptedException
{
obj_id self = getSelf();
if (beast_lib.isBeast(self))
{
return false;
}
if (hasObjVar(self, "hologram_performer"))
{
return false;
}
obj_id target = getTarget(self);
if (!isIdValid(target) || !exists(target))
{
return false;
}
String type = getStringObjVar(self, "creature_type");
dictionary aiData = dataTableGetRow("datatables/mob/creatures.iff", type);
float assistRange = aiData.getFloat("assist");
String socialGroup = aiData.getString("socialGroup");
String pvpFaction = aiData.getString("pvpFaction");
if (assistRange == 0.0f)
{
return false;
}
obj_id[] creatures = getNPCsInRange(self, assistRange);
if (creatures == null || creatures.length == 0)
{
return false;
}
Vector callToList = new Vector();
callToList.setSize(0);
for (int i = 0; i < creatures.length; i++)
{
if (creatures[i] == self)
{
continue;
}
if (!isIdValid(creatures[i]) || !exists(creatures[i]))
{
continue;
}
if (isInvulnerable(creatures[i]))
{
continue;
}
if (isPlayer(target) && factions.ignorePlayer(target, creatures[i]))
{
continue;
}
if (isDead(creatures[i]))
{
continue;
}
if (isIdValid(getMaster(creatures[i])))
{
continue;
}
if (!canSee(self, creatures[i]))
{
continue;
}
if (!factions.shareSocialGroup(self, creatures[i]) && !factions.areCreaturesAllied(self, creatures[i]))
{
continue;
}
if (Math.abs(getLocation(self).y - getLocation(creatures[i]).y) > 6.0f)
{
continue;
}
callToList.add(creatures[i]);
}
if (callToList == null || callToList.size() == 0)
{
return false;
}
for (int q = 0; q < callToList.size(); q++)
{
startAssistedCombat(((obj_id)callToList.get(q)), target);
}
return true;
}
public static void startAssistedCombat(obj_id creature, obj_id target) throws InterruptedException
{
deltadictionary dict = creature.getScriptVars();
if (!ai_lib.isInCombat(creature))
{
faceTo(creature, target);
dict.put("ai.combat.assist.waitTime", isPlayer(target) ? rand(1.0f, 2.0f) : rand(3.0f, 4.0f));
dict.put("ai.combat.assist", true);
dict.put("ai.combat.assist.noAssistCall", true);
}
startCombat(creature, target);
}
}
@@ -1,158 +0,0 @@
include library.ai_lib;
include library.beast_lib;
include library.colors;
include library.factions;
void clearAssist()
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
dict.remove("ai.combat.assist");
}
void clearNoAssistCall()
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
dict.remove("ai.combat.assist.noAssistCall");
}
boolean isWaiting()
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getBoolean("ai.combat.assist");
}
int getWaitTime()
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getInt("ai.combat.assist.waitTime");
}
// This code would fire based on the observer and seemed to ignore line of sight checks. It is disabled
// in favor of the defender calling for help explicitly (below in callForAssist).
void assist(obj_id defender, obj_id target)
{
/**
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
if (!ai_lib.isInCombat(self))
{
//showFlyText(self, new string_id("npc_reaction/flytext", "alert"), 2.0f, colors.ORANGERED);
faceTo(self, target);
dict.put("ai.combat.assist.waitTime", isPlayer(defender) ? rand(1.0f, 2.0f) : rand(3.0f, 4.0f));
dict.put("ai.combat.assist", true);
dict.put("ai.combat.assist.noAssistCall", true);
}
startCombat(self, target);
**/
}
boolean canCallForAssist()
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return !dict.getBoolean("ai.combat.assist.noAssistCall");
}
boolean callForAssist()
{
obj_id self = getSelf();
//we dont want beasts asking for help
if(beast_lib.isBeast(self))
return false;
//we dont want decoys or holograms asking for help
if(hasObjVar(self, "hologram_performer"))
return false;
obj_id target = getTarget(self);
if (!isIdValid(target) || !exists(target))
return false;
string type = getStringObjVar(self, "creature_type");
dictionary aiData = dataTableGetRow("datatables/mob/creatures.iff", type);
float assistRange = aiData.getFloat("assist");
string socialGroup = aiData.getString("socialGroup");
string pvpFaction = aiData.getString("pvpFaction");
if (assistRange == 0.0f)
return false;
obj_id[] creatures = getNPCsInRange(self, assistRange);
if (creatures == null || creatures.length == 0)
return false;
resizeable obj_id[] callToList = new obj_id[0];
for (int i=0;i<creatures.length;i++)
{
if (creatures[i] == self)
continue;
if (!isIdValid(creatures[i]) || !exists(creatures[i]))
continue;
if (isInvulnerable(creatures[i]))
continue;
if (isPlayer(target) && factions.ignorePlayer(target, creatures[i]))
continue;
if (isDead(creatures[i]))
continue;
if (isIdValid(getMaster(creatures[i])))
continue;
if (!canSee(self, creatures[i]))
continue;
if (!factions.shareSocialGroup(self, creatures[i]) && !factions.areCreaturesAllied(self, creatures[i]))
continue;
if (Math.abs(getLocation(self).y - getLocation(creatures[i]).y) > 6.0f)
continue;
callToList.add(creatures[i]);
}
if (callToList == null || callToList.length == 0)
return false;
for (int q=0;q<callToList.length;q++)
{
startAssistedCombat(callToList[q], target);
}
return true;
}
void startAssistedCombat(obj_id creature, obj_id target)
{
deltadictionary dict = creature.getScriptVars();
if (!ai_lib.isInCombat(creature))
{
faceTo(creature, target);
dict.put("ai.combat.assist.waitTime", isPlayer(target) ? rand(1.0f, 2.0f) : rand(3.0f, 4.0f));
dict.put("ai.combat.assist", true);
dict.put("ai.combat.assist.noAssistCall", true);
}
startCombat(creature, target);
}
@@ -0,0 +1,44 @@
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.utils;
public class ai_combat_damage extends script.base_script
{
public ai_combat_damage()
{
}
public static void addAttack(obj_id attacker) throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
final int attackCount = dict.getInt("ai.combat.attack_count." + attacker);
dict.put("ai.combat.attack_count." + attacker, attackCount + 1);
dict.put("ai.combat.last_attack_time." + attacker, getGameTime());
}
public static int getTimeSinceLastAttack(obj_id attacker) throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return getGameTime() - dict.getInt("ai.combat.last_attack_time." + attacker);
}
public static int getAttackCount(obj_id attacker) throws InterruptedException
{
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getInt("ai.combat.attack_count." + attacker);
}
public static void clearAttackerList() throws InterruptedException
{
final obj_id self = getSelf();
utils.removeScriptVarTree(self, "ai.combat.attack_count");
utils.removeScriptVarTree(self, "ai.combat.last_attack_time");
}
}
@@ -1,35 +0,0 @@
include library.utils;
void addAttack(obj_id attacker)
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
const int attackCount = dict.getInt("ai.combat.attack_count." + attacker);
dict.put("ai.combat.attack_count." + attacker, attackCount + 1);
dict.put("ai.combat.last_attack_time." + attacker, getGameTime());
}
int getTimeSinceLastAttack(obj_id attacker)
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return getGameTime() - dict.getInt("ai.combat.last_attack_time." + attacker);
}
int getAttackCount(obj_id attacker)
{
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
return dict.getInt("ai.combat.attack_count." + attacker);
}
void clearAttackerList()
{
const obj_id self = getSelf();
utils.removeScriptVarTree(self, "ai.combat.attack_count");
utils.removeScriptVarTree(self, "ai.combat.last_attack_time");
}
@@ -0,0 +1,347 @@
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.instance;
import script.library.utils;
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;
}
}
@@ -1,504 +0,0 @@
include library.instance;
include library.utils;
const int MOVEMODE_INVALID = 0;
const int MOVEMODE_FOLLOW = 1;
const int MOVEMODE_RANDOM = 2;
const int MOVEMODE_PREPARING_TO_MOVE = 3;
const int MOVEMODE_PATHING_HOME = 4;
const int MOVEMODE_PREPARING_TO_STAND = 5;
const int MOVEMODE_MOVING_TO_HEAL = 7;
const int MOVEMODE_IDLE = 9;
const int MOVEMODE_FLEE = 10;
const int MOVEMODE_FOLLOW_FORMATION = 11;
const int MOVEMODE_MOVING_TO_SEE = 12;
const int MOVEMODE_MOVING_TO_DEATHBLOW = 13;
const int MOVEMODE_SWARM = 14;
const int MOVEMOVE_EVADE = 15;
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_INVALID
//
/////////////////////////////////////////////////////////////////////////
void aiClearMoveMode()
{
const obj_id self = getSelf();
//debugSpeakMsg(self, "Clear Movement.");
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_INVALID);
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_IDLE
//
/////////////////////////////////////////////////////////////////////////
void aiIdle()
{
if (aiIsIdle())
{
return;
}
const obj_id self = getSelf();
// stop whatever the ai was doing
// NOTE: Currently only doing this for patrols. suspendMovement() will work for all movement types, but there
// may need to be extra code (setting/clearing scriptvars, for instance) written that I'm not aware of. SAJ
if ( aiGetMovementState(self) == MOVEMENT_PATROL && !hasSuspendedMovement(self) )
{
suspendMovement(self);
}
deltadictionary dict = self.getScriptVars();
dict.put("ai.combat.moveMode", MOVEMODE_IDLE);
stop(self);
}
boolean aiIsIdle()
{
const obj_id self = getSelf();
const deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_IDLE);
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_MOVING_TO_SEE
//
/////////////////////////////////////////////////////////////////////////
void aiMoveToSee(obj_id target)
{
if (aiIsMovingToSee(target))
{
return;
}
const obj_id self = getSelf();
// stop whatever the ai was doing (see aiIdle() above)
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));
}
boolean aiIsMovingToSee(obj_id target)
{
if(aiIsMovingToSee() && aiGetMoveToSeeTarget() == target)
{
return true;
}
return false;
}
boolean aiIsMovingToSee()
{
const obj_id self = getSelf();
const deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_MOVING_TO_SEE);
}
obj_id aiGetMoveToSeeTarget()
{
const obj_id self = getSelf();
const deltadictionary dict = self.getScriptVars();
return dict.getObjId("ai.combat.moveToSee.target");
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_MOVING_TO_DEATHBLOW
//
/////////////////////////////////////////////////////////////////////////
void aiMoveToDeathBlow(obj_id target)
{
if ( aiIsMovingToDeathBlow(target)
|| !isIncapacitated(target))
{
return;
}
const obj_id self = getSelf();
// stop whatever the ai was doing (see aiIdle() above)
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));
}
boolean aiIsMovingToDeathBlow(obj_id target)
{
if ( (aiIsMovingToDeathBlow())
&& (aiGetMoveToDeathBlowTarget() == target))
{
return true;
}
return false;
}
boolean aiIsMovingToDeathBlow()
{
const obj_id self = getSelf();
const deltadictionary dict = self.getScriptVars();
return (dict.getInt("ai.combat.moveMode") == MOVEMODE_MOVING_TO_DEATHBLOW);
}
obj_id aiGetMoveToDeathBlowTarget()
{
const obj_id self = getSelf();
const deltadictionary dict = self.getScriptVars();
return dict.getObjId("ai.combat.moveToDeathBlow.target");
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_FOLLOW
//
/////////////////////////////////////////////////////////////////////////
void aiFollow(obj_id target, float minDistance, float maxDistance)
{
if (aiIsFollowing(target, minDistance, maxDistance))
{
return;
}
const obj_id self = getSelf();
// stop whatever the ai was doing (see aiIdle() above)
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);
}
void aiSwarm(obj_id target, float minDistance, float maxDistance)
{
if (aiIsSwarming(target, minDistance, maxDistance))
return;
const obj_id self = getSelf();
// stop whatever the ai was doing (see aiIdle() above)
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 );
}
boolean aiIsFollowing(obj_id target, float minDistance, float maxDistance)
{
const obj_id self = getSelf();
const 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;
}
boolean aiIsSwarming(obj_id target, float minDistance, float maxDistance)
{
const obj_id self = getSelf();
const 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;
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_EVADE
//
/////////////////////////////////////////////////////////////////////////
float getActualEvadeChance(obj_id ai, float min, float max)
{
float rslt = max;
float difference = max - min;
float maxHealth = (float)getMaxHealth(ai);
float curHealth = (float)getHealth(ai);
rslt -= (difference * (curHealth / maxHealth));
return rslt;
}
//
// Runs the AI to some location around the target, given the distances
// @chance is a number between 1 and 0. if >=1 is passed in, the ai
// will attempt an evasion attempt 100% of the time (not recommended as
// it will make AI run around like Benny Hill during combat since the
// movement code (including this function) is triggered by the server
// every frame (up to 4 times a second)
//
boolean aiEvade(obj_id target, obj_id ai, range_info aiWeaponRanges, float minChance, float maxChance)
{
obj_id primaryWeapon = aiGetPrimaryWeapon(ai);
obj_id secondaryWeapon = aiGetSecondaryWeapon(ai);
float primaryRange = 0;
float secondaryRange = 0;
obj_id master = getMaster(ai);
// Pets do not evade.
if(isIdValid(master))
{
return false;
}
// Am I in a heroic instance? Do not evade!
if(hasScript(ai, "systems.dungeon_sequencer.ai_controller"))
{
return false;
}
if(isIdValid(primaryWeapon) && exists(primaryWeapon))
{
const range_info primaryWeaponRange = aiGetWeaponRangeInfo(primaryWeapon);
primaryRange = primaryWeaponRange.maxRange;
}
if(isIdValid(secondaryWeapon) && exists(secondaryWeapon))
{
const range_info secondaryWeaponRange = aiGetWeaponRangeInfo(secondaryWeapon);
secondaryRange = secondaryWeaponRange.maxRange;
}
if(primaryRange <= 10f && secondaryRange <= 10f)
{
return false; // Melee doesn't evade.
}
const int now = getGameTime();
const int then = utils.getIntScriptVar(ai, "aiIsEvading");
if(then != 0 && (now - then) < 15)
{
return false;
}
float minDistance = 0; // min distance to run away
float maxDistance = 1f; // max distance to run away
if(getTopMostContainer(ai) == ai) // outside with a gun
{
minDistance = 15f;
maxDistance = 20f;
}
else // inside with a gun
{
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; // when fighting a player with a melee weapon, less chance to evade, even if player is too close
}
else
{
mod = 0.9f;
}
minDistance = 5f;
if(rand(1, 100) < 30) // n% chance to run out of player's range
{
maxDistance = playerRange.maxRange + 5;
}
else
{
maxDistance = playerRange.maxRange - 1;
}
if(minDistance > maxDistance)
{
minDistance = maxDistance;
}
}
maxChance -= (maxChance * mod);
if(minChance > maxChance)
{
minChance = maxChance;
}
//debugSpeakMsg(ai, "MinEvade=" + minChance + " MaxEvade=" + maxChance);
}
float chance = getActualEvadeChance(ai, minChance, maxChance);
if(chance < 1f && rand(0.0f, 1.0f) > chance)
{
return false;
}
// Get valid away location gets a location from current location to a radius of minDistance to maxDistance.
// If the location can not be seen by the target, then it returns null.
// The away location is not away from the target. It is a random circular location from its current location.
location evasionTargetLoc = getValidAwayLocation(target, minDistance, maxDistance);
if(evasionTargetLoc == null || getLocation(ai).cell != evasionTargetLoc.cell)
{
return false;
}
// If the ai cannot see the location, then return false. The target has already checked its visibility.
if(!canSee(ai, evasionTargetLoc))
{
return false;
}
utils.setScriptVar(ai, "aiIsEvading", getGameTime());
pathTo(ai, evasionTargetLoc);
faceTo(ai, target);
return true;
}
//
// this function will fail frequently (return null), but its designed to be called potentially every
// frame; so frames where failures are returned are just discarded
//
location getValidAwayLocation(obj_id mob, float minDistance, float maxDistance)
{
location from = getLocation(mob);
//debugSpeakMsg(mob, "" + minDistance + "/" + maxDistance);
location evasionTarget = utils.getRandomAwayLocation(from, minDistance, maxDistance);
evasionTarget.y += 0.5f; // have to do this because canSee will fail due to ground geometry collision otherwise
if(!canSee(mob, evasionTarget))
{
//playClientEffectLoc(target, "appearance/" + "pt_fireworks_01.prt", evasionTarget, 0.0f);
//debugSpeakMsg(mob, "Can't see evasion target. Not Evading");
return null;
}
evasionTarget.y -= 0.5f;
return evasionTarget;
}
/////////////////////////////////////////////////////////////////////////
//
// MOVEMODE_FLEE
//
/////////////////////////////////////////////////////////////////////////
void aiFlee(obj_id target, float distance)
{
if (aiIsFleeing(target, distance))
{
return;
}
const obj_id self = getSelf();
// stop whatever the ai was doing (see aiIdle() above)
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);
}
boolean aiIsFleeing(obj_id ai)
{
const deltadictionary dict = ai.getScriptVars();
return dict.getInt("ai.combat.moveMode") == MOVEMODE_FLEE;
}
boolean aiIsFleeing(obj_id target, float distance)
{
const obj_id self = getSelf();
const 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;
}
//Additional Move Modes
boolean isAiImmobile(obj_id subject)
{
return hasObjVar(subject, "isImmobile") ? getBooleanObjVar(subject, "isImmobile") : false;
}
@@ -0,0 +1,101 @@
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.buff;
import script.library.pet_lib;
import script.library.target_dummy;
import script.library.utils;
public class ai_combat_target extends script.base_script
{
public ai_combat_target()
{
}
public static void clearTargetList() throws InterruptedException
{
final obj_id self = getSelf();
utils.removeScriptVarTree(self, "ai.combat.targetSocialGroup.verified");
}
public static boolean isValidTarget(obj_id target) throws InterruptedException
{
if (!isIdValid(target))
{
return false;
}
boolean result = true;
final obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
final String targetSocialGroupVerified = "ai.combat.targetSocialGroup.verified." + target;
if (!pvpCanAttack(self, target))
{
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") CAN'T ATTACK THIS TARGET");
result = false;
}
else if (isGameObjectTypeOf(getTopMostContainer(target), GOT_building_player) && !target_dummy.isTargetDummy(target))
{
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") NOT ALLOWED IN STRUCTURE");
result = false;
}
else if (dict.getBoolean(targetSocialGroupVerified) == false)
{
final String selfSocialGroup = ai_lib.getSocialGroup(self);
if (selfSocialGroup != null && ai_lib.isMob(target))
{
if (!isIdValid(getMaster(self)) && !isIdValid(getMaster(target)) && selfSocialGroup.equals(ai_lib.getSocialGroup(target)))
{
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") SAME SOCIAL GROUP");
result = false;
}
else
{
dict.put(targetSocialGroupVerified, true);
}
}
}
String evasionObjVarName = "me_evasion." + target;
if (utils.hasScriptVar(self, evasionObjVarName) && buff.hasBuff(target, "me_evasion_1"))
{
obj_id[] thoseWhoHateMe = getHateList(self);
if (thoseWhoHateMe.length < 2)
{
return true;
}
return false;
}
if (hasObjVar(target, "ai.combat.limitAttackers") && !isPlayer(target) && !pet_lib.hasMaster(target))
{
int attackers = getIntObjVar(target, "ai.combat.limitAttackers");
obj_id[] haters = getHateList(target);
if (haters.length >= attackers)
{
int npcCount = 0;
for (int i = 0, j = haters.length; i < j; i++)
{
if (isIdValid(haters[i]) && !isPlayer(haters[i]) && !pet_lib.hasMaster(haters[i]))
{
npcCount++;
}
if (npcCount > attackers)
{
stopCombat(self);
clearHateList(self);
return false;
}
if (isIdValid(haters[i]) && haters[i] == self)
{
return true;
}
}
}
}
return result;
}
}
@@ -1,118 +0,0 @@
include library.ai_lib;
include library.buff;
include library.pet_lib;
include library.target_dummy;
include library.utils;
//-----------------------------------------------------------------------
void clearTargetList()
{
const obj_id self = getSelf();
utils.removeScriptVarTree(self, "ai.combat.targetSocialGroup.verified");
}
//-----------------------------------------------------------------------
boolean isValidTarget(obj_id target)
{
if(!isIdValid(target))
{
return false;
}
boolean result = true;
const obj_id self = getSelf();
deltadictionary dict = self.getScriptVars();
const String targetSocialGroupVerified = "ai.combat.targetSocialGroup.verified." + target;
if (!pvpCanAttack(self, target))
{
// Can't attack this target
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") CAN'T ATTACK THIS TARGET");
result = false;
}
else if ( isGameObjectTypeOf(getTopMostContainer(target), GOT_building_player) && !target_dummy.isTargetDummy(target) )
{
// AI not allowed in this structure
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") NOT ALLOWED IN STRUCTURE");
result = false;
}
else if (dict.getBoolean(targetSocialGroupVerified) == false)
{
const String selfSocialGroup = ai_lib.getSocialGroup(self);
if (selfSocialGroup != null && ai_lib.isMob(target))
{
if (!isIdValid(getMaster(self)) && !isIdValid(getMaster(target)) && selfSocialGroup.equals(ai_lib.getSocialGroup(target)))
{
// They are in the same social group
LOGC(aiLoggingEnabled(self), "debug_ai", "ai_combat_target::isValidTarget() self(" + self + ":" + getName(self) + ") target(" + target + ":" + getName(target) + ") SAME SOCIAL GROUP");
result = false;
}
else
{
// They are not in the same social group
dict.put(targetSocialGroupVerified, true);
}
}
}
string evasionObjVarName = "me_evasion." + target;
if(utils.hasScriptVar(self, evasionObjVarName) && buff.hasBuff(target, "me_evasion_1"))
{
obj_id[] thoseWhoHateMe = getHateList(self);
// Nobody else on my hate list but you, buddy.
if(thoseWhoHateMe.length < 2)
{
// debugSpeakMsg(self, "Valid Target: " + target + " is in evasion mode.");
return true;
}
// debugSpeakMsg(self, "Invalid Target: " + target + " is in evasion mode.");
return false;
}
if(hasObjVar(target, "ai.combat.limitAttackers") && !isPlayer(target) && !pet_lib.hasMaster(target))
{
int attackers = getIntObjVar(target, "ai.combat.limitAttackers");
obj_id[] haters = getHateList(target);
if(haters.length >= attackers)
{
int npcCount = 0;
for(int i = 0, j = haters.length; i < j; i++)
{
// Count how many NPC's are in combat with this target.
if(isIdValid(haters[i]) && !isPlayer(haters[i]) && !pet_lib.hasMaster(haters[i]))
{
npcCount++;
}
// If there are more NPC attackers than the limit, this is a bad target.
if(npcCount > attackers)
{
stopCombat(self);
clearHateList(self);
return false;
}
// If the target has me already in its list before the limit is reached, this is a valid target.
if(isIdValid(haters[i]) && haters[i] == self)
{
return true;
}
}
}
}
return result;
}
@@ -0,0 +1,212 @@
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.create;
import script.library.ai_lib;
public class ai_debug extends script.base_script
{
public ai_debug()
{
}
public int OnCreatureDamaged(obj_id self, obj_id attacker, obj_id weapon, int[] damage) throws InterruptedException
{
healShockWound(self, getShockWound(self));
setAttrib(self, HEALTH, getMaxAttrib(self, HEALTH));
return SCRIPT_CONTINUE;
}
public int OnSpeaking(obj_id self, String text) throws InterruptedException
{
LOG("debug_ai", "OnSpeaking: " + text);
if (isGod(self))
{
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(text);
if (tokenizer.hasMoreTokens())
{
String command = tokenizer.nextToken();
LOG("debug_ai", "command is: " + command + " ---------------------------------------");
if (command.equalsIgnoreCase("invulnerable"))
{
final obj_id target = getLookAtTarget(self);
if (target != null)
{
setInvulnerable(target, !isInvulnerable(target));
LOG("debug_ai", "target(" + target + ") invulnerable(" + (isInvulnerable(target) ? "yes" : "no") + ")");
}
}
else if (command.equalsIgnoreCase("forceAction"))
{
final obj_id target = getLookAtTarget(self);
if (target != null)
{
setObjVar(target, "ai.combat.forcedAction", "powerAttack");
}
}
else if (command.equalsIgnoreCase("tuskenline"))
{
for (int i = 0; i < 5; ++i)
{
location spawnLocation = getLocation(self);
if ((i % 1) == 0)
{
spawnLocation.x += 3.0f * i;
}
else
{
spawnLocation.x += -3.0f * i;
}
final obj_id ai = create.object("tusken_warrior", spawnLocation);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
}
else if (command.equalsIgnoreCase("tusken"))
{
location spawnLocation = getLocation(self);
LOG("debug_ai", "tusken created @ (" + spawnLocation.x + ", " + spawnLocation.y + ", " + spawnLocation.z + ")");
final obj_id ai = create.object("tusken_warrior", spawnLocation);
}
else if (command.equalsIgnoreCase("stormtrooper"))
{
final location spawnLocation = getLocation(self);
final obj_id ai = create.createCreature("stormtrooper", spawnLocation, true);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
else if (command.equalsIgnoreCase("attackMe"))
{
final obj_id target = getLookAtTarget(self);
if (isValidId(target))
{
startCombat(target, self);
}
else
{
debugSpeakMsg(self, "Specify a target");
}
}
else if (command.equalsIgnoreCase("jedifight"))
{
location here = getLocation(self);
here.z = here.z + 2;
obj_id jedi = create.object("light_jedi_sentinel", here);
here.x = here.x + 2;
obj_id sith = create.object("dark_jedi_knight", here);
startCombat(jedi, sith);
}
else if (command.equalsIgnoreCase("gangfight"))
{
{
for (int i = 0; i < 20; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("tusken_berserker", spawnLocation);
}
}
{
for (int i = 0; i < 10; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("arachne_warrior", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("group_tusken"))
{
{
for (int i = 0; i < 6; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("tusken_berserker", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("group_stormtrooper"))
{
{
for (int i = 0; i < 20; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-10, 10);
spawnLocation.z += rand(-10, 10);
create.object("stormtrooper", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("trigger"))
{
location spawnLocation = getLocation(self);
final obj_id ai = create.createCreature("blurrg_hunter", spawnLocation, true);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
else if (command.equalsIgnoreCase("loiterLocation"))
{
final obj_id target = getLookAtTarget(self);
if (target != null)
{
ai_lib.setDefaultCalmBehavior(target, ai_lib.BEHAVIOR_LOITER);
}
debugConsoleMsg(self, "DONE");
}
else if (command.equalsIgnoreCase("heal"))
{
final obj_id lookAtTarget = getLookAtTarget(self);
final obj_id healTarget = !isIdValid(lookAtTarget) ? self : lookAtTarget;
int maxHealth = 0;
if (isMob(healTarget))
{
maxHealth = getMaxHealth(healTarget);
setHealth(healTarget, maxHealth);
}
else
{
maxHealth = getMaxHitpoints(healTarget);
setHitpoints(healTarget, maxHealth);
}
LOG("debug_ai", "healTarget(" + healTarget + ":" + getName(healTarget) + ") maxHealth(" + maxHealth + ")");
LOG("debug_ai", "lookAtTarget(" + lookAtTarget + ":" + getName(lookAtTarget) + ")");
}
else if (command.equalsIgnoreCase("patrol"))
{
final location anchorLocation = getLocation(self);
final obj_id leader = create.object("stormtrooper", anchorLocation);
final float radius = 20.0f;
final int points = 10;
location path[] = new location[points];
for (int i = 0; i < points; ++i)
{
path[i] = new location();
final float radian = (float)Math.PI * 2.0f * ((float)i / (float)points);
path[i].x = anchorLocation.x + (float)Math.sin(radian) * radius;
path[i].y = anchorLocation.y;
path[i].z = anchorLocation.z + (float)Math.cos(radian) * radius;
}
ai_lib.setPatrolPath(leader, path);
ai_lib.resumePatrol(leader);
final int squadSize = 7;
for (int i = 1; i <= squadSize; ++i)
{
final obj_id follower = create.object("stormtrooper", anchorLocation);
ai_lib.followInFormation(follower, leader, ai_lib.FORMATION_WEDGE, i);
}
}
}
}
return SCRIPT_CONTINUE;
}
}
@@ -1,224 +0,0 @@
include library.create;
include library.ai_lib;
trigger OnCreatureDamaged(obj_id attacker, obj_id weapon, int[] damage)
{
healShockWound(self, getShockWound(self) );
setAttrib(self, HEALTH, getMaxAttrib( self, HEALTH));
return SCRIPT_CONTINUE;
}
trigger OnSpeaking(String text)
{
LOG("debug_ai", "OnSpeaking: " + text);
if (isGod(self))
{
java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(text);
if (tokenizer.hasMoreTokens())
{
String command = tokenizer.nextToken();
LOG("debug_ai", "command is: " + command + " ---------------------------------------");
if (command.equalsIgnoreCase("invulnerable"))
{
const obj_id target = getLookAtTarget(self);
if (target != null)
{
setInvulnerable(target, !isInvulnerable(target));
LOG("debug_ai", "target(" + target + ") invulnerable(" + (isInvulnerable(target) ? "yes" : "no") + ")");
}
}
else if (command.equalsIgnoreCase("forceAction"))
{
const obj_id target = getLookAtTarget(self);
if (target != null)
{
setObjVar(target, "ai.combat.forcedAction", "powerAttack");
}
}
else if (command.equalsIgnoreCase("tuskenline"))
{
for (int i = 0; i < 5; ++i)
{
location spawnLocation = getLocation(self);
if ((i % 1) == 0)
{
spawnLocation.x += 3.0f * i;
}
else
{
spawnLocation.x += -3.0f * i;
}
const obj_id ai = create.object("tusken_warrior", spawnLocation);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
}
else if (command.equalsIgnoreCase("tusken"))
{
location spawnLocation = getLocation(self);
LOG("debug_ai", "tusken created @ (" + spawnLocation.x + ", " + spawnLocation.y + ", " + spawnLocation.z + ")");
const obj_id ai = create.object("tusken_warrior", spawnLocation);
//ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
else if (command.equalsIgnoreCase("stormtrooper"))
{
const location spawnLocation = getLocation(self);
const obj_id ai = create.createCreature("stormtrooper", spawnLocation, true);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
else if (command.equalsIgnoreCase("attackMe"))
{
const obj_id target = getLookAtTarget(self);
if (isValidId(target))
{
startCombat(target, self);
}
else
{
debugSpeakMsg(self, "Specify a target");
}
}
else if (command.equalsIgnoreCase("jedifight"))
{
location here = getLocation(self);
here.z = here.z + 2;
obj_id jedi = create.object("light_jedi_sentinel", here);
here.x = here.x + 2;
obj_id sith = create.object("dark_jedi_knight", here);
startCombat(jedi, sith);
}
else if (command.equalsIgnoreCase("gangfight"))
{
{
for (int i = 0; i < 20; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("tusken_berserker", spawnLocation);
}
}
{
for (int i = 0; i < 10; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("arachne_warrior", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("group_tusken"))
{
{
for (int i = 0; i < 6; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-20, 20);
spawnLocation.z += rand(-20, 20);
create.object("tusken_berserker", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("group_stormtrooper"))
{
{
for (int i = 0; i < 20; ++i)
{
location spawnLocation = getLocation(self);
spawnLocation.x += rand(-10, 10);
spawnLocation.z += rand(-10, 10);
create.object("stormtrooper", spawnLocation);
}
}
}
else if (command.equalsIgnoreCase("trigger"))
{
location spawnLocation = getLocation(self);
const obj_id ai = create.createCreature("blurrg_hunter", spawnLocation, true);
ai_lib.setDefaultCalmBehavior(ai, ai_lib.BEHAVIOR_SENTINEL);
}
else if (command.equalsIgnoreCase("loiterLocation"))
{
const obj_id target = getLookAtTarget(self);
if (target != null)
{
ai_lib.setDefaultCalmBehavior(target, ai_lib.BEHAVIOR_LOITER);
}
debugConsoleMsg(self, "DONE");
}
else if (command.equalsIgnoreCase("heal"))
{
const obj_id lookAtTarget = getLookAtTarget(self);
const obj_id healTarget = !isIdValid(lookAtTarget) ? self : lookAtTarget;
int maxHealth = 0;
if (isMob(healTarget))
{
maxHealth = getMaxHealth(healTarget);
setHealth(healTarget, maxHealth);
}
else
{
maxHealth = getMaxHitpoints(healTarget);
setHitpoints(healTarget, maxHealth);
}
LOG("debug_ai", "healTarget(" + healTarget + ":" + getName(healTarget) + ") maxHealth(" + maxHealth + ")");
LOG("debug_ai", "lookAtTarget(" + lookAtTarget + ":" + getName(lookAtTarget) + ")");
}
else if (command.equalsIgnoreCase("patrol"))
{
const location anchorLocation = getLocation(self);
const obj_id leader = create.object("stormtrooper", anchorLocation);
const float radius = 20.0f;
const int points = 10;
location path[] = new location[points];
for (int i = 0; i < points; ++i)
{
path[i] = new location();
const float radian = (float)Math.PI * 2.0f * ((float)i / (float)points);
path[i].x = anchorLocation.x + (float)Math.sin(radian) * radius;
path[i].y = anchorLocation.y;
path[i].z = anchorLocation.z + (float)Math.cos(radian) * radius;
}
ai_lib.setPatrolPath(leader, path);
ai_lib.resumePatrol(leader);
const int squadSize = 7;
for (int i = 1; i <= squadSize; ++i)
{
const obj_id follower = create.object("stormtrooper", anchorLocation);
ai_lib.followInFormation(follower, leader, ai_lib.FORMATION_WEDGE, i);
}
}
}
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,272 @@
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.factions;
import script.ai.ai_combat;
public class ai_template extends script.base_script
{
public ai_template()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public static final String ACTION_ALERT = "alert";
public static final String ACTION_THREATEN = "threaten";
public static final float CORPSE_CLEANUP_DELAY = 30.0f;
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "handleSetupNPC", null, 5, isObjectPersisted(self));
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int handleSetupNPC(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, "ai.setupComplete"))
{
messageTo(self, "handleSetupNPC", null, 5, isObjectPersisted(self));
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int resumeDefaultCalmBehavior(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "ai.conversing"))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnMovePathComplete(obj_id self) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnMovePathNotFound(obj_id self) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (breacher == self || ai_lib.isAiDead(breacher))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ALERT_VOLUME_NAME))
{
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (volumeName.equals(ALERT_VOLUME_NAME))
{
}
return SCRIPT_CONTINUE;
}
public int OnLoiterWaiting(obj_id self, modifiable_float time) throws InterruptedException
{
int herding = dataTableGetInt("datatables/ai/species.iff", ai_lib.aiGetSpecies(self), "Herd");
if (herding != 1)
{
}
return SCRIPT_CONTINUE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (newBehavior <= oldBehavior)
{
if (doCalmerBehavior(self, newBehavior, oldBehavior) == SCRIPT_CONTINUE)
{
return SCRIPT_CONTINUE;
}
else
{
return SCRIPT_OVERRIDE;
}
}
else
{
if (doAgitatedBehavior(self, newBehavior, oldBehavior) == SCRIPT_CONTINUE)
{
return SCRIPT_CONTINUE;
}
else
{
return SCRIPT_OVERRIDE;
}
}
}
public int doCalmerBehavior(obj_id npc, int newBehavior, int oldBehavior) throws InterruptedException
{
switch (newBehavior)
{
case BEHAVIOR_CALM:
break;
case BEHAVIOR_ALERT:
break;
case BEHAVIOR_THREATEN:
break;
case BEHAVIOR_FLEE:
break;
case BEHAVIOR_PANIC:
break;
case BEHAVIOR_ATTACK:
break;
case BEHAVIOR_FRENZY:
break;
default:
break;
}
return SCRIPT_CONTINUE;
}
public int doAgitatedBehavior(obj_id npc, int newBehavior, int oldBehavior) throws InterruptedException
{
switch (newBehavior)
{
case BEHAVIOR_CALM:
break;
case BEHAVIOR_ALERT:
break;
case BEHAVIOR_THREATEN:
break;
case BEHAVIOR_FLEE:
break;
case BEHAVIOR_PANIC:
break;
case BEHAVIOR_ATTACK:
break;
case BEHAVIOR_FRENZY:
break;
default:
break;
}
return SCRIPT_CONTINUE;
}
public int OnEnteredCombat(obj_id self) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int OnDefenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int lairThreatened(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (!hasObjVar(self, "poi.baseObject"))
{
return SCRIPT_CONTINUE;
}
obj_id myLair = getObjIdObjVar(self, "poi.baseObject");
obj_id lair = params.getObjId("lairId");
if (lair == null || lair == obj_id.NULL_ID)
{
return SCRIPT_CONTINUE;
}
if (lair == myLair)
{
}
return SCRIPT_CONTINUE;
}
public int OnIncapacitated(obj_id self, obj_id attacker) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int corpseCleanup(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int OnStartNpcConversation(obj_id self, obj_id speaker) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(speaker))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnNpcConversationResponse(obj_id self, String convo, obj_id player, string_id response) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int OnEndNpcConversation(obj_id self, obj_id speaker) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int OnFleeTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnFleePathNotFound(obj_id self, obj_id oldTarget) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnFollowTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnFollowPathNotFound(obj_id self, obj_id target) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
}
@@ -1,414 +0,0 @@
include library.ai_lib;
include library.factions;
include ai.ai_combat;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
const float CORPSE_CLEANUP_DELAY = 30.0f;
trigger OnAttach()
{
// To ensure that you don't do anything with the NPC until he has been
// instantiated and setup, use a callback:
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageTo( self, "handleSetupNPC", null, 5, isObjectPersisted( self ) );
//mever do anything here.
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
//mever do anything here.
return SCRIPT_CONTINUE;
}
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageHandler handleSetupNPC()
{
//if setup isn't complete yet, then wait 5 seconds and try again:
if ( !hasObjVar( self, "ai.setupComplete" ))
{
//CHANGE THE NAME OF THIS HANDLER TO ONE SPECIFIC TO THIS AI SCRIPT!
messageTo( self, "handleSetupNPC", null, 5, isObjectPersisted( self ) );
return SCRIPT_CONTINUE;
}
/* -----------------9/11/2002 11:30AM----------------
* Your setup code goes here.
* --------------------------------------------------*/
return SCRIPT_CONTINUE;
}
messageHandler resumeDefaultCalmBehavior()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
if ( hasObjVar( self, "ai.conversing") )
{
//the npc is conversing. Want to do something special?
// return SCRIPT_OVERRIDE;
// otherwise
return SCRIPT_CONTINUE;
}
//if you don't want a calm NPC to resume his default calm behavior,
// then
//
// YOUR CODE GOES HERE
//
// return SCRIPT_OVERRIDE;
// else
return SCRIPT_CONTINUE;
}
trigger OnMovePathComplete()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
return SCRIPT_CONTINUE;
}
trigger OnMovePathNotFound()
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
// return SCRIPT_OVERRIDE; if you do NOT want the NPC to
// resume patrolling (if he was patrolling) or to
// resume his default behavior (if he's calm)
// otherwise:
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
//ignore gm's
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
//ignore yourself and dead things
if ( breacher == self || ai_lib.isAiDead( breacher ) )
return SCRIPT_CONTINUE;
if ( volumeName == ALERT_VOLUME_NAME )
{
//the alert trigger has been breached! Wand to prevent default
// reactions from taking place?
// return SCRIPT_OVERRIDE;
// otherwise:
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
if ( volumeName == ALERT_VOLUME_NAME )
{
//want to prevent herding behaviors and the like?
// if you return SCRIPT_OVERRIDE here, make sure
// to call this function first!
//ignoreCreatureMovement(self, breacher);
// return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
trigger OnLoiterWaiting(modifiable_float time)
{
int herding = dataTableGetInt("datatables/ai/species.iff", ai_lib.aiGetSpecies( self ), "Herd");
if ( herding != 1 )
{
//you can do anything you want to here, and
// return SCRIPT_OVERRIDE;
}
//you can do anything you want to here,
// but if you return SCRIPT_OVERRIDE then
// herding animals won't herd!
// Unless you also call:
// ai_lib.maintainHerding( self );
// return SCRIPT_OVERRIDE;
return SCRIPT_CONTINUE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( ai_lib.isAiDead( self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;//you probably don't want to do anything if you are in combat
//don't put code in this trigger. Put it in doCalmerBehavior or doAgitated behavior
// this is hard enough to read already:
if ( newBehavior <= oldBehavior )
{
if ( doCalmerBehavior( self, newBehavior, oldBehavior ) == SCRIPT_CONTINUE)
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
else
{
if ( doAgitatedBehavior( self, newBehavior, oldBehavior) == SCRIPT_CONTINUE )
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
}
int doCalmerBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are now calming down.
// return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//going from More Agitated to Calm
// Your code goes here.
break;
case BEHAVIOR_ALERT:
//going from More Agitated to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from More Agitated to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from More Agitated to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//going from More Agitated to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from More Agitated to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//This is impossible.
break;
default :
// This is an error
break;
}
return SCRIPT_CONTINUE;
}
int doAgitatedBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are becoming more Fearful or more Angry
// return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//this is impossible
break;
case BEHAVIOR_ALERT:
//going from Calmer to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from Calmer to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from Calmer to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//Going from Calmer to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from Calmer to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//going from Calmer to Frenzy
break;
default :
// This is an error
break;
}
return SCRIPT_CONTINUE;
}
/* -----------------8/1/2002 9:42PM------------------
* COMBAT:
* --------------------------------------------------*/
trigger OnEnteredCombat()
{
//you probably dont want to do anything here
return SCRIPT_CONTINUE;
}
trigger OnDefenderCombatAction( obj_id attacker, obj_id weapon, int combatResult )
{
//bet you shouldn't do anything here, either.
return SCRIPT_CONTINUE;
}
messageHandler lairThreatened()
{
if ( ai_lib.isAiDead( self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self) )
return SCRIPT_CONTINUE;
if ( !hasObjVar( self, "poi.baseObject" ))
return SCRIPT_CONTINUE;
obj_id myLair = getObjIdObjVar( self, "poi.baseObject" );
obj_id lair = params.getObjId( "lairId" );
if ( lair == null || lair == obj_id.NULL_ID )
return SCRIPT_CONTINUE;
if ( lair == myLair )
{
//your code goes here.
// return SCRIPT_OVERRIDE;
// to stomp default behavior.
}
return SCRIPT_CONTINUE;
}
//--------------- DEATH -----------------------//
trigger OnIncapacitated( obj_id attacker )
{
//you probably don't ever want to use
// return SCRIPT_OVERRIDE here
// if you do, it'll prevent the body from
// decaying (Ever!), etc.
return SCRIPT_CONTINUE;
}
messageHandler corpseCleanup()
{
//want to do something special when the corpse
// is deleted? Better hurry!
// If you
// return SCRIPT_OVERRIDE
// then you'd better
//destroyObject( self );
// or the corpse will never go away.
return SCRIPT_CONTINUE;
}
//---------------DEATH -----------------------//
trigger OnStartNpcConversation (obj_id speaker)
{
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( speaker ) )
return SCRIPT_CONTINUE;
//if you return SCRIPT_OVERRIDE in this trigger,
// then do all this stuff FIRST!
/*
ai_lib.setMood( self, ai_lib.MOOD_CALM );
stop( self );
faceTo( self, speaker );
setObjVar( self, "ai.conversing", false );
messageTo( self, "handleAbortConversation", null, 30, true );
*/
return SCRIPT_CONTINUE;
}
trigger OnNpcConversationResponse(string convo, obj_id player, string_id response)
{
//if you return SCRIPT_OVERRIDE from this trigger, then do
// this stuff FIRST!
/*
if ( hasObjVar( self, "ai.conversing" ) )
setObjVar( self, "ai.conversing", true);
*/
return SCRIPT_CONTINUE;
}
trigger OnEndNpcConversation(obj_id speaker )
{
//if you return SCRIPT_OVERRIDE from this trigger, then do
// this stuff FIRST!
/*
removeObjVar( self, "ai.conversing");
if ( getBehavior(self) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
*/
return SCRIPT_CONTINUE;
}
trigger OnFleeTargetLost(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//if you don't want the NPC to resume default calm behavior (if calm)
//return SCRIPT_OVERRIDE;
//else:
return SCRIPT_CONTINUE;
}
trigger OnFleePathNotFound(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//if you don't want the NPC to resume default calm behavior (if calm)
//return SCRIPT_OVERRIDE;
//else:
return SCRIPT_CONTINUE;
}
trigger OnFollowTargetLost(obj_id oldTarget)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//note: if the npc is not in combat, and you fail
// to return SCRIPT_CONTINUE -and- you don't call
// ai_lib.stopFollowing(), then this NPC will
// think he's following someone, but won't be moving!
// That's BAD.
return SCRIPT_CONTINUE;
}
trigger OnFollowPathNotFound(obj_id target)
{
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;//you probably don't want to do anything if the creature is in combat
//note: if the npc is not in combat, and you fail
// to return SCRIPT_CONTINUE -and- you don't call
// ai_lib.stopFollowing(), then this NPC will
// think he's following someone, but won't be moving!
// That's BAD.
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,55 @@
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.chat;
public class bark_string_on_initialize extends script.base_script
{
public bark_string_on_initialize()
{
}
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "barkString", null, 1, false);
return SCRIPT_CONTINUE;
}
public int barkString(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, "bark_string_file") || !hasObjVar(self, "bark_string_id"))
{
if (!hasObjVar(self, "alreadyTriedBarking"))
{
setObjVar(self, "alreadyTriedBarking", 1);
}
else
{
if (getIntObjVar(self, "alreadyTriedBarking") > 2)
{
return SCRIPT_CONTINUE;
}
}
messageTo(self, "barkString", null, 1, false);
return SCRIPT_CONTINUE;
}
String stringFile = getStringObjVar(self, "bark_string_file");
if (stringFile == null || stringFile.length() <= 0)
{
return SCRIPT_CONTINUE;
}
String stringId = getStringObjVar(self, "bark_string_id");
if (stringId == null || stringId.length() <= 0)
{
return SCRIPT_CONTINUE;
}
string_id message = new string_id(stringFile, stringId);
chat.chat(self, message);
return SCRIPT_CONTINUE;
}
}
@@ -1,41 +0,0 @@
include library.chat;
trigger OnAttach()
{
messageTo(self, "barkString", null, 1, false);
return SCRIPT_CONTINUE;
}
messageHandler barkString()
{
if(!hasObjVar(self, "bark_string_file") || !hasObjVar(self, "bark_string_id"))
{
if(!hasObjVar(self, "alreadyTriedBarking"))
{
setObjVar(self, "alreadyTriedBarking", 1);
}
else
{
if(getIntObjVar(self, "alreadyTriedBarking") > 2)
return SCRIPT_CONTINUE;
}
messageTo(self, "barkString", null, 1, false);
return SCRIPT_CONTINUE;
}
string stringFile = getStringObjVar(self, "bark_string_file");
if(stringFile == null || stringFile.length() <= 0)
return SCRIPT_CONTINUE;
string stringId = getStringObjVar(self, "bark_string_id");
if(stringId == null || stringId.length() <= 0)
return SCRIPT_CONTINUE;
string_id message = new string_id(stringFile, stringId);
chat.chat(self, message);
return SCRIPT_CONTINUE;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,743 @@
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.callable;
import script.library.hue;
import script.library.space_utils;
import script.library.space_crafting;
import script.library.utils;
import script.library.sui;
import script.library.pet_lib;
import script.library.beast_lib;
import script.library.create;
import script.library.ai_lib;
import script.library.factions;
import script.library.consumable;
import script.library.healing;
import script.library.prose;
import script.library.vehicle;
import script.library.space_transition;
import script.library.buff;
import script.library.group;
import script.library.performance;
import script.library.ai_lib;
import script.library.tcg;
public class beast_control_device extends script.base_script
{
public beast_control_device()
{
}
public static final string_id SID_CANNOT_TRANSFER_BCD = new string_id("beast", "cannot_transfer_bcd");
public static final string_id SID_CANNOT_CALL_BEAST_COMBAT = new string_id("beast", "beast_cant_call_combat");
public static final string_id SID_CANNOT_STORE_BEAST_COMBAT = new string_id("beast", "beast_cant_store");
public static final string_id SID_STUFF_BEAST = new string_id("beast", "beast_stuff");
public static final String CALLED_FOR_PET = "player.calledForPet";
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info mi) throws InterruptedException
{
if (ai_lib.aiIsDead(player))
{
return SCRIPT_CONTINUE;
}
obj_id myContainer = getContainedBy(self);
obj_id yourPad = utils.getPlayerDatapad(player);
if (myContainer != yourPad)
{
if (hasScript(myContainer, "ai.beast_control_device"))
{
putIn(self, yourPad);
}
return SCRIPT_CONTINUE;
}
obj_id calledBeast = beast_lib.getBCDBeastCalled(self);
if (!beast_lib.isValidBeast(calledBeast))
{
if (!isSpaceScene() || getState(player, STATE_SHIP_INTERIOR) == 1)
{
setCount(self, 0);
mi.addRootMenu(menu_info_types.PET_CALL, new string_id(pet_lib.MENU_FILE, "menu_call"));
}
mi.addRootMenu(menu_info_types.SERVER_MENU1, SID_STUFF_BEAST);
}
else
{
if (calledBeast.isLoaded() && exists(calledBeast) && !ai_lib.isInCombat(player))
{
mi.addRootMenu(menu_info_types.PET_CALL, new string_id(pet_lib.MENU_FILE, "menu_store"));
}
}
return SCRIPT_CONTINUE;
}
public int OnObjectMenuSelect(obj_id self, obj_id player, int item) throws InterruptedException
{
if (ai_lib.aiIsDead(player) || getPerformanceType(player) != 0)
{
sendSystemMessage(player, new string_id("spam", "cant_do_it_state"));
return SCRIPT_CONTINUE;
}
obj_id calledBeast = beast_lib.getBCDBeastCalled(self);
if (item == menu_info_types.PET_CALL && !beast_lib.isValidBeast(calledBeast))
{
String beastName = beast_lib.getBCDBeastName(self);
if (beastName == null || beastName.equals(""))
{
return SCRIPT_CONTINUE;
}
if (isSpaceScene() && getState(player, STATE_SHIP_INTERIOR) != 1)
{
string_id strSpam = new string_id("space/space_interaction", "no_action_station");
sendSystemMessage(player, strSpam);
return SCRIPT_CONTINUE;
}
if (vehicle.isRidingBattlefieldVehicle(player))
{
string_id strSpam = new string_id("beast", "battlefield_vehicle_restriction");
sendSystemMessage(player, strSpam);
return SCRIPT_CONTINUE;
}
if (!beast_lib.isBeastMaster(player))
{
sendSystemMessage(player, beast_lib.SID_NOT_BEAST_MASTER);
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(player, CALLED_FOR_PET))
{
int timeLeft = pet_lib.getTimeLeft(player, CALLED_FOR_PET, pet_lib.CALL_FINISH);
if (timeLeft < 0)
{
utils.removeScriptVar(player, CALLED_FOR_PET);
}
else
{
prose_package pp = prose.getPackage(pet_lib.SID_SYS_CALL_DELAY_FINISH_PET, timeLeft);
sendSystemMessageProse(player, pp);
return SCRIPT_CONTINUE;
}
}
if (callable.hasCallable(player, callable.CALLABLE_TYPE_RIDEABLE))
{
obj_id rideable = callable.getCallable(player, callable.CALLABLE_TYPE_RIDEABLE);
if (isIdValid(rideable) && exists(rideable))
{
callable.storeCallable(player, rideable);
}
}
obj_id currentBeast = null;
if (callable.hasCallable(player, callable.CALLABLE_TYPE_COMBAT_PET))
{
currentBeast = callable.getCallable(player, callable.CALLABLE_TYPE_COMBAT_PET);
if (beast_lib.isValidBeast(currentBeast))
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
else
{
beast_lib.setBCDBeastCalled(self, null);
}
}
if (isIdValid(space_transition.getContainingShip(player)))
{
if (space_utils.isInStation(player))
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
}
if ((getLocation(player).area).startsWith("kashyyyk_pob") && getTopMostContainer(player) == player)
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
if (beast_lib.getTotalBeastsCalled(player) > 0)
{
sendSystemMessage(player, beast_lib.SID_MAXIMUM_BEASTS);
return SCRIPT_CONTINUE;
}
int beastLevel = beast_lib.getBCDBeastLevel(self);
if (getLevel(player) < beastLevel - beast_lib.BEAST_LEVEL_MAX_DIFFERENCE && !isGod(player))
{
sendSystemMessage(player, beast_lib.SID_BEAST_TOO_HIGH_LEVEL);
return SCRIPT_CONTINUE;
}
obj_id beast = beast_lib.createBeastFromBCD(player, self);
if (isIdValid(beast))
{
beast_lib.checkForFavoriteLocation(self);
}
if (group.isGrouped(player))
{
messageTo(self, "ownerGrouped", null, 1, false);
}
if (performance.checkPlayerEntertained(player, "both"))
{
messageTo(self, "ownerEntertained", null, 1, false);
}
sendDirtyObjectMenuNotification(self);
return SCRIPT_CONTINUE;
}
else if (item == menu_info_types.PET_CALL && beast_lib.isValidBeast(calledBeast))
{
if (ai_lib.isInCombat(player))
{
sendSystemMessage(player, SID_CANNOT_STORE_BEAST_COMBAT);
return SCRIPT_CONTINUE;
}
if (callable.hasCallable(player, callable.CALLABLE_TYPE_COMBAT_PET))
{
obj_id currentBeast = callable.getCallable(player, callable.CALLABLE_TYPE_COMBAT_PET);
if (ai_lib.isInCombat(currentBeast))
{
sendSystemMessage(player, new string_id("beast", "beast_cant_store"));
return SCRIPT_CONTINUE;
}
}
beast_lib.storeBeast(self);
sendDirtyObjectMenuNotification(self);
return SCRIPT_CONTINUE;
}
else if (item == menu_info_types.SERVER_MENU1)
{
if (beast_lib.isValidBeast(calledBeast))
{
sendSystemMessage(player, new string_id("beast", "beast_cant_stuff"));
return SCRIPT_CONTINUE;
}
String title = utils.packStringId(new string_id("beast", "beast_stuff_really_title"));
String prompt = getString(new string_id("beast", "beast_stuff_really_prompt"));
int pid = sui.msgbox(self, player, prompt, sui.YES_NO, title, "handleBeastStuffingConfirm");
}
return SCRIPT_CONTINUE;
}
public int handleBeastStuffingConfirm(obj_id self, dictionary params) throws InterruptedException
{
obj_id player = sui.getPlayerId(params);
if (!isIdValid(player))
{
return SCRIPT_CONTINUE;
}
int bp = sui.getIntButtonPressed(params);
if (bp == sui.BP_CANCEL)
{
return SCRIPT_CONTINUE;
}
beast_lib.convertBcdIntoBeastItem(player, self);
return SCRIPT_CONTINUE;
}
public int OnAboutToReceiveItem(obj_id self, obj_id srcContainer, obj_id transferer, obj_id item) throws InterruptedException
{
if (hasScript(item, "ai.beast_control_device"))
{
return SCRIPT_OVERRIDE;
}
if (!isIdValid(transferer))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_OVERRIDE;
}
public int OnDestroy(obj_id self) throws InterruptedException
{
beast_lib.storeBeast(self);
obj_id master = beast_lib.getBCDPlayer(self);
if (beast_lib.isValidPlayer(master))
{
setBeastmasterPet(master, null);
}
return SCRIPT_CONTINUE;
}
public int OnTransferred(obj_id self, obj_id sourceContainer, obj_id destContainer, obj_id transferer) throws InterruptedException
{
if (!exists(self))
{
return SCRIPT_CONTINUE;
}
beast_lib.storeBeast(self);
return SCRIPT_CONTINUE;
}
public int OnAttach(obj_id self) throws InterruptedException
{
obj_id player = utils.getContainingPlayer(self);
if (!beast_lib.isValidPlayer(player))
{
return SCRIPT_CONTINUE;
}
sendSystemMessage(player, new string_id("beast", "datapad_beast_added"));
return SCRIPT_CONTINUE;
}
public int OnGetAttributes(obj_id self, obj_id player, String[] names, String[] attribs) throws InterruptedException
{
if (!exists(self))
{
return SCRIPT_CONTINUE;
}
int idx = utils.getValidAttributeIndex(names);
if (idx == -1)
{
return SCRIPT_CONTINUE;
}
names[idx] = beast_lib.BEAST_MOOD_TITLE;
String currentHappiness = utils.packStringId(beast_lib.convertHappinessString(self));
if (currentHappiness != null)
{
attribs[idx] = "" + currentHappiness;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
names[idx] = beast_lib.BEAST_LOYALTY_TITLE;
String currentLoyalty = utils.packStringId(beast_lib.convertLoyaltyString(self));
if (currentLoyalty != null)
{
attribs[idx] = "" + currentLoyalty;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int level = beast_lib.getBCDBeastLevel(self);
int trainingPoints = beast_lib.getSingleSkillMaxTrainingPoints(self, level);
if (trainingPoints > 0)
{
names[idx] = "bm_single_max_training_points";
attribs[idx] = "" + trainingPoints;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int pointsSpent = beast_lib.calculateTrainingPointsSpent(self);
if (pointsSpent > 0)
{
names[idx] = "bm_points_spent";
attribs[idx] = "" + pointsSpent;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int maxAvailableTrainingPoints = beast_lib.getAvailableTrainingPoints(self);
if (maxAvailableTrainingPoints > 0)
{
names[idx] = "bm_points_available";
attribs[idx] = "" + maxAvailableTrainingPoints;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
if (hasObjVar(self, beast_lib.OBJVAR_BEAST_INCUBATION_BONUSES))
{
int[] incubationBonuses = getIntArrayObjVar(self, beast_lib.OBJVAR_BEAST_INCUBATION_BONUSES);
if (incubationBonuses.length == beast_lib.ARRAY_BEAST_INCUBATION_STATS.length && incubationBonuses.length == beast_lib.DISPLAY_NAMES.length && incubationBonuses.length == beast_lib.DISPLAY_OBJVAR_CONVERSION_RATES.length)
{
for (int i = 0; i < incubationBonuses.length; i++)
{
String name = beast_lib.DISPLAY_NAMES[i];
if (name.indexOf("_skill") < 0)
{
if (!name.equals("block_value_bonus"))
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" + utils.roundFloatByDecimal((float)incubationBonuses[i] * beast_lib.DISPLAY_OBJVAR_CONVERSION_RATES[i]) + "%";
idx++;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" + incubationBonuses[i];
idx++;
}
continue;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" + incubationBonuses[i];
idx++;
continue;
}
}
}
}
if (exists(self) && hasObjVar(self, beast_lib.OBJVAR_BEAST_ENGINEER))
{
String creatorName = getStringObjVar(self, beast_lib.OBJVAR_BEAST_ENGINEER);
names[idx] = "bm_creator";
attribs[idx] = creatorName;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
setDescriptionStringId(self, new string_id("spam", "bm_train_pet_info"));
return SCRIPT_CONTINUE;
}
public int OnAboutToBeTransferred(obj_id self, obj_id destContainer, obj_id transferer) throws InterruptedException
{
if (tcg.isBarnRanchhand(destContainer) || tcg.isBarnRanchhand(getContainedBy(destContainer)))
{
return SCRIPT_CONTINUE;
}
obj_id bcdPlayer = beast_lib.getBCDPlayer(self);
if (isIdValid(bcdPlayer) && destContainer == bcdPlayer || getContainedBy(destContainer) == bcdPlayer)
{
return SCRIPT_CONTINUE;
}
sendSystemMessage(transferer, SID_CANNOT_TRANSFER_BCD);
return SCRIPT_OVERRIDE;
}
public int handlePetDeathblow(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int beastPing(obj_id self, dictionary params) throws InterruptedException
{
obj_id beast = params.getObjId("beastId");
int messageCount = params.getInt("messageId");
if (!beast_lib.isValidBeast(beast))
{
return SCRIPT_CONTINUE;
}
obj_id beastOnBCD = beast_lib.getBCDBeastCalled(self);
obj_id player = beast_lib.getBCDPlayer(self);
if (beastOnBCD != beast || getMaster(beast) != player || beast_lib.getTotalBeastsCalled(player) > 1)
{
beast_lib.storeBeast(self);
}
messageCount++;
dictionary messageData = new dictionary();
messageData.put("messageId", messageCount);
messageTo(beast, "bcdPingResponse", messageData, 1, false);
return SCRIPT_CONTINUE;
}
public int beastHungry(obj_id self, dictionary params) throws InterruptedException
{
obj_id beast = params.getObjId("beastId");
obj_id beastOnBCD = beast_lib.getBCDBeastCalled(self);
obj_id player = beast_lib.getBCDPlayer(self);
if (beastOnBCD != beast || getMaster(beast) != player || beast_lib.getTotalBeastsCalled(player) > 1)
{
return SCRIPT_CONTINUE;
}
if (!beast_lib.hasBCDBeastFood(self))
{
LOG("beast_control_device", "Something is wrong. Pet has been fed before or this message shouldn't go off, yet the pet doesn't have the beastmood.beastLastFed");
}
int currentTime = getGameTime();
int[] beastFood = beast_lib.getBCDBeastFood(self);
if (beast_lib.getBCDBeastLastFedTime(self) > 3600)
{
if (beastFood.length != beast_lib.PET_FOOD_MAX_ARRAYS)
{
return SCRIPT_CONTINUE;
}
int[] autoFeederBuffCrc = buff.getAllBuffsByEffect(beast, "beast_auto_feeder");
if (autoFeederBuffCrc != null && autoFeederBuffCrc.length > 0)
{
String autoFeederBuffName = buff.getBuffNameFromCrc(autoFeederBuffCrc[0]);
if (autoFeederBuffName != null && autoFeederBuffName.length() > 0)
{
if (beast_lib.feedBeastUsingAutoFeeder(beast, player, autoFeederBuffName))
{
return SCRIPT_CONTINUE;
}
}
}
if (beastFood[beast_lib.PET_WHICH_FOOD] != beast_lib.PET_NO_FOOD)
{
beastFood[beast_lib.PET_WHICH_FOOD] = beast_lib.PET_NO_FOOD;
beast_lib.setBCDBeastFood(self, beastFood);
beast_lib.decrementBeastLoyalty(self, beast_lib.LOYALTY_FOOD_LOSS);
beast_lib.updateBeastHappiness(self, beastOnBCD);
}
if (!utils.hasScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR))
{
if (!isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_PET_HUNGRY);
}
utils.setScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeHungryBlock", null, 600, false);
}
}
else
{
LOG("beast_control_device", "Something is wrong. Pet has been fed but their last time fed has not been updated");
}
return SCRIPT_CONTINUE;
}
public int ownerGrouped(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int[] beastHappiness = new int[beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
String favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
String dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
if (favoriteActivity.indexOf("grouped") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "checkIfStillGrouped", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if (dislikeActivity.indexOf("grouped") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "checkIfStillGrouped", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
public int checkIfStillGrouped(obj_id self, dictionary params) throws InterruptedException
{
obj_id player = beast_lib.getBCDPlayer(self);
if (group.isGrouped(player))
{
messageTo(self, "checkIfStillGrouped", null, 1800, false);
}
else
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
}
return SCRIPT_CONTINUE;
}
public int ownerEntertained(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int[] beastHappiness = new int[beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
String favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
String dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
if (favoriteActivity.indexOf("watchingEntertainer") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "checkIfStillEntertained", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if (dislikeActivity.indexOf("watchingEntertainer") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "checkIfStillEntertained", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
public int checkIfStillEntertained(obj_id self, dictionary params) throws InterruptedException
{
obj_id player = beast_lib.getBCDPlayer(self);
if (performance.checkPlayerEntertained(player, "both"))
{
messageTo(self, "checkIfStillEntertained", null, 1800, false);
}
else
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
}
return SCRIPT_CONTINUE;
}
public int beastKilledSomething(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id target = params.getObjId("targetId");
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int[] beastHappiness = new int[beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
String favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
String dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
if (ai_lib.isAnimal(target))
{
if (favoriteActivity.indexOf("killCreature") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeKillBonus", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR, 1);
}
}
else if (dislikeActivity != null && dislikeActivity.length() > 0 && dislikeActivity.indexOf("killCreature") > -1)
{
if (isIdValid(player) && hasObjVar(player, "qa_beast_hate"))
{
sendSystemMessageTestingOnly(player, "QA: Beast used to hate combat with creatures. It would have its happiness lowered here.");
}
}
}
if (ai_lib.isNpc(target))
{
if (favoriteActivity.indexOf("killNpc") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeKillBonus", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR, 1);
}
}
else if (dislikeActivity != null && dislikeActivity.length() > 0 && dislikeActivity.indexOf("killNpc") > -1)
{
if (isIdValid(player) && hasObjVar(player, "qa_beast_hate"))
{
sendSystemMessageTestingOnly(player, "QA: Beast used to hate combat with npc's. It would have its happiness lowered here.");
}
}
}
}
return SCRIPT_CONTINUE;
}
public int removeKillBonus(obj_id self, dictionary params) throws InterruptedException
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
if (utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
public int petDoingTrick(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int[] beastHappiness = new int[beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
String favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
String dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] - 1), beast_lib.DATATABLE_ACTIVITY_COL);
if (favoriteActivity.indexOf("trick") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeTrickBonus", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if (dislikeActivity.indexOf("trick") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "removeTrickBonus", null, 1800, false);
if (!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if (isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
public int removeTrickBonus(obj_id self, dictionary params) throws InterruptedException
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
return SCRIPT_CONTINUE;
}
public int removeHungryBlock(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
public int removeActivityBlock(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,913 +0,0 @@
/*
* Title: ai.beast_control_device
*/
include library.callable;
include library.hue;
include library.space_utils;
include library.space_crafting;
include library.utils;
include library.sui;
include library.pet_lib;
include library.beast_lib;
include library.create;
include library.ai_lib;
include library.factions;
include library.consumable;
include library.healing;
include library.prose;
include library.vehicle;
include library.space_transition;
include library.buff;
include library.group;
include library.performance;
include library.ai_lib;
include library.tcg;
/***** CONSTANTS ****************************************************/
const string_id SID_CANNOT_TRANSFER_BCD = new string_id("beast", "cannot_transfer_bcd");
const string_id SID_CANNOT_CALL_BEAST_COMBAT = new string_id("beast", "beast_cant_call_combat");
const string_id SID_CANNOT_STORE_BEAST_COMBAT = new string_id("beast", "beast_cant_store");
const string_id SID_STUFF_BEAST = new string_id("beast", "beast_stuff");
const string CALLED_FOR_PET = "player.calledForPet";
/***** FUNCTIONS ****************************************************/
trigger OnObjectMenuRequest(obj_id player, menu_info mi)
{
if(ai_lib.aiIsDead(player))
{
return SCRIPT_CONTINUE;
}
obj_id myContainer = getContainedBy(self);
obj_id yourPad = utils.getPlayerDatapad(player);
if(myContainer != yourPad)
{
if(hasScript(myContainer, "ai.beast_control_device"))
{
putIn(self, yourPad);
}
return SCRIPT_CONTINUE;
}
obj_id calledBeast = beast_lib.getBCDBeastCalled(self);
if(!beast_lib.isValidBeast(calledBeast))
{
// Cannot call in space unless in a pob ship interior
if( !isSpaceScene() || getState(player, STATE_SHIP_INTERIOR) == 1 )
{
//add a call tab on radial and fix the count on the PCD in case it was in a bad state of the player crashing whilst on a mount:
setCount(self, 0);
mi.addRootMenu(menu_info_types.PET_CALL, new string_id(pet_lib.MENU_FILE, "menu_call"));
}
mi.addRootMenu(menu_info_types.SERVER_MENU1, SID_STUFF_BEAST);
}
else
{
if(calledBeast.isLoaded() && exists(calledBeast) && !ai_lib.isInCombat(player))
{
mi.addRootMenu(menu_info_types.PET_CALL, new string_id(pet_lib.MENU_FILE, "menu_store"));
}
}
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuSelect(obj_id player, int item)
{
if(ai_lib.aiIsDead(player) || getPerformanceType(player) != 0)
{
sendSystemMessage(player, new string_id("spam", "cant_do_it_state"));
return SCRIPT_CONTINUE;
}
obj_id calledBeast = beast_lib.getBCDBeastCalled(self);
if(item == menu_info_types.PET_CALL && !beast_lib.isValidBeast(calledBeast))
{
string beastName = beast_lib.getBCDBeastName(self);
if(beastName == null || beastName == "")
{
return SCRIPT_CONTINUE;
}
if(isSpaceScene() && getState(player, STATE_SHIP_INTERIOR) != 1)
{
// no call
string_id strSpam = new string_id("space/space_interaction", "no_action_station");
sendSystemMessage(player, strSpam);
return SCRIPT_CONTINUE;
}
if( vehicle.isRidingBattlefieldVehicle(player) )
{
// no call
string_id strSpam = new string_id("beast", "battlefield_vehicle_restriction");
sendSystemMessage(player, strSpam);
return SCRIPT_CONTINUE;
}
if(!beast_lib.isBeastMaster(player))
{
sendSystemMessage(player, beast_lib.SID_NOT_BEAST_MASTER);
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(player, CALLED_FOR_PET))
{
int timeLeft = pet_lib.getTimeLeft(player, CALLED_FOR_PET, pet_lib.CALL_FINISH);
if(timeLeft < 0)
{
// Failsafe in case the pet call never goes off.
utils.removeScriptVar(player, CALLED_FOR_PET);
}
else
{
prose_package pp = prose.getPackage(pet_lib.SID_SYS_CALL_DELAY_FINISH_PET, timeLeft);
sendSystemMessageProse(player, pp);
return SCRIPT_CONTINUE;
}
}
if(callable.hasCallable(player, callable.CALLABLE_TYPE_RIDEABLE))
{
obj_id rideable = callable.getCallable(player, callable.CALLABLE_TYPE_RIDEABLE);
if(isIdValid(rideable) && exists(rideable))
{
callable.storeCallable(player, rideable);
}
}
obj_id currentBeast = null;
if(callable.hasCallable(player, callable.CALLABLE_TYPE_COMBAT_PET))
{
currentBeast = callable.getCallable(player, callable.CALLABLE_TYPE_COMBAT_PET);
if(beast_lib.isValidBeast(currentBeast))
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
else
{
beast_lib.setBCDBeastCalled(self, null);
}
}
// cannot call beasts in ships
if(isIdValid(space_transition.getContainingShip(player)))
{
if(space_utils.isInStation(player))
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
}
//No pets on the landing platform of the avatar platform, they just fall out.
if(getLocation(player).area.startsWith("kashyyyk_pob") && getTopMostContainer(player) == player)
{
sendSystemMessage(player, pet_lib.SID_SYS_CANT_CALL);
return SCRIPT_CONTINUE;
}
if(beast_lib.getTotalBeastsCalled(player) > 0)
{
sendSystemMessage(player, beast_lib.SID_MAXIMUM_BEASTS);
return SCRIPT_CONTINUE;
}
int beastLevel = beast_lib.getBCDBeastLevel(self);
if(getLevel(player) < beastLevel - beast_lib.BEAST_LEVEL_MAX_DIFFERENCE && !isGod(player))
{
sendSystemMessage(player, beast_lib.SID_BEAST_TOO_HIGH_LEVEL);
return SCRIPT_CONTINUE;
}
obj_id beast = beast_lib.createBeastFromBCD(player, self);
//checking if pet is being called at its favorite location.
if(isIdValid(beast))
beast_lib.checkForFavoriteLocation(self);
//checking if player is grouped and if that's a favorite location of the pet.
if(group.isGrouped(player))
{
messageTo(self, "ownerGrouped", null, 1, false);
}
//checking if owner is watching an entertainer and seeing if the pet enjoys being entertained.
if(performance.checkPlayerEntertained(player, "both"))
{
messageTo(self, "ownerEntertained", null, 1, false);
}
sendDirtyObjectMenuNotification(self);
return SCRIPT_CONTINUE;
}
else if(item == menu_info_types.PET_CALL && beast_lib.isValidBeast(calledBeast))
{
if(ai_lib.isInCombat(player))
{
sendSystemMessage(player, SID_CANNOT_STORE_BEAST_COMBAT);
return SCRIPT_CONTINUE;
}
if(callable.hasCallable(player, callable.CALLABLE_TYPE_COMBAT_PET))
{
obj_id currentBeast = callable.getCallable(player, callable.CALLABLE_TYPE_COMBAT_PET);
if(ai_lib.isInCombat(currentBeast))
{
sendSystemMessage(player, new string_id("beast", "beast_cant_store"));
return SCRIPT_CONTINUE;
}
}
beast_lib.storeBeast(self);
sendDirtyObjectMenuNotification(self);
return SCRIPT_CONTINUE;
}
else if(item == menu_info_types.SERVER_MENU1)
{
if(beast_lib.isValidBeast(calledBeast))
{
sendSystemMessage(player, new string_id("beast", "beast_cant_stuff"));
return SCRIPT_CONTINUE;
}
string title = utils.packStringId(new string_id("beast", "beast_stuff_really_title")); // Confirm Stuffing?
string prompt = getString(new string_id("beast", "beast_stuff_really_prompt")); // Are you sure that you want to stuff the selected beast?
int pid = sui.msgbox(self, player, prompt, sui.YES_NO, title, "handleBeastStuffingConfirm");
}
return SCRIPT_CONTINUE;
}
messageHandler handleBeastStuffingConfirm()
{
obj_id player = sui.getPlayerId(params);
if(!isIdValid(player))
return SCRIPT_CONTINUE;
int bp = sui.getIntButtonPressed(params);
if(bp == sui.BP_CANCEL)
return SCRIPT_CONTINUE;
beast_lib.convertBcdIntoBeastItem(player, self);
// sendSystemMessage
return SCRIPT_CONTINUE;
}
trigger OnAboutToReceiveItem(obj_id srcContainer, obj_id transferer, obj_id item)
{
if(hasScript(item, "ai.beast_control_device"))
{
return SCRIPT_OVERRIDE;
}
if(!isIdValid(transferer))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_OVERRIDE;
}
trigger OnDestroy()
{
beast_lib.storeBeast(self);
obj_id master = beast_lib.getBCDPlayer(self);
if(beast_lib.isValidPlayer(master))
{
setBeastmasterPet(master, null);
}
return SCRIPT_CONTINUE;
}
trigger OnTransferred(obj_id sourceContainer, obj_id destContainer, obj_id transferer)
{
if(!exists(self))
{
return SCRIPT_CONTINUE;
}
beast_lib.storeBeast(self);
return SCRIPT_CONTINUE;
}
trigger OnAttach()
{
obj_id player = utils.getContainingPlayer(self);
if(!beast_lib.isValidPlayer(player))
{
return SCRIPT_CONTINUE;
}
sendSystemMessage(player, new string_id("beast", "datapad_beast_added"));
return SCRIPT_CONTINUE;
}
trigger OnGetAttributes( obj_id player, string[] names, string[] attribs )
{
if(!exists(self))
{
return SCRIPT_CONTINUE;
}
int idx = utils.getValidAttributeIndex(names);
if(idx == -1)
{
return SCRIPT_CONTINUE;
}
names[idx] = beast_lib.BEAST_MOOD_TITLE;
string currentHappiness = utils.packStringId(beast_lib.convertHappinessString(self));
if(currentHappiness != null)
{
attribs[idx] = "" + currentHappiness;
idx++;
if(idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
names[idx] = beast_lib.BEAST_LOYALTY_TITLE;
string currentLoyalty = utils.packStringId(beast_lib.convertLoyaltyString(self));
if(currentLoyalty != null)
{
attribs[idx] = "" + currentLoyalty;
idx++;
if(idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
//display the points available for training.
int level = beast_lib.getBCDBeastLevel(self);
int trainingPoints = beast_lib.getSingleSkillMaxTrainingPoints(self, level);
if(trainingPoints > 0)
{
names[idx] = "bm_single_max_training_points";
attribs[idx] = "" + trainingPoints;
idx++;
if(idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int pointsSpent = beast_lib.calculateTrainingPointsSpent(self);
if( pointsSpent > 0)
{
names[idx] = "bm_points_spent";
attribs[idx] = "" + pointsSpent;
idx++;
if(idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int maxAvailableTrainingPoints = beast_lib.getAvailableTrainingPoints(self);
if( maxAvailableTrainingPoints > 0)
{
names[idx] = "bm_points_available";
attribs[idx] = "" + maxAvailableTrainingPoints;
idx++;
if(idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
if(hasObjVar(self, beast_lib.OBJVAR_BEAST_INCUBATION_BONUSES) )
{
int[] incubationBonuses = getIntArrayObjVar(self, beast_lib.OBJVAR_BEAST_INCUBATION_BONUSES);
if(incubationBonuses.length == beast_lib.ARRAY_BEAST_INCUBATION_STATS.length && incubationBonuses.length == beast_lib.DISPLAY_NAMES.length
&& incubationBonuses.length == beast_lib.DISPLAY_OBJVAR_CONVERSION_RATES.length)
{
for(int i = 0 ; i < incubationBonuses.length; i++)
{
string name = beast_lib.DISPLAY_NAMES[i];
if(name.indexOf("_skill") < 0)
{
if(!name.equals("block_value_bonus"))
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" + utils.roundFloatByDecimal((float)incubationBonuses[i] * beast_lib.DISPLAY_OBJVAR_CONVERSION_RATES[i]) + "%";
idx++;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" +incubationBonuses[i];
idx++;
}
continue;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = "" +incubationBonuses[i];
idx++;
continue;
}
}
}
}
if(exists(self) && hasObjVar(self, beast_lib.OBJVAR_BEAST_ENGINEER))
{
string creatorName = getStringObjVar(self, beast_lib.OBJVAR_BEAST_ENGINEER);
names[idx] = "bm_creator";
attribs[idx] = creatorName;
idx++;
if (idx >= names.length)
return SCRIPT_CONTINUE;
}
setDescriptionStringId(self, new string_id("spam", "bm_train_pet_info"));
return SCRIPT_CONTINUE;
}
trigger OnAboutToBeTransferred(obj_id destContainer, obj_id transferer)
{
if ( tcg.isBarnRanchhand(destContainer) || tcg.isBarnRanchhand(getContainedBy(destContainer)))
{
return SCRIPT_CONTINUE;
}
obj_id bcdPlayer = beast_lib.getBCDPlayer(self);
if ( isIdValid(bcdPlayer) && destContainer == bcdPlayer || getContainedBy(destContainer) == bcdPlayer )
{
return SCRIPT_CONTINUE;
}
sendSystemMessage(transferer, SID_CANNOT_TRANSFER_BCD);
return SCRIPT_OVERRIDE;
}
messageHandler handlePetDeathblow()
{
return SCRIPT_CONTINUE;
}
messageHandler beastPing()
{
obj_id beast = params.getObjId("beastId");
int messageCount = params.getInt("messageId");
if(!beast_lib.isValidBeast(beast))
{
return SCRIPT_CONTINUE;
}
obj_id beastOnBCD = beast_lib.getBCDBeastCalled(self);
obj_id player = beast_lib.getBCDPlayer(self);
if(beastOnBCD != beast || getMaster(beast) != player || beast_lib.getTotalBeastsCalled(player) > 1)
{
beast_lib.storeBeast(self);
}
messageCount++;
dictionary messageData = new dictionary();
messageData.put("messageId", messageCount);
messageTo(beast, "bcdPingResponse", messageData, 1, false);
return SCRIPT_CONTINUE;
}
messageHandler beastHungry()
{
obj_id beast = params.getObjId("beastId");
obj_id beastOnBCD = beast_lib.getBCDBeastCalled(self);
obj_id player = beast_lib.getBCDPlayer(self);
if(beastOnBCD != beast || getMaster(beast) != player || beast_lib.getTotalBeastsCalled(player) > 1)
//No pet out, player will be informed that pet is hungry when he's next called.
return SCRIPT_CONTINUE;
//validating
if(!beast_lib.hasBCDBeastFood(self))
LOG("beast_control_device", "Something is wrong. Pet has been fed before or this message shouldn't go off, yet the pet doesn't have the beastmood.beastLastFed");
//validating again
int currentTime = getGameTime();
int [] beastFood = beast_lib.getBCDBeastFood(self);
if(beast_lib.getBCDBeastLastFedTime(self) > 3600)
{
//validate
if(beastFood.length != beast_lib.PET_FOOD_MAX_ARRAYS)
{
return SCRIPT_CONTINUE;
}
// does the beast have an autofeeder buff
int[] autoFeederBuffCrc = buff.getAllBuffsByEffect(beast, "beast_auto_feeder");
if ( autoFeederBuffCrc != null && autoFeederBuffCrc.length > 0 )
{
string autoFeederBuffName = buff.getBuffNameFromCrc(autoFeederBuffCrc[0]);
if ( autoFeederBuffName != null && autoFeederBuffName.length() > 0 )
{
if ( beast_lib.feedBeastUsingAutoFeeder(beast, player, autoFeederBuffName) )
{
// the beast was successfully fed using an autofeeder
return SCRIPT_CONTINUE;
}
}
}
if(beastFood[beast_lib.PET_WHICH_FOOD] != beast_lib.PET_NO_FOOD)
{
//set beast to not being fed
beastFood[beast_lib.PET_WHICH_FOOD] = beast_lib.PET_NO_FOOD;
beast_lib.setBCDBeastFood(self, beastFood);
beast_lib.decrementBeastLoyalty(self, beast_lib.LOYALTY_FOOD_LOSS);
beast_lib.updateBeastHappiness(self, beastOnBCD);
}
if(!utils.hasScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR))
{
if(!isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_PET_HUNGRY);
}
utils.setScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeHungryBlock", null, 600, false);
}
}
else
LOG("beast_control_device", "Something is wrong. Pet has been fed but their last time fed has not been updated");
return SCRIPT_CONTINUE;
}
//Beast owner added to group. Checking if that's a favorite activity for beast.
messageHandler ownerGrouped()
{
if(!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int [] beastHappiness = new int [beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
string favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] -1), beast_lib.DATATABLE_ACTIVITY_COL);
string dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] -1), beast_lib.DATATABLE_ACTIVITY_COL);
if(favoriteActivity.indexOf("grouped") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "checkIfStillGrouped", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if(dislikeActivity.indexOf("grouped") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "checkIfStillGrouped", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
//Checking if beast owner is still grouped, otherwise, remove activity bonus/penalty
messageHandler checkIfStillGrouped()
{
obj_id player = beast_lib.getBCDPlayer(self);
if(group.isGrouped(player))
{
messageTo(self, "checkIfStillGrouped", null, 1800, false);
}
else
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
}
return SCRIPT_CONTINUE;
}
//Beast owner being entertained, checking if that's a favorite or dislike activity of pet.
messageHandler ownerEntertained()
{
if(!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int [] beastHappiness = new int [beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar (self, beast_lib.PET_FAVORITES_OBJVAR);
string favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] -1), beast_lib.DATATABLE_ACTIVITY_COL);
string dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] -1), beast_lib.DATATABLE_ACTIVITY_COL);
if(favoriteActivity.indexOf("watchingEntertainer") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "checkIfStillEntertained", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if(dislikeActivity.indexOf("watchingEntertainer") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "checkIfStillEntertained", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
messageHandler checkIfStillEntertained()
{
obj_id player = beast_lib.getBCDPlayer(self);
if(performance.checkPlayerEntertained(player, "both"))
{
messageTo(self, "checkIfStillEntertained", null, 1800, false);
}
else
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
}
return SCRIPT_CONTINUE;
}
//Beast killed something, checking if that's a favorite or dislike activity
messageHandler beastKilledSomething()
{
if(!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id target = params.getObjId("targetId");
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int [] beastHappiness = new int [beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
string favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] -1), beast_lib.DATATABLE_ACTIVITY_COL);
string dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] -1), beast_lib.DATATABLE_ACTIVITY_COL);
if(ai_lib.isAnimal(target))
{
if(favoriteActivity.indexOf("killCreature") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeKillBonus", null, 1800, false);
//To avoid spamming the player everytime his pet kills something, we put a script var after playing the system message for a player.
if(!utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR, 1);
}
}
else if(dislikeActivity != null && dislikeActivity.length() > 0 && dislikeActivity.indexOf("killCreature") > -1)
{
if(isIdValid(player) && hasObjVar(player, "qa_beast_hate"))
{
sendSystemMessageTestingOnly(player, "QA: Beast used to hate combat with creatures. It would have its happiness lowered here.");
}
}
}
if(ai_lib.isNpc(target))
{
if(favoriteActivity.indexOf("killNpc") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeKillBonus", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR, 1);
}
}
else if(dislikeActivity != null && dislikeActivity.length() > 0 && dislikeActivity.indexOf("killNpc") > -1)
{
if(isIdValid(player) && hasObjVar(player, "qa_beast_hate"))
{
sendSystemMessageTestingOnly(player, "QA: Beast used to hate combat with npc's. It would have its happiness lowered here.");
}
}
}
}
return SCRIPT_CONTINUE;
}
//It's been 30 mins since the beast killed something, remove happiness bonus.
messageHandler removeKillBonus()
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
//Removing anti spam scriptvar.
if(utils.hasScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_KILL_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
//Beast is performing a trick, checing if it's his favorite activity.
messageHandler petDoingTrick()
{
if(!hasObjVar(self, beast_lib.PET_FAVORITES_OBJVAR))
{
LOG("beast_control_device", "Something is wrong. This BCD does not have the pets favorite activities stored. Setting them up now");
beast_lib.setupHappinessLoyalty(self);
}
else
{
obj_id player = beast_lib.getBCDPlayer(self);
obj_id beast = beast_lib.getBCDBeastCalled(self);
int [] beastHappiness = new int [beast_lib.LIKE_DISLIKE_MAX];
beastHappiness = getIntArrayObjVar(self, beast_lib.PET_FAVORITES_OBJVAR);
string favoriteActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[2] -1), beast_lib.DATATABLE_ACTIVITY_COL);
string dislikeActivity = dataTableGetString(beast_lib.DATATABLE_BEAST_FAVORITES, (beastHappiness[3] -1), beast_lib.DATATABLE_ACTIVITY_COL);
if(favoriteActivity.indexOf("trick") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_FAVORITE_ACTIVITY);
messageTo(self, "removeTrickBonus", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_FAVORITE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
else if(dislikeActivity.indexOf("trick") > -1)
{
beast_lib.performingActivity(self, beast_lib.PET_DISLIKE_ACTIVITY);
messageTo(self, "removeTrickBonus", null, 1800, false);
if(!utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
if(isIdValid(beast) && exists(beast) && !isDead(beast))
{
sendSystemMessage(player, beast_lib.SID_DISLIKE_ACTIVITY);
}
utils.setScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR, 1);
messageTo(self, "removeActivityBlock", null, 600, false);
}
}
}
return SCRIPT_CONTINUE;
}
//It's been 30 mins since the beast did a trick, remove happiness bonus.
messageHandler removeTrickBonus()
{
beast_lib.performingActivity(self, beast_lib.PET_NORMAL_ACTIVITY);
return SCRIPT_CONTINUE;
}
//It's been 10 mins since the beast let his owner know that he's hungry. Remove scriptvar block.
messageHandler removeHungryBlock()
{
//Removing anti spam scriptvar.
if(utils.hasScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_HUNGRY_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
//It's been 10 mins since the beast let his owner know that he likes the current activity. Remove scriptvar block.
messageHandler removeActivityBlock()
{
//Removing anti spam scriptvar.
if(utils.hasScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR))
{
utils.removeScriptVar(self, beast_lib.PET_ACTIVITY_MESSAGE_SCRIPTVAR);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,30 @@
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.utils;
public class beast_inventory extends script.base_script
{
public beast_inventory()
{
}
public int OnReceivedItem(obj_id self, obj_id srcContainer, obj_id transferer, obj_id item) throws InterruptedException
{
if (!isPlayer(transferer))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_OVERRIDE;
}
public int OnAboutToLoseItem(obj_id self, obj_id destContainer, obj_id transferer, obj_id item) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
}
@@ -1,16 +0,0 @@
include library.utils;
trigger OnReceivedItem(obj_id srcContainer, obj_id transferer, obj_id item)
{
if(!isPlayer(transferer))
{
return SCRIPT_CONTINUE;
}
return SCRIPT_OVERRIDE;
}
trigger OnAboutToLoseItem(obj_id destContainer, obj_id transferer, obj_id item)
{
return SCRIPT_OVERRIDE;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,252 @@
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.callable;
import script.library.create;
import script.library.utils;
public class dancing_droid extends script.base_script
{
public dancing_droid()
{
}
public static final string_id SID_DANCE = new string_id("pet/pet_menu", "dance");
public static final String TRIG_VOLUME = "droid_trig_volume";
public static final int TRIG_RADIUS = 20;
public static final boolean PROMISCUOUS = true;
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info item) throws InterruptedException
{
if (getMaster(self) != player)
{
return SCRIPT_CONTINUE;
}
if (!utils.hasScriptVar(self, "music.stillPlaying"))
{
item.addRootMenu(menu_info_types.SERVER_MENU1, SID_DANCE);
}
return SCRIPT_CONTINUE;
}
public int OnObjectMenuSelect(obj_id self, obj_id player, int item) throws InterruptedException
{
if (getMaster(self) != player)
{
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.SERVER_MENU1 && !utils.hasScriptVar(self, "music.stillPlaying"))
{
location startLocation = getLocation(self);
obj_id pcd = callable.getCallableCD(self);
obj_id soundObject = createObject("object/soundobject/soundobject_figrin_dan_band_droid.iff", startLocation);
String template = getTemplateName(self);
String droidName = getName(self);
String[] splitName = split(droidName, '/');
if (splitName.length > 1)
{
droidName = "@" + droidName;
}
location holoOneLocation = (location)startLocation.clone();
boolean goodLocation = false;
for (int i = 0; i < 10; ++i)
{
holoOneLocation = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
if (isIdValid(holoOneLocation.cell))
{
if (isValidInteriorLocation(holoOneLocation))
{
goodLocation = true;
break;
}
}
else
{
goodLocation = true;
break;
}
}
obj_id holo_01 = create.object(template, holoOneLocation, false);
attachScript(holo_01, "ai.dancing_droid");
setInvulnerable(holo_01, true);
setHologramType(holo_01, HOLOGRAM_TYPE1_QUALITY3);
setName(holo_01, droidName);
location holoTwoLocation = (location)startLocation.clone();
goodLocation = false;
for (int i = 0; i < 10; ++i)
{
holoTwoLocation = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
if (isIdValid(holoTwoLocation.cell))
{
if (isValidInteriorLocation(holoTwoLocation) && !holoTwoLocation.equals(holoOneLocation))
{
goodLocation = true;
break;
}
}
else if (!holoTwoLocation.equals(holoOneLocation))
{
goodLocation = true;
break;
}
}
obj_id holo_02 = create.object(template, holoTwoLocation, false);
attachScript(holo_02, "ai.dancing_droid");
setInvulnerable(holo_02, true);
setHologramType(holo_02, HOLOGRAM_TYPE1_QUALITY3);
setName(holo_02, droidName);
utils.setScriptVar(self, "music.stillPlaying", 1);
utils.setScriptVar(holo_01, "music.stillPlaying", 1);
utils.setScriptVar(holo_02, "music.stillPlaying", 1);
utils.setScriptVar(self, "dancingDroid.startLocation", startLocation);
utils.setScriptVar(holo_01, "dancingDroid.startLocation", holoOneLocation);
utils.setScriptVar(holo_02, "dancingDroid.startLocation", holoTwoLocation);
setObjVar(pcd, "dancingDroid.soundObject", soundObject);
setObjVar(pcd, "dancingDroid.holo_02", holo_02);
setObjVar(pcd, "dancingDroid.holo_01", holo_01);
createTriggerVolume(TRIG_VOLUME, TRIG_RADIUS, PROMISCUOUS);
messageTo(self, "clearDancingDroidScriptVar", null, 165, false);
messageTo(self, "moveDancingDroidNewLocation", null, 1, false);
messageTo(holo_01, "moveDancingDroidNewLocation", null, 2, false);
messageTo(holo_02, "moveDancingDroidNewLocation", null, 3, false);
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int OnDestroy(obj_id self) throws InterruptedException
{
obj_id petControlDevice = callable.getCallableCD(self);
if (isIdValid(petControlDevice))
{
if (hasObjVar(petControlDevice, "dancingDroid.soundObject"))
{
obj_id soundObject = getObjIdObjVar(petControlDevice, "dancingDroid.soundObject");
dictionary dict = new dictionary();
dict.put("pcd", petControlDevice);
messageTo(soundObject, "destroyDancingDroidSoundObject", dict, 0, true);
}
obj_id pcd = callable.getCallableCD(self);
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (volumeName.equals(TRIG_VOLUME))
{
if (isPlayer(breacher) && getMaster(self) == breacher)
{
obj_id pcd = callable.getCallableCD(self);
obj_id soundObject = getObjIdObjVar(pcd, "dancingDroid.soundObject");
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.soundObject");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
destroyObject(soundObject);
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
}
return SCRIPT_CONTINUE;
}
public int clearDancingDroidScriptVar(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, "music.stillPlaying"))
{
obj_id pcd = callable.getCallableCD(self);
obj_id soundObject = getObjIdObjVar(pcd, "dancingDroid.soundObject");
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
removeObjVar(pcd, "dancingDroid.soundObject");
destroyObject(soundObject);
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
return SCRIPT_CONTINUE;
}
public int moveDancingDroidStartLocation(obj_id self, dictionary params) throws InterruptedException
{
location startLocation = getLocation(self);
if (utils.hasScriptVar(self, "dancingDroid.startLocation"))
{
startLocation = utils.getLocationScriptVar(self, "dancingDroid.startLocation");
}
pathTo(self, startLocation);
if (utils.hasScriptVar(self, "music.stillPlaying"))
{
messageTo(self, "moveDancingDroidNewLocation", null, 3, false);
}
else
{
utils.removeScriptVar(self, "dancingDroid.startLocation");
}
return SCRIPT_CONTINUE;
}
public int moveDancingDroidNewLocation(obj_id self, dictionary params) throws InterruptedException
{
location startLocation = getLocation(self);
if (utils.hasScriptVar(self, "dancingDroid.startLocation"))
{
startLocation = utils.getLocationScriptVar(self, "dancingDroid.startLocation");
}
if (utils.hasScriptVar(self, "music.stillPlaying"))
{
location moveToLoc = (location)startLocation.clone();
boolean goodLocation = false;
for (int i = 0; i < 10; ++i)
{
moveToLoc = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
if (isIdValid(moveToLoc.cell))
{
if (isValidInteriorLocation(moveToLoc))
{
goodLocation = true;
break;
}
}
else
{
goodLocation = true;
break;
}
}
pathTo(self, moveToLoc);
}
messageTo(self, "moveDancingDroidStartLocation", null, 2, false);
return SCRIPT_CONTINUE;
}
public int destroyDancingDroidSoundObject(obj_id self, dictionary params) throws InterruptedException
{
if (params == null || params.isEmpty())
{
return SCRIPT_CONTINUE;
}
obj_id pcd = params.getObjId("pcd");
if (destroyObject(self))
{
messageTo(pcd, "dancingDroidSoundObjectDestroyed", null, 1, false);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,318 +0,0 @@
include library.callable;
include library.create;
include library.utils;
//constants
const string_id SID_DANCE = new string_id("pet/pet_menu", "dance");
const string TRIG_VOLUME = "droid_trig_volume";
const int TRIG_RADIUS = 20;
const boolean PROMISCUOUS = true;
trigger OnObjectMenuRequest(obj_id player, menu_info item)
{
if(getMaster(self) != player)
return SCRIPT_CONTINUE;
//verify that the droid is not still playing music and dancing
if(!utils.hasScriptVar(self, "music.stillPlaying"))
item.addRootMenu(menu_info_types.SERVER_MENU1, SID_DANCE);
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuSelect(obj_id player, int item)
{
if(getMaster(self) != player)
return SCRIPT_CONTINUE;
if(item == menu_info_types.SERVER_MENU1 && !utils.hasScriptVar(self, "music.stillPlaying"))
{
//get current location
location startLocation = getLocation(self);
//get the pcd
obj_id pcd = callable.getCallableCD(self);
//start music
obj_id soundObject = createObject("object/soundobject/soundobject_figrin_dan_band_droid.iff", startLocation);
//make holo pets
string template = getTemplateName(self);
string droidName = getName(self);
//determine if we are going to use the default name or the name the player has given his droid
string[] splitName = split(droidName, '/');
if(splitName.length > 1)
droidName = "@" + droidName;
//use current location as default
location holoOneLocation = (location)startLocation.clone();
boolean goodLocation = false;
//loop 10 times looking for a good location in a circle around the droid
for(int i = 0; i < 10; ++i)
{
holoOneLocation = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
//if we are in an interior we want to verify we dont go out of bounds
if(isIdValid(holoOneLocation.cell))
{
if(isValidInteriorLocation(holoOneLocation))
{
goodLocation = true;
break;
}
}
else
{
goodLocation = true;
break;
}
}
//create hologram 1
obj_id holo_01 = create.object(template, holoOneLocation, false);
//attach dancing droid script
attachScript(holo_01, "ai.dancing_droid");
//make invulnerable
setInvulnerable(holo_01, true);
//make it a hologram
setHologramType(holo_01, HOLOGRAM_TYPE1_QUALITY3);
//set the name
setName(holo_01, droidName);
//start finding location for hologram 2
location holoTwoLocation = (location)startLocation.clone();
goodLocation = false;
//loop 10 times looking for a suitable location
for(int i = 0; i < 10; ++i)
{
holoTwoLocation = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
//if we are inside we want to make sure we dont go thru a wall and we are not on top of the other hologram
if(isIdValid(holoTwoLocation.cell))
{
if(isValidInteriorLocation(holoTwoLocation) && holoTwoLocation != holoOneLocation)
{
goodLocation = true;
break;
}
}
else if(holoTwoLocation != holoOneLocation)
{
goodLocation = true;
break;
}
}
//create hologram 2
obj_id holo_02 = create.object(template, holoTwoLocation, false);
//attach dancing droid script
attachScript(holo_02, "ai.dancing_droid");
//make invulnerable
setInvulnerable(holo_02, true);
//make into hologram
setHologramType(holo_02, HOLOGRAM_TYPE1_QUALITY3);
//set the name
setName(holo_02, droidName);
//set still playing scriptvars on dancers
utils.setScriptVar(self, "music.stillPlaying", 1);
utils.setScriptVar(holo_01, "music.stillPlaying", 1);
utils.setScriptVar(holo_02, "music.stillPlaying", 1);
//set starting locations on dancers
utils.setScriptVar(self, "dancingDroid.startLocation", startLocation);
utils.setScriptVar(holo_01, "dancingDroid.startLocation", holoOneLocation);
utils.setScriptVar(holo_02, "dancingDroid.startLocation", holoTwoLocation);
//set the obj_ids of the dancers on the pcd
setObjVar(pcd, "dancingDroid.soundObject", soundObject);
setObjVar(pcd, "dancingDroid.holo_02", holo_02);
setObjVar(pcd, "dancingDroid.holo_01", holo_01);
//create our out-of-bounds trigger volume
createTriggerVolume(TRIG_VOLUME, TRIG_RADIUS, PROMISCUOUS);
//send our ending messageTo, arrives around the time of the end of the song
messageTo(self, "clearDancingDroidScriptVar", null, 165, false);
//tell our dancers to start dancing
messageTo(self, "moveDancingDroidNewLocation", null, 1, false);
messageTo(holo_01, "moveDancingDroidNewLocation", null, 2, false);
messageTo(holo_02, "moveDancingDroidNewLocation", null, 3, false);
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered(string volumeName, obj_id breacher)
{
return SCRIPT_CONTINUE;
}
trigger OnDestroy()
{
//make sure sound object is removed from world
obj_id petControlDevice = callable.getCallableCD(self);
if(isIdValid(petControlDevice))
{
if(hasObjVar(petControlDevice, "dancingDroid.soundObject"))
{
obj_id soundObject = getObjIdObjVar(petControlDevice, "dancingDroid.soundObject");
dictionary dict = new dictionary();
dict.put("pcd", petControlDevice);
messageTo(soundObject, "destroyDancingDroidSoundObject", dict, 0, true);
}
obj_id pcd = callable.getCallableCD(self);
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited(string volumeName, obj_id breacher)
{
//if it is our out-of-bounds trigger volume, we want to clean up the sounds and holograms
if(volumeName.equals(TRIG_VOLUME))
{
if(isPlayer(breacher) && getMaster(self) == breacher)
{
obj_id pcd = callable.getCallableCD(self);
obj_id soundObject = getObjIdObjVar(pcd, "dancingDroid.soundObject");
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.soundObject");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
destroyObject(soundObject);
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
}
return SCRIPT_CONTINUE;
}
messageHandler clearDancingDroidScriptVar()
{
//song should be over, time to clear up dancers
if(utils.hasScriptVar(self, "music.stillPlaying"))
{
obj_id pcd = callable.getCallableCD(self);
obj_id soundObject = getObjIdObjVar(pcd, "dancingDroid.soundObject");
obj_id holo_01 = getObjIdObjVar(pcd, "dancingDroid.holo_01");
obj_id holo_02 = getObjIdObjVar(pcd, "dancingDroid.holo_02");
utils.removeScriptVar(self, "music.stillPlaying");
removeObjVar(pcd, "dancingDroid.holo_01");
removeObjVar(pcd, "dancingDroid.holo_02");
removeObjVar(pcd, "dancingDroid.soundObject");
destroyObject(soundObject);
destroyObject(holo_01);
destroyObject(holo_02);
removeTriggerVolume(TRIG_VOLUME);
}
return SCRIPT_CONTINUE;
}
//moves our dancers back to their original location
messageHandler moveDancingDroidStartLocation()
{
location startLocation = getLocation(self);
//try to get the scriptvar with our starting location
if(utils.hasScriptVar(self, "dancingDroid.startLocation"))
{
startLocation = utils.getLocationScriptVar(self, "dancingDroid.startLocation");
}
//move to our start location
pathTo(self, startLocation);
//if we still are playing music and dancing, we need to message to our next location
//otherwise we need to clear ourselves of junk scriptvars
if(utils.hasScriptVar(self, "music.stillPlaying"))
{
messageTo(self, "moveDancingDroidNewLocation", null, 3, false);
}
else
utils.removeScriptVar(self, "dancingDroid.startLocation");
return SCRIPT_CONTINUE;
}
//moves our dancers to our new location
messageHandler moveDancingDroidNewLocation()
{
//use our start location is our temp location
location startLocation = getLocation(self);
if(utils.hasScriptVar(self, "dancingDroid.startLocation"))
{
startLocation = utils.getLocationScriptVar(self, "dancingDroid.startLocation");
}
//if music is still playing then we can move
if(utils.hasScriptVar(self, "music.stillPlaying"))
{
location moveToLoc = (location)startLocation.clone();
boolean goodLocation = false;
for(int i = 0; i < 10; ++i)
{
moveToLoc = utils.getRandomLocationInRing(startLocation, 1.0f, 2.0f);
if(isIdValid(moveToLoc.cell))
{
if(isValidInteriorLocation(moveToLoc))
{
goodLocation = true;
break;
}
}
else
{
goodLocation = true;
break;
}
}
pathTo(self, moveToLoc);
//make them wiggle
}
messageTo(self, "moveDancingDroidStartLocation", null, 2, false);
return SCRIPT_CONTINUE;
}
//to be used when the object might persist and needs to be removed.
messageHandler destroyDancingDroidSoundObject()
{
if(params == null || params.isEmpty())
return SCRIPT_CONTINUE;
obj_id pcd = params.getObjId("pcd");
if(destroyObject(self))
messageTo(pcd, "dancingDroidSoundObjectDestroyed", null, 1, false);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,122 @@
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.factions;
import script.library.chat;
import script.ai.ai_combat;
import script.library.pet_lib;
import script.library.colors;
import script.library.group;
import script.library.healing;
public class droid extends script.base_script
{
public droid()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnLoiterWaiting(obj_id self, modifiable_float time) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (newBehavior <= oldBehavior)
{
if (doCalmerBehavior(self, newBehavior, oldBehavior) == SCRIPT_CONTINUE)
{
return SCRIPT_CONTINUE;
}
else
{
return SCRIPT_OVERRIDE;
}
}
else
{
if (doAgitatedBehavior(self, newBehavior, oldBehavior) == SCRIPT_CONTINUE)
{
return SCRIPT_CONTINUE;
}
else
{
return SCRIPT_OVERRIDE;
}
}
}
public int doCalmerBehavior(obj_id npc, int newBehavior, int oldBehavior) throws InterruptedException
{
switch (newBehavior)
{
case BEHAVIOR_CALM:
messageTo(npc, "resumeDefaultCalmBehavior", null, 5, false);
break;
case BEHAVIOR_ALERT:
break;
case BEHAVIOR_THREATEN:
break;
case BEHAVIOR_FLEE:
break;
case BEHAVIOR_PANIC:
break;
case BEHAVIOR_ATTACK:
break;
case BEHAVIOR_FRENZY:
break;
default:
break;
}
return SCRIPT_OVERRIDE;
}
public int doAgitatedBehavior(obj_id npc, int newBehavior, int oldBehavior) throws InterruptedException
{
switch (newBehavior)
{
case BEHAVIOR_CALM:
break;
case BEHAVIOR_ALERT:
break;
case BEHAVIOR_THREATEN:
break;
case BEHAVIOR_FLEE:
break;
case BEHAVIOR_PANIC:
break;
case BEHAVIOR_ATTACK:
break;
case BEHAVIOR_FRENZY:
break;
default:
break;
}
return SCRIPT_OVERRIDE;
}
public int lairThreatened(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
}
@@ -1,142 +0,0 @@
include library.ai_lib;
include library.factions;
include library.chat;
include ai.ai_combat;
include library.pet_lib;
include library.colors;
include library.group;
include library.healing;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
//droids ignore everything
return SCRIPT_OVERRIDE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
//droids ignore everything:
return SCRIPT_OVERRIDE;
}
trigger OnLoiterWaiting(modifiable_float time)
{
return SCRIPT_OVERRIDE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( ai_lib.isAiDead( self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;//you probably don't want to do anything if you are in combat
//don't put code in this trigger. Put it in doCalmerBehavior or doAgitated behavior
// this is hard enough to read already:
if ( newBehavior <= oldBehavior )
{
if ( doCalmerBehavior( self, newBehavior, oldBehavior ) == SCRIPT_CONTINUE)
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
else
{
if ( doAgitatedBehavior( self, newBehavior, oldBehavior) == SCRIPT_CONTINUE )
return SCRIPT_CONTINUE;
else
return SCRIPT_OVERRIDE;
}
}
int doCalmerBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are now calming down.
//return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//going from More Agitated to Calm
messageTo( npc, "resumeDefaultCalmBehavior", null, 5, false );
break;
case BEHAVIOR_ALERT:
//going from More Agitated to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from More Agitated to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from More Agitated to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//going from More Agitated to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from More Agitated to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//This is impossible.
break;
default :
// This is an error
break;
}
return SCRIPT_OVERRIDE;
}
int doAgitatedBehavior( obj_id npc, int newBehavior, int oldBehavior )
{
//You are becoming more Fearful or more Angry
// return SCRIPT_OVERRIDE to stomp on default behaviors:
switch ( newBehavior )
{
case BEHAVIOR_CALM:
//this is impossible
break;
case BEHAVIOR_ALERT:
//going from Calmer to Alert
// Your code goes here.
break;
case BEHAVIOR_THREATEN:
//going from Calmer to Threaten
// Your code goes here.
break;
case BEHAVIOR_FLEE:
//going from Calmer to Flee
// Your code goes here.
break;
case BEHAVIOR_PANIC:
//Going from Calmer to Panic
// Your code goes here.
break;
case BEHAVIOR_ATTACK:
//Going from Calmer to Attack
// Your code goes here.
break;
case BEHAVIOR_FRENZY:
//going from Calmer to Frenzy
break;
default :
// This is an error
break;
}
return SCRIPT_OVERRIDE;
}
/* -----------------8/1/2002 9:42PM------------------
* COMBAT:
* --------------------------------------------------*/
messageHandler lairThreatened()
{
return SCRIPT_OVERRIDE;
}
@@ -0,0 +1,32 @@
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;
public class equip_weapon extends script.base_script
{
public equip_weapon()
{
}
public int OnAttach(obj_id self) throws InterruptedException
{
if (!aiUsingPrimaryWeapon(self))
{
aiEquipPrimaryWeapon(self);
}
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
if (!aiUsingPrimaryWeapon(self))
{
aiEquipPrimaryWeapon(self);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,18 +0,0 @@
trigger OnAttach()
{
if(!aiUsingPrimaryWeapon(self))
{
aiEquipPrimaryWeapon(self);
}
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
if(!aiUsingPrimaryWeapon(self))
{
aiEquipPrimaryWeapon(self);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,409 @@
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.buff;
import script.library.callable;
import script.library.pet_lib;
import script.library.utils;
public class familiar extends script.base_script
{
public familiar()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public static final String MESSAGE_PET_ID = "petId";
public static final String MENU_FILE = "pet/pet_menu";
public static final boolean debug = false;
public static final int FALSE = 0;
public static final int TRUE = 1;
public static final int FAMILIAR_TRICK_1 = 1;
public static final int FAMILIAR_TRICK_2 = 2;
public static final int FAMILIAR_TRICK_3 = 3;
public static final int FAMILIAR_TRICK_4 = 4;
public static final int FAMILIAR_TRICK_5 = 5;
public static final int FAMILIAR_TRICK_6 = 6;
public void doFamiliarTrick(obj_id pet, int trickNum) throws InterruptedException
{
obj_id petControl = callable.getCallableCD(pet);
String creatureName = getStringObjVar(petControl, "pet.creatureName");
if (creatureName.startsWith("loveday_romance_seeker_familiar"))
{
return;
}
if (creatureName.equals("vr_mouse_droid"))
{
trickNum = trickNum + 2;
}
else if (creatureName.equals("loveday_ewok_cupid_familiar"))
{
trickNum = trickNum + 4;
}
obj_id master = getMaster(pet);
switch (trickNum)
{
case FAMILIAR_TRICK_1:
doAnimationAction(pet, "trick_1");
break;
case FAMILIAR_TRICK_2:
doAnimationAction(pet, "trick_2");
break;
case FAMILIAR_TRICK_3:
if (isIdValid(master))
{
playClientEffectObj(master, "clienteffect/droid_effect_fog_machine.cef", pet, "");
playClientEffectObj(master, "clienteffect/droid_vocal/mouse_vocalize.cef", pet, "");
}
break;
case FAMILIAR_TRICK_4:
if (isIdValid(master))
{
playClientEffectObj(master, "clienteffect/npe_droid_static.cef", pet, "");
playClientEffectObj(master, "sound/item_electronics_break.snd", pet, "");
}
break;
case FAMILIAR_TRICK_5:
String[] anims_01 =
{
"stretch",
"bow",
"wave_item"
};
int chance_01 = rand(0, anims_01.length - 1);
doAnimationAction(pet, anims_01[chance_01]);
break;
case FAMILIAR_TRICK_6:
String[] anims_02 =
{
"startle",
"goodbye",
"shrug"
};
int chance_02 = rand(0, anims_02.length - 1);
doAnimationAction(pet, anims_02[chance_02]);
break;
}
return;
}
public int doFamiliarTrick(obj_id self, dictionary params) throws InterruptedException
{
obj_id pet = params.getObjId("pet");
int trickNum = params.getInt("trickNum");
boolean heartBeat = params.getBoolean("heartBeat");
if (!isIdValid(pet))
{
return SCRIPT_CONTINUE;
}
obj_id petControl = callable.getCallableCD(pet);
if (!isIdValid(petControl))
{
return SCRIPT_CONTINUE;
}
String creatureName = getStringObjVar(petControl, "pet.creatureName");
if (creatureName == null || creatureName.length() <= 0)
{
return SCRIPT_CONTINUE;
}
if (creatureName.startsWith("loveday_romance_seeker_familiar") || hasObjVar(petControl, "familiar_noTricks"))
{
return SCRIPT_CONTINUE;
}
doFamiliarTrick(pet, trickNum);
if (heartBeat)
{
int whichTrick = rand(1, 2);
dictionary trickData = new dictionary();
switch (whichTrick)
{
case 1:
trickData.put("trickNum", FAMILIAR_TRICK_1);
break;
case 2:
trickData.put("trickNum", FAMILIAR_TRICK_2);
break;
}
trickData.put("pet", pet);
int trickDelay = rand(300, 480);
trickData.put("heartBeat", true);
messageTo(pet, "doFamiliarTrick", trickData, trickDelay, false);
}
return SCRIPT_CONTINUE;
}
public int OnAttach(obj_id self) throws InterruptedException
{
setObjVar(self, "alreadyTamed", true);
messageTo(self, "handleSetupPet", null, 3, false);
return SCRIPT_CONTINUE;
}
public boolean applyBuff(obj_id pet) throws InterruptedException
{
obj_id master = getMaster(pet);
if (!isIdValid(master))
{
destroyObject(pet);
return false;
}
String nameBuff = "";
int levelUpBuff = 1;
obj_id petControl = callable.getCallableCD(pet);
String creatureName = getStringObjVar(petControl, "pet.creatureName");
int row = dataTableSearchColumnForString(creatureName, "familiar_name", "datatables/familiar/familiar_buff.iff");
if (row < 0)
{
return false;
}
nameBuff = dataTableGetString("datatables/familiar/familiar_buff.iff", row, "buff_name");
levelUpBuff = dataTableGetInt("datatables/familiar/familiar_buff.iff", row, "level_up");
if (nameBuff.length() > 0)
{
if (levelUpBuff == 1)
{
int level = getLevel(master) / 10;
if (level < 1)
{
level = 1;
}
if (level > 8)
{
level = 8;
}
nameBuff += level;
}
buff.applyBuff(master, nameBuff);
}
return true;
}
public void removePetBuff(obj_id master) throws InterruptedException
{
int numbuff = buff.getBuffOnTargetFromGroup(master, "vr_familiar");
buff.applyBuff(master, numbuff, 3600f);
return;
}
public void repackPet(obj_id master, obj_id pet) throws InterruptedException
{
if (isIdValid(master))
{
removePetBuff(master);
}
obj_id petControlDevice = callable.getCallableCD(pet);
utils.setScriptVar(pet, "stored", true);
dictionary messageData = new dictionary();
messageData.put(MESSAGE_PET_ID, pet);
if (petControlDevice.isLoaded() && exists(petControlDevice))
{
sendDirtyObjectMenuNotification(petControlDevice);
}
if (destroyObject(pet))
{
messageTo(petControlDevice, "handleRemoveCurrentPet", messageData, 1, false);
}
return;
}
public int handleSetupPet(obj_id self, dictionary params) throws InterruptedException
{
applySkillStatisticModifier(self, "slope_move", 100);
obj_id master = getMaster(self);
if (!isIdValid(master))
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
setOwner(utils.getInventoryContainer(self), master);
setObjVar(master, "familiar", self);
pet_lib.addToPetList(master, self);
if (!pet_lib.findMaster(self))
{
messageTo(self, "handleLostMaster", null, 1800, false);
}
final boolean promiscuous = true;
final float alertRadius = 128.0f;
createTriggerVolume(ai_lib.ALERT_VOLUME_NAME, alertRadius, promiscuous);
messageTo(self, "cleanupCheck", null, 300, false);
applyBuff(self);
ai_lib.aiFollow(self, master, 3f, 6f);
int whichTrick = rand(1, 2);
dictionary trickData = new dictionary();
switch (whichTrick)
{
case 1:
trickData.put("trickNum", FAMILIAR_TRICK_1);
break;
case 2:
trickData.put("trickNum", FAMILIAR_TRICK_2);
break;
}
trickData.put("pet", self);
trickData.put("heartBeat", true);
int trickDelay = rand(300, 480);
messageTo(self, "doFamiliarTrick", trickData, trickDelay, false);
return SCRIPT_CONTINUE;
}
public int cleanupCheck(obj_id self, dictionary params) throws InterruptedException
{
if (!pet_lib.findMaster(self))
{
destroyObject(self);
}
messageTo(self, "cleanupCheck", null, 300, false);
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME) && breacher == getMaster(self))
{
repackPet(breacher, self);
}
return SCRIPT_CONTINUE;
}
public int OnDetach(obj_id self) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (!isIdValid(master))
{
removePetBuff(master);
}
pet_lib.removeFromPetList(self);
removeObjVar(self, "ai.pet");
if (!ai_lib.isAiDead(self))
{
ai_lib.setDefaultCalmBehavior(self, ai_lib.BEHAVIOR_WANDER);
}
setOwner(utils.getInventoryContainer(self), obj_id.NULL_ID);
setObjVar(self, "alreadyTrained", true);
return SCRIPT_CONTINUE;
}
public int OnDestroy(obj_id self) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
removeObjVar(master, "familiar");
removePetBuff(master);
}
if (hasObjVar(self, "pet.controlDestroyed") || !isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id petControlDevice = callable.getCallableCD(self);
if (isIdValid(master))
{
pet_lib.removeFromPetList(self);
}
if (isIdValid(petControlDevice) && petControlDevice.isLoaded())
{
obj_id currentPet = callable.getCDCallable(petControlDevice);
if (isIdValid(currentPet) && currentPet == self)
{
pet_lib.savePetInfo(self, petControlDevice);
setObjVar(petControlDevice, "pet.timeStored", getGameTime());
callable.setCDCallable(petControlDevice, null);
}
}
return SCRIPT_CONTINUE;
}
public int OnFollowWaiting(obj_id self, obj_id target) throws InterruptedException
{
pet_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
public int OnFollowMoving(obj_id self, obj_id target) throws InterruptedException
{
if (getLocomotion(self) != LOCOMOTION_RUNNING)
{
}
setMovementRun(self);
pet_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
public int handlePackRequest(obj_id self, dictionary params) throws InterruptedException
{
if (!isIdValid(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master))
{
removePetBuff(master);
}
obj_id petControlDevice = callable.getCallableCD(self);
utils.setScriptVar(self, "stored", true);
dictionary messageData = new dictionary();
messageData.put(MESSAGE_PET_ID, self);
if (petControlDevice.isLoaded() && exists(petControlDevice))
{
sendDirtyObjectMenuNotification(petControlDevice);
}
if (destroyObject(self))
{
messageTo(petControlDevice, "handleRemoveCurrentPet", messageData, 1, false);
}
else
{
debugServerConsoleMsg(null, "+++ pet.messageHandler handlePackRequest +++ WARNINGWARNING - FAILED TO DESTROY SELF");
}
return SCRIPT_CONTINUE;
}
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info mi) throws InterruptedException
{
if (isDead(self) || ai_lib.aiIsDead(player))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (player != getMaster(self))
{
return SCRIPT_CONTINUE;
}
mi.addRootMenu(menu_info_types.PET_STORE, new string_id(MENU_FILE, "menu_store"));
return SCRIPT_CONTINUE;
}
public int OnObjectMenuSelect(obj_id self, obj_id player, int item) throws InterruptedException
{
if (ai_lib.aiIsDead(player))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (player != getMaster(self))
{
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.PET_STORE)
{
pet_lib.storePet(self, player);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,454 +0,0 @@
include library.ai_lib;
include library.buff;
include library.callable;
include library.pet_lib;
include library.utils;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
const string MESSAGE_PET_ID = "petId";
const string MENU_FILE = "pet/pet_menu";
const boolean debug = false;
const int FALSE = 0;
const int TRUE = 1;
const int FAMILIAR_TRICK_1 =1;
const int FAMILIAR_TRICK_2 =2;
const int FAMILIAR_TRICK_3 =3;
const int FAMILIAR_TRICK_4 =4;
const int FAMILIAR_TRICK_5 =5;
const int FAMILIAR_TRICK_6 =6;
void doFamiliarTrick(obj_id pet, int trickNum)
{
// Droid does its own set of tricks
obj_id petControl = callable.getCallableCD(pet);
string creatureName = getStringObjVar(petControl, "pet.creatureName");
if ( creatureName.startsWith("loveday_romance_seeker_familiar") )
{
return;
}
if ( creatureName == "vr_mouse_droid" )
{
trickNum = trickNum +2;
}
else if ( creatureName == "loveday_ewok_cupid_familiar" )
{
trickNum = trickNum +4;
}
obj_id master = getMaster(pet);
switch (trickNum)
{
case FAMILIAR_TRICK_1 :
doAnimationAction(pet, "trick_1");
break;
case FAMILIAR_TRICK_2 :
doAnimationAction(pet, "trick_2");
break;
case FAMILIAR_TRICK_3 :
if(isIdValid(master))
{
playClientEffectObj(master, "clienteffect/droid_effect_fog_machine.cef", pet, "");
playClientEffectObj(master, "clienteffect/droid_vocal/mouse_vocalize.cef", pet, "");
}
break;
case FAMILIAR_TRICK_4 :
if(isIdValid(master))
{
playClientEffectObj(master, "clienteffect/npe_droid_static.cef", pet, "");
playClientEffectObj(master, "sound/item_electronics_break.snd", pet, "");
}
break;
case FAMILIAR_TRICK_5 :
string[] anims_01 = { "stretch", "bow", "wave_item" };
int chance_01 = rand(0, anims_01.length-1);
doAnimationAction(pet, anims_01[chance_01]);
break;
case FAMILIAR_TRICK_6 :
string[] anims_02 = { "startle", "goodbye", "shrug" };
int chance_02 = rand(0, anims_02.length-1);
doAnimationAction(pet, anims_02[chance_02]);
break;
}
return;
}
messageHandler doFamiliarTrick()
{
obj_id pet = params.getObjId("pet");
int trickNum = params.getInt("trickNum");
boolean heartBeat = params.getBoolean("heartBeat");
if ( !isIdValid(pet) )
{
return SCRIPT_CONTINUE;
}
obj_id petControl = callable.getCallableCD(pet);
if ( !isIdValid(petControl) )
{
return SCRIPT_CONTINUE;
}
string creatureName = getStringObjVar(petControl, "pet.creatureName");
if ( creatureName == null || creatureName.length() <= 0 )
{
return SCRIPT_CONTINUE;
}
if ( creatureName.startsWith("loveday_romance_seeker_familiar") || hasObjVar(petControl, "familiar_noTricks") )
{
return SCRIPT_CONTINUE;
}
doFamiliarTrick(pet, trickNum);
if(heartBeat)
{
int whichTrick = rand(1,2);
dictionary trickData = new dictionary();
switch (whichTrick)
{
case 1 :
trickData.put("trickNum", FAMILIAR_TRICK_1);
break;
case 2 :
trickData.put("trickNum", FAMILIAR_TRICK_2);
break;
}
trickData.put("pet", pet);
int trickDelay = rand(300,480);
trickData.put("heartBeat", true);
messageTo(pet, "doFamiliarTrick", trickData, trickDelay, false);
}
return SCRIPT_CONTINUE;
}
trigger OnAttach()
{
setObjVar(self, "alreadyTamed", true);
messageTo(self, "handleSetupPet", null, 3, false);
return SCRIPT_CONTINUE;
}
boolean applyBuff(obj_id pet)
{
obj_id master = getMaster(pet);
if(!isIdValid(master))
{
destroyObject(pet);
return false;
}
string nameBuff = "";
int levelUpBuff = 1;
obj_id petControl = callable.getCallableCD(pet);
string creatureName = getStringObjVar(petControl, "pet.creatureName");
int row = dataTableSearchColumnForString(creatureName, "familiar_name", "datatables/familiar/familiar_buff.iff");
if(row < 0)
{
//log
return false;
}
nameBuff = dataTableGetString("datatables/familiar/familiar_buff.iff", row, "buff_name");
levelUpBuff = dataTableGetInt("datatables/familiar/familiar_buff.iff", row, "level_up");
if(nameBuff.length() > 0)
{
if (levelUpBuff == 1)
{
int level = getLevel(master)/10;
if(level <1)
{
level = 1;
}
if(level >8)
{
level = 8;
}
nameBuff+=level;
}
buff.applyBuff(master, nameBuff);
}
return true;
}
void removePetBuff(obj_id master)
{
// Commenting out the Travis-hack
//if (true)
// return;
int numbuff = buff.getBuffOnTargetFromGroup(master, "vr_familiar");
buff.applyBuff(master, numbuff, 3600f);
return;
}
void repackPet(obj_id master, obj_id pet)
{
if(isIdValid(master))
{
removePetBuff(master);
}
//-- Destroy the object.
obj_id petControlDevice = callable.getCallableCD(pet);
utils.setScriptVar(pet, "stored", true);
// Create dictionary for message.
dictionary messageData = new dictionary();
messageData.put(MESSAGE_PET_ID, pet);
if(petControlDevice.isLoaded() && exists(petControlDevice))
sendDirtyObjectMenuNotification (petControlDevice);
if(destroyObject(pet))
{
messageTo(petControlDevice, "handleRemoveCurrentPet", messageData, 1, false);
}
return;
}
messageHandler handleSetupPet()
{
// Give em max terrain negotiation so they keep up with players - PMW
applySkillStatisticModifier(self, "slope_move", 100);
obj_id master = getMaster(self);
if(!isIdValid(master))
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
setOwner(utils.getInventoryContainer(self), master);
setObjVar(master, "familiar", self);
pet_lib.addToPetList(master, self);
if(!pet_lib.findMaster(self))
messageTo(self, "handleLostMaster", null, 1800, false);
//Setup trigger volume
const boolean promiscuous = true;
const float alertRadius = 128.0f;
createTriggerVolume(ai_lib.ALERT_VOLUME_NAME, alertRadius, promiscuous);
messageTo(self, "cleanupCheck", null, 300, false);
applyBuff(self);
ai_lib.aiFollow(self, master, 3f, 6f);
int whichTrick = rand(1,2);
dictionary trickData = new dictionary();
switch (whichTrick)
{
case 1 :
trickData.put("trickNum", FAMILIAR_TRICK_1);
break;
case 2 :
trickData.put("trickNum", FAMILIAR_TRICK_2);
break;
}
trickData.put("pet", self);
trickData.put("heartBeat", true);
int trickDelay = rand(300,480);
messageTo(self, "doFamiliarTrick", trickData, trickDelay, false);
return SCRIPT_CONTINUE;
}
messageHandler cleanupCheck()
{
if(!pet_lib.findMaster(self))
{
destroyObject(self);
}
messageTo(self, "cleanupCheck", null, 300, false);
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited(string volumeName, obj_id breacher)
{
if(!isMob(self))
return SCRIPT_CONTINUE;
if(volumeName == ai_lib.ALERT_VOLUME_NAME && breacher == getMaster(self))
{
repackPet(breacher, self);
}
return SCRIPT_CONTINUE;
}
trigger OnDetach()
{
if(!isMob(self))
return SCRIPT_CONTINUE;
obj_id master = getMaster(self);
if(!isIdValid(master))
{
removePetBuff(master);
}
pet_lib.removeFromPetList(self);
removeObjVar(self, "ai.pet");
if(!ai_lib.isAiDead(self))
ai_lib.setDefaultCalmBehavior(self, ai_lib.BEHAVIOR_WANDER);
setOwner(utils.getInventoryContainer(self), obj_id.NULL_ID);
setObjVar(self, "alreadyTrained", true);
return SCRIPT_CONTINUE;
}
trigger OnDestroy()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
removeObjVar(master, "familiar");
removePetBuff(master);
}
if(hasObjVar(self, "pet.controlDestroyed") || !isMob(self)) // Already handled control destroyed?
{
return SCRIPT_CONTINUE;
}
obj_id petControlDevice = callable.getCallableCD(self);
if(isIdValid(master))
{
pet_lib.removeFromPetList(self);
}
if(isIdValid(petControlDevice) && petControlDevice.isLoaded())
{
obj_id currentPet = callable.getCDCallable(petControlDevice);
if(isIdValid(currentPet) && currentPet == self)
{
pet_lib.savePetInfo(self, petControlDevice);
setObjVar(petControlDevice, "pet.timeStored", getGameTime());
callable.setCDCallable(petControlDevice, null);
}
}
return SCRIPT_CONTINUE;
}
trigger OnFollowWaiting(obj_id target)
{
pet_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
trigger OnFollowMoving(obj_id target)
{
if(getLocomotion(self) != LOCOMOTION_RUNNING);
setMovementRun(self);
pet_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
messageHandler handlePackRequest()
{
if(!isIdValid(self))
return SCRIPT_CONTINUE; //I have already been destroyed by another script.
obj_id master = getMaster(self);
if(isIdValid(master))
{
removePetBuff(master);
}
//-- Destroy the object.
obj_id petControlDevice = callable.getCallableCD(self);
utils.setScriptVar(self, "stored", true);
// Create dictionary for message.
dictionary messageData = new dictionary();
messageData.put(MESSAGE_PET_ID, self);
if(petControlDevice.isLoaded() && exists(petControlDevice))
sendDirtyObjectMenuNotification (petControlDevice);
if(destroyObject(self))
{
messageTo(petControlDevice, "handleRemoveCurrentPet", messageData, 1, false);
}
else
debugServerConsoleMsg(null, "+++ pet.messageHandler handlePackRequest +++ WARNINGWARNING - FAILED TO DESTROY SELF");
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuRequest(obj_id player, menu_info mi)
{
if ( isDead(self) || ai_lib.aiIsDead(player) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( !isMob(self) )
return SCRIPT_CONTINUE;
if ( player != getMaster( self ) )
return SCRIPT_CONTINUE;
mi.addRootMenu (menu_info_types.PET_STORE, new string_id(MENU_FILE,"menu_store"));
return SCRIPT_CONTINUE;
}
trigger OnObjectMenuSelect(obj_id player, int item)
{
////debugSpeakMsg( self, "performing chechs");
if ( ai_lib.aiIsDead(player) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( !isMob(self) )
return SCRIPT_CONTINUE;
if ( player != getMaster(self) )
return SCRIPT_CONTINUE;
if ( item == menu_info_types.PET_STORE )
{
pet_lib.storePet( self, player );
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,46 @@
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.buff;
import script.library.callable;
import script.library.pet_lib;
public class hand_sampling extends script.base_script
{
public hand_sampling()
{
}
public static final int BUFF_TICK_TIME = 20;
public int OnInitialize(obj_id self) throws InterruptedException
{
messageTo(self, "handlerApplySamplerBuff", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "handlerApplySamplerBuff", null, 3, false);
return SCRIPT_CONTINUE;
}
public int handlerApplySamplerBuff(obj_id self, dictionary params) throws InterruptedException
{
obj_id petControlDevice = callable.getCallableCD(self);
int powerLevel = getIntObjVar(petControlDevice, "ai.pet.powerLevel");
if (powerLevel >= pet_lib.OUT_OF_POWER)
{
messageTo(self, "handlerApplySamplerBuff", null, BUFF_TICK_TIME, false);
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
int buffValue = getIntObjVar(self, "module_data.sampling_power");
buff.applyBuff(master, "droid_hand_sample", 30, buffValue);
messageTo(self, "handlerApplySamplerBuff", null, BUFF_TICK_TIME, false);
return SCRIPT_CONTINUE;
}
}
@@ -1,44 +0,0 @@
include library.buff;
include library.callable;
include library.pet_lib;
//constants
const int BUFF_TICK_TIME = 20;
trigger OnInitialize()
{
messageTo(self, "handlerApplySamplerBuff", null, 3, false);
return SCRIPT_CONTINUE;
}
trigger OnAttach()
{
messageTo(self, "handlerApplySamplerBuff", null, 3, false);
return SCRIPT_CONTINUE;
}
messageHandler handlerApplySamplerBuff()
{
obj_id petControlDevice = callable.getCallableCD(self);
int powerLevel = getIntObjVar(petControlDevice, "ai.pet.powerLevel");
if(powerLevel >= pet_lib.OUT_OF_POWER)
{
messageTo(self, "handlerApplySamplerBuff", null, BUFF_TICK_TIME, false);
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
int buffValue = getIntObjVar(self, "module_data.sampling_power");
//buff.applyBuff(master, self, "droid_hand_sample");
buff.applyBuff(master, "droid_hand_sample", 30, buffValue);
messageTo(self, "handlerApplySamplerBuff", null, BUFF_TICK_TIME, false);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,60 @@
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.ai.ai_combat;
import script.library.attrib;
public class hunter extends script.base_script
{
public hunter()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public int OnAttach(obj_id self) throws InterruptedException
{
setAttributeInterested(self, attrib.HERBIVORE);
setAttributeInterested(self, attrib.CARNIVORE);
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange(self), true);
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (!isMob(breacher))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isAiDead(self) || ai_lib.isAiDead(breacher))
{
return SCRIPT_CONTINUE;
}
if (!ai_lib.isMonster(breacher))
{
return SCRIPT_CONTINUE;
}
startCombat(self, breacher);
return SCRIPT_CONTINUE;
}
}
@@ -1,41 +0,0 @@
include library.ai_lib;
include ai.ai_combat;
include library.attrib;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
trigger OnAttach()
{
setAttributeInterested( self, attrib.HERBIVORE );
setAttributeInterested( self, attrib.CARNIVORE );
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
createTriggerVolume( ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange( self ), true );
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
if ( !isMob( breacher) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( breacher == self )
return SCRIPT_CONTINUE;
if ( ai_lib.isAiDead(self) || ai_lib.isAiDead( breacher ))
return SCRIPT_CONTINUE;
if (!ai_lib.isMonster( breacher ))
return SCRIPT_CONTINUE;
startCombat( self, breacher );
return SCRIPT_CONTINUE;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,80 @@
package script.ai.imperial_presence;
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.ai.ai_combat;
import script.library.ai_lib;
import script.library.chat;
public class harass_backup extends script.base_script
{
public harass_backup()
{
}
public static final String STF = "imperial_presence/contraband_search";
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "goingToFight", null, 1, false);
int x = rand(300, 600);
messageTo(self, "cleanUp", null, x, false);
return SCRIPT_CONTINUE;
}
public int goingToFight(obj_id self, dictionary params) throws InterruptedException
{
location goFight = getLocationObjVar(self, "whereToFight");
goFight.x = goFight.x + (rand(-5, 5));
ai_lib.aiPathTo(self, goFight);
setMovementRun(self);
addLocationTarget("fight", goFight, 1);
return SCRIPT_CONTINUE;
}
public int OnArrivedAtLocation(obj_id self, String name) throws InterruptedException
{
if (name.equals("fight"))
{
chat.setAngryMood(self);
if (hasObjVar(self, "leader"))
{
if (hasObjVar(self, "jedi"))
{
chat.chat(self, new string_id(STF, "containment_team_jedi_" + getStringObjVar(self, "faction")));
}
else
{
chat.chat(self, new string_id(STF, "containment_team_" + getStringObjVar(self, "faction")));
}
}
obj_id attacker = getObjIdObjVar(self, "whoToFight");
startCombat(self, attacker);
}
if (name.equals("done"))
{
messageTo(self, "leaveWorld", null, 7, false);
}
return SCRIPT_CONTINUE;
}
public int cleanUp(obj_id self, dictionary params) throws InterruptedException
{
location home = getLocationObjVar(self, "home");
ai_lib.aiPathTo(self, home);
addLocationTarget("done", home, 1);
messageTo(self, "handleBadLeaving", null, 120, false);
return SCRIPT_CONTINUE;
}
public int leaveWorld(obj_id self, dictionary params) throws InterruptedException
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
public int handleBadLeaving(obj_id self, dictionary params) throws InterruptedException
{
messageTo(self, "leaveWorld", null, 7, false);
return SCRIPT_CONTINUE;
}
}
@@ -1,94 +0,0 @@
include ai.ai_combat;
include library.ai_lib;
include library.chat;
const string STF = "imperial_presence/contraband_search";
//------------------------------------------------
// OnAttach
//------------------------------------------------
trigger OnAttach()
{
messageTo( self, "goingToFight", null, 1, false );
int x = rand( 300, 600 );
messageTo( self, "cleanUp", null, x, false );
return SCRIPT_CONTINUE;
}
//------------------------------------------------
// goingToFight
//------------------------------------------------
messageHandler goingToFight()
{
location goFight = getLocationObjVar( self, "whereToFight" );
goFight.x = goFight.x + ( rand (-5, 5) );
ai_lib.aiPathTo( self, goFight );
setMovementRun( self );
addLocationTarget( "fight", goFight, 1 );
return SCRIPT_CONTINUE;
}
//------------------------------------------------
// OnArrivedAtLocation
//------------------------------------------------
trigger OnArrivedAtLocation( string name )
{
if ( name == "fight" )
{
chat.setAngryMood( self );
if ( hasObjVar( self, "leader" ) )
{
if ( hasObjVar( self, "jedi" ) )
chat.chat( self, new string_id(STF, "containment_team_jedi_"+getStringObjVar(self,"faction")) );
else
chat.chat( self, new string_id(STF, "containment_team_"+getStringObjVar(self,"faction")) );
}
obj_id attacker = getObjIdObjVar( self, "whoToFight" );
startCombat( self, attacker );
}
if ( name == "done" )
{
messageTo( self, "leaveWorld", null, 7, false );
}
return SCRIPT_CONTINUE;
}
//------------------------------------------------
// cleanUp
//------------------------------------------------
messageHandler cleanUp()
{
location home = getLocationObjVar( self, "home" );
ai_lib.aiPathTo( self, home );
addLocationTarget( "done", home, 1 );
messageTo( self, "handleBadLeaving", null, 120, false );
return SCRIPT_CONTINUE;
}
//------------------------------------------------
// leaveWorld
//------------------------------------------------
messageHandler leaveWorld()
{
destroyObject( self );
return SCRIPT_CONTINUE;
}
//------------------------------------------------
// handleBadLeaving
//------------------------------------------------
messageHandler handleBadLeaving()
{
messageTo( self, "leaveWorld", null, 7, false );
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,59 @@
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.ai.ai_combat;
import script.library.attrib;
public class monster extends script.base_script
{
public monster()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public int OnAttach(obj_id self) throws InterruptedException
{
setAttributeInterested(self, attrib.NPC);
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange(self), true);
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (!isMob(breacher))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isAiDead(self) || ai_lib.isAiDead(breacher))
{
return SCRIPT_CONTINUE;
}
if (!ai_lib.isNpc(breacher) || !ai_lib.isAndroid(breacher))
{
return SCRIPT_CONTINUE;
}
startCombat(self, breacher);
return SCRIPT_CONTINUE;
}
}
@@ -1,40 +0,0 @@
include library.ai_lib;
include ai.ai_combat;
include library.attrib;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
trigger OnAttach()
{
setAttributeInterested( self, attrib.NPC );
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
createTriggerVolume( ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange( self ), true );
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
if ( !isMob( breacher) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ) )
return SCRIPT_CONTINUE;
if ( breacher == self )
return SCRIPT_CONTINUE;
if ( ai_lib.isAiDead(self) || ai_lib.isAiDead( breacher ))
return SCRIPT_CONTINUE;
if (!ai_lib.isNpc( breacher ) || !ai_lib.isAndroid(breacher))
return SCRIPT_CONTINUE;
startCombat( self, breacher );
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,95 @@
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.ai.ai_combat;
import script.library.ai_lib;
import script.library.combat;
import script.library.pclib;
import script.library.factions;
import script.library.utils;
import script.library.pet_lib;
import script.library.scout;
import script.library.colors;
import script.library.xp;
public class mount_combat extends script.systems.combat.combat_base
{
public mount_combat()
{
}
public static final int RANGE_NEAR = 0;
public static final int RANGE_MID_NEAR = 1;
public static final int RANGE_MID_FAR = 2;
public static final int RANGE_FAR = 3;
public static final int COMBATMODE_NONE = 0;
public static final int COMBATMODE_DEFAULT = 1;
public static final int COMBATMODE_EQUIPPED = 2;
public static final int COMBATMODE_SPECIAL = 3;
public static final String CREATURE_TABLE = "datatables/mob/creatures.iff";
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public int aiCombatLoop(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnCreatureDamaged(obj_id self, obj_id attacker, obj_id weapon, int[] damage) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int defenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int handleDefenderCombatAction(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnDefenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int vocalizeEndCombat(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int postCombatPathHome(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnMovePathComplete(obj_id self) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnMoveMoving(obj_id self) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnIncapacitateTarget(obj_id self, obj_id target) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnAttach(obj_id self) throws InterruptedException
{
setWantSawAttackTriggers(self, false);
return SCRIPT_CONTINUE;
}
public int OnDetach(obj_id self) throws InterruptedException
{
setWantSawAttackTriggers(self, true);
return SCRIPT_CONTINUE;
}
}
@@ -1,102 +0,0 @@
// mount_combat.script
// a hijacked and modified copy of creature_combat.script
// intended to intercept creature combat triggers to prevent mounts from behaving in an untoward manner while the player is mounted
include ai.ai_combat;
include library.ai_lib;
include library.combat;
include library.pclib;
include library.factions;
include library.utils;
include library.pet_lib;
include library.scout;
include library.colors;
include library.xp;
inherits systems.combat.combat_base;
const int RANGE_NEAR = 0;
const int RANGE_MID_NEAR = 1;
const int RANGE_MID_FAR = 2;
const int RANGE_FAR = 3;
const int COMBATMODE_NONE = 0;
const int COMBATMODE_DEFAULT = 1;
const int COMBATMODE_EQUIPPED = 2;
const int COMBATMODE_SPECIAL = 3;
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
messageHandler aiCombatLoop()
{
return SCRIPT_OVERRIDE;
}
trigger OnCreatureDamaged( obj_id attacker, obj_id weapon, int[] damage )
{
return SCRIPT_OVERRIDE;
}
int defenderCombatAction( obj_id self, obj_id attacker, obj_id weapon, int combatResult )
{
return SCRIPT_OVERRIDE;
}
//message sent from non-combat, but aggressive scripts like poison, etc.
messageHandler handleDefenderCombatAction()
{
return SCRIPT_OVERRIDE;
}
trigger OnDefenderCombatAction( obj_id attacker, obj_id weapon, int combatResult )
{
return SCRIPT_OVERRIDE;
}
messageHandler vocalizeEndCombat()
{
return SCRIPT_OVERRIDE;
}
messageHandler postCombatPathHome()
{
return SCRIPT_OVERRIDE;
}
trigger OnMovePathComplete()
{
return SCRIPT_OVERRIDE;
}
trigger OnMoveMoving()
{
return SCRIPT_OVERRIDE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
return SCRIPT_OVERRIDE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
return SCRIPT_OVERRIDE;
}
trigger OnIncapacitateTarget(obj_id target)
{
return SCRIPT_OVERRIDE;
}
trigger OnAttach()
{
setWantSawAttackTriggers( self, false );
return SCRIPT_CONTINUE;
}
trigger OnDetach()
{
setWantSawAttackTriggers( self, true );
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,55 @@
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.pet_lib;
public class officer_pet extends script.base_script
{
public officer_pet()
{
}
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "getAndFollowMaster", null, 3, false);
messageTo(self, "verifyReinforcementsSkill", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
messageTo(self, "getAndFollowMaster", null, 3, false);
messageTo(self, "verifyReinforcementsSkill", null, 3, false);
return SCRIPT_CONTINUE;
}
public int getAndFollowMaster(obj_id self, dictionary params) throws InterruptedException
{
setCondition(self, CONDITION_CONVERSABLE);
obj_id master = getMaster(self);
if (isIdNull(master))
{
return SCRIPT_CONTINUE;
}
pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW, master);
return SCRIPT_CONTINUE;
}
public int verifyReinforcementsSkill(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdNull(master))
{
return SCRIPT_CONTINUE;
}
if (!hasSkill(master, "expertise_of_reinforcements_1"))
{
sendSystemMessage(master, new string_id("spam", "off_pet_no_skill"));
pet_lib.destroyOfficerPets(master);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,45 +0,0 @@
include library.pet_lib;
trigger OnAttach()
{
messageTo(self, "getAndFollowMaster", null, 3, false);
messageTo(self, "verifyReinforcementsSkill", null, 3, false);
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
messageTo(self, "getAndFollowMaster", null, 3, false);
messageTo(self, "verifyReinforcementsSkill", null, 3, false);
return SCRIPT_CONTINUE;
}
messageHandler getAndFollowMaster()
{
setCondition(self, CONDITION_CONVERSABLE);
obj_id master = getMaster(self);
if(isIdNull(master) )
return SCRIPT_CONTINUE;
pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW, master);
// pet_lib.doCommandNum(self, pet_lib.COMMAND_GUARD, master);
return SCRIPT_CONTINUE;
}
messageHandler verifyReinforcementsSkill()
{
obj_id master = getMaster(self);
if(isIdNull(master) )
return SCRIPT_CONTINUE;
if(!hasSkill(master, "expertise_of_reinforcements_1") )
{
sendSystemMessage(master, new string_id("spam", "off_pet_no_skill") );
pet_lib.destroyOfficerPets(master);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,398 @@
package script.ai.override_behavior;
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.ai.ai_combat;
import script.library.gcw;
import script.library.utils;
import script.library.ai_lib;
import script.library.factions;
import script.library.colors;
import script.library.faction_perk;
import script.library.jedi;
public class scout extends script.base_script
{
public scout()
{
}
public static final String SCRIPTVAR_SCOUT_TARGET = "behavior.scout.target";
public static final String SCRIPTVAR_SCANNED = "behavior.scout.scanned";
public static final String SCRIPTVAR_SCAN_STATUS = "behavior.scout.scan_status";
public static final String SCRIPTVAR_ATTACKED = "behavior.scout.attacked";
public static final String SCRIPTVAR_CALLED_SUPPORT = "behavior.scout.calledSupport";
public static final String CONTRABAND_SEARCH_STF = "imperial_presence/contraband_search";
public int OnAttach(obj_id self) throws InterruptedException
{
createTriggerVolume(ai_lib.AGGRO_VOLUME_NAME, 0, false);
stop(self);
gcw.assignScanInterests(self);
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (utils.hasScriptVar(self, "petBeingInitialized"))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (!isMob(breacher))
{
return SCRIPT_CONTINUE;
}
if (breacher == self || ai_lib.isAiDead(breacher) || ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.AGGRO_VOLUME_NAME))
{
if (!ai_lib.isInCombat(self))
{
int reaction = factions.getFactionReaction(self, breacher);
if (reaction == factions.REACTION_NEGATIVE)
{
return SCRIPT_OVERRIDE;
}
}
}
return SCRIPT_CONTINUE;
}
public int handleTargetAssignment(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT))
{
return SCRIPT_CONTINUE;
}
obj_id target = params.getObjId("target");
if (!isIdValid(target))
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
obj_id playerCurrentMount = getMountId(target);
if (isIdValid(playerCurrentMount))
{
obj_id mountId = getMountId(target);
if (isIdValid(mountId))
{
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "dismount"));
}
utils.dismountRiderJetpackCheck(target);
}
if (isIdValid(target))
{
scoutTarget(self, target);
}
return SCRIPT_CONTINUE;
}
public void scoutTarget(obj_id npc, obj_id target) throws InterruptedException
{
if (!isIdValid(npc) || !isIdValid(target) || npc == target)
{
return;
}
location here = getLocation(target);
if (here == null)
{
return;
}
if (isIdValid(here.cell))
{
return;
}
utils.setScriptVar(npc, SCRIPTVAR_SCOUT_TARGET, target);
if (ai_lib.isInCombat(npc))
{
return;
}
ai_lib.aiFollow(npc, target, 32f, 74f);
}
public int OnCreatureDamaged(obj_id self, obj_id attacker, obj_id wpn, int[] damage) throws InterruptedException
{
if (utils.hasScriptVar(self, SCRIPTVAR_ATTACKED))
{
return SCRIPT_CONTINUE;
}
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_distress_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", attacker);
messageTo(self, "callLambdaSupport", d1, 30f, false);
utils.setScriptVar(self, SCRIPTVAR_ATTACKED, 1);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
public int OnDefenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
if (utils.hasScriptVar(self, SCRIPTVAR_ATTACKED))
{
return SCRIPT_CONTINUE;
}
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_distress_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", attacker);
messageTo(self, "callLambdaSupport", d1, 30f, false);
messageTo(self, "reportActivities", d1, 35, false);
utils.setScriptVar(self, SCRIPTVAR_ATTACKED, 1);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
public int OnFollowTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
public int OnFollowWaiting(obj_id self, obj_id target) throws InterruptedException
{
if (!utils.hasScriptVar(self, SCRIPTVAR_SCAN_STATUS))
{
Vector scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
if (scanned != null && scanned.size() > 0)
{
if (utils.getElementPositionInArray(scanned, target) > -1)
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
}
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "probe_scan"));
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probe_scan_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
utils.setScriptVar(self, SCRIPTVAR_SCAN_STATUS, target);
dictionary d = new dictionary();
d.put("target", target);
messageTo(self, "handleScanComplete", d, 60f, false);
}
return SCRIPT_CONTINUE;
}
public int handleScanComplete(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
utils.removeScriptVar(self, SCRIPTVAR_SCAN_STATUS);
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT) || ai_lib.isDead(self))
{
return SCRIPT_CONTINUE;
}
obj_id target = params.getObjId("target");
obj_id oldTarget = utils.getObjIdScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if (!isIdValid(target) || target != oldTarget)
{
return SCRIPT_CONTINUE;
}
utils.setScriptVar(target, "scan_successful", 1);
if (ai_lib.checkForSmuggler(target))
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
int myFac = pvpGetAlignedFaction(self);
int tFac = pvpGetAlignedFaction(target);
if (pvpAreFactionsOpposed(myFac, tFac))
{
if (isPlayer(target) && pvpGetType(target) == PVPTYPE_DECLARED)
{
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_support_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
utils.setScriptVar(target, "scan_successful", 1);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", target);
messageTo(self, "callLambdaSupport", d1, 10f, false);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
}
float rating = gcw.scan(self, target);
Vector scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
scanned = utils.addElement(scanned, target);
if (scanned != null && scanned.size() > 0)
{
utils.setScriptVar(self, SCRIPTVAR_SCANNED, scanned);
}
if (rating > 15f)
{
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "probe_scan_positive"));
int actionCode = gcw.AC_SCAN;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", target);
messageTo(self, "callLambdaSupport", d1, 10f, false);
acquireNewTarget(self);
}
else
{
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "probe_scan_negative"));
acquireNewTarget(self);
}
return SCRIPT_CONTINUE;
}
public int OnFleeTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
if (!ai_lib.isInCombat(self))
{
obj_id target = utils.getObjIdScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if (!isIdValid(target) || !exists(target) || !target.isLoaded())
{
acquireNewTarget(self);
}
else
{
scoutTarget(self, target);
}
}
return SCRIPT_CONTINUE;
}
public void acquireNewTarget(obj_id self) throws InterruptedException
{
if (!isIdValid(self))
{
return;
}
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT))
{
return;
}
utils.removeScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if (ai_lib.isInCombat(self))
{
messageTo(self, "handleNeedTarget", null, 10f, false);
return;
}
obj_id[] players = getPlayerCreaturesInRange(self, 100f);
if (players == null || players.length == 0)
{
destroyObject(self);
return;
}
utils.removeScriptVar(self, SCRIPTVAR_ATTACKED);
Vector scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
Vector unscanned = utils.removeElements(new Vector(Arrays.asList(players)), scanned);
if (unscanned != null && unscanned.size() > 0)
{
obj_id target = ((obj_id)unscanned.get(rand(0, unscanned.size() - 1)));
if (isIdValid(target) && (!utils.hasScriptVar(target, "scan_successful")))
{
scoutTarget(self, target);
return;
}
}
ai_lib.wander(self);
messageTo(self, "handleNeedTarget", null, 15f, false);
}
public int handleNeedTarget(obj_id self, dictionary params) throws InterruptedException
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
public int callLambdaSupport(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isDead(self))
{
return SCRIPT_CONTINUE;
}
obj_id target = params.getObjId("target");
int actionCode = params.getInt("actionCode");
if (!isIdValid(self) || !isIdValid(target))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT))
{
return SCRIPT_CONTINUE;
}
utils.setScriptVar(self, SCRIPTVAR_CALLED_SUPPORT, getGameTime());
dictionary d = new dictionary();
d.put("actionCode", actionCode);
d.put("actionTarget", target);
if (actionCode == gcw.AC_SCAN)
{
int interests = utils.getIntScriptVar(self, gcw.SCRIPTVAR_SCAN_INTEREST);
d.put("scanInterests", interests);
}
location there = getLocation(target);
if (there == null)
{
utils.removeScriptVar(self, SCRIPTVAR_CALLED_SUPPORT);
return SCRIPT_CONTINUE;
}
location tmp = utils.getRandomLocationInRing(there, 5f, 10f);
if (tmp != null)
{
there = (location)tmp.clone();
}
if (there != null)
{
gcw.spawnViaLambdaPerGeo(there, d);
}
messageTo(self, "handleClearSupportCall", null, 180f, false);
return SCRIPT_CONTINUE;
}
public int handleClearSupportCall(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isDead(self))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "lambda_strike"))
{
utils.removeScriptVar(self, "lambda_strike");
}
utils.removeScriptVar(self, SCRIPTVAR_CALLED_SUPPORT);
return SCRIPT_CONTINUE;
}
public int reportActivities(obj_id self, dictionary params) throws InterruptedException
{
if (ai_lib.isDead(self))
{
return SCRIPT_CONTINUE;
}
obj_id target = params.getObjId("target");
int actionCode = params.getInt("actionCode");
if (!isIdValid(target))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "lambda_strike"))
{
return SCRIPT_CONTINUE;
}
if (target == null)
{
return SCRIPT_CONTINUE;
}
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "report_activities"));
utils.setScriptVar(self, "lambda_strike", getGameTime());
if (!isJedi(target))
{
pvpMakeDeclared(target);
CustomerServiceLog("CONTRABAND_SCANNING: ", "%TU made Overt by Probot Scan", target, null);
}
else
{
jedi.doJediTEF(target);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,438 +0,0 @@
include ai.ai_combat;
include library.gcw;
include library.utils;
include library.ai_lib;
include library.factions;
include library.colors;
include library.faction_perk;
include library.jedi;
const string SCRIPTVAR_SCOUT_TARGET = "behavior.scout.target";
const string SCRIPTVAR_SCANNED = "behavior.scout.scanned";
const string SCRIPTVAR_SCAN_STATUS = "behavior.scout.scan_status";
const string SCRIPTVAR_ATTACKED = "behavior.scout.attacked";
const string SCRIPTVAR_CALLED_SUPPORT = "behavior.scout.calledSupport";
const string CONTRABAND_SEARCH_STF = "imperial_presence/contraband_search";
trigger OnAttach()
{
createTriggerVolume( ai_lib.AGGRO_VOLUME_NAME, 0, false );
stop(self);
gcw.assignScanInterests(self);
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( utils.hasScriptVar( self, "petBeingInitialized") )
return SCRIPT_CONTINUE;
//debugSpeakMsg( self, "I see " + getName( breacher ) );
if ( hasObjVar( breacher, "gm") )
{
//debugSpeakMsg( self, "you are a gm" );
return SCRIPT_CONTINUE;
}
if ( !isMob( breacher ) )
{
//debugSpeakMsg( self, "you are not a mob" );
return SCRIPT_CONTINUE;
}
if ( breacher == self || ai_lib.isAiDead( breacher ) || ai_lib.isAiDead( self ))
{
//debugSpeakMsg( self, "somethin is dead" );
return SCRIPT_CONTINUE;
}
if ( volumeName.equals( ai_lib.AGGRO_VOLUME_NAME ))
{
//debugSpeakMsg( self, " i see " + getName( breacher ) );
//debugSpeakMsg( breacher, "entering aggro");
if ( !ai_lib.isInCombat( self ) )
{
int reaction = factions.getFactionReaction( self, breacher );
if ( reaction == factions.REACTION_NEGATIVE )
{
//debugSpeakMsg( self, "reaction is negative");
return SCRIPT_OVERRIDE;
}
}
}
return SCRIPT_CONTINUE;
}
messageHandler handleTargetAssignment()
{
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT) )
return SCRIPT_CONTINUE;
obj_id target = params.getObjId("target");
if (!isIdValid(target))
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
obj_id playerCurrentMount = getMountId (target);
if ( isIdValid( playerCurrentMount ) )
{
obj_id mountId = getMountId(target);
if (isIdValid(mountId))
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF,"dismount"));
utils.dismountRiderJetpackCheck(target);
}
if ( isIdValid(target))
scoutTarget(self, target);
return SCRIPT_CONTINUE;
}
void scoutTarget( obj_id npc, obj_id target )
{
if ( !isIdValid(npc) || !isIdValid(target) || npc == target )
return;
location here = getLocation(target);
if ( here == null )
return;
if ( isIdValid(here.cell) )
return;
utils.setScriptVar(npc, SCRIPTVAR_SCOUT_TARGET, target);
if ( ai_lib.isInCombat(npc) )
return;
ai_lib.aiFollow( npc, target, 32f, 74f );
}
trigger OnCreatureDamaged(obj_id attacker, obj_id wpn, int[] damage)
{
//debugSpeakMsg(self, "OnCreatureDamaged("+attacker+"): -> attempting to flee...");
//ai_combat.fleeFromCombat(self, attacker);
if (utils.hasScriptVar(self, SCRIPTVAR_ATTACKED))
return SCRIPT_CONTINUE;
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_distress_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", attacker);
messageTo(self, "callLambdaSupport", d1, 30f, false);
//messageTo(self, "reportActivities", d1, 35, false);
utils.setScriptVar(self, SCRIPTVAR_ATTACKED, 1);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
trigger OnDefenderCombatAction( obj_id attacker, obj_id weapon, int combatResult )
{
//debugSpeakMsg(self, "OnCreatureDamaged("+attacker+"): -> attempting to flee...");
//ai_combat.fleeFromCombat(self, attacker);
if (utils.hasScriptVar(self, SCRIPTVAR_ATTACKED))
return SCRIPT_CONTINUE;
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_distress_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", attacker);
messageTo(self, "callLambdaSupport", d1, 30f, false);
messageTo(self, "reportActivities", d1, 35, false);
utils.setScriptVar(self, SCRIPTVAR_ATTACKED, 1);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
trigger OnFollowTargetLost(obj_id oldTarget)
{
//need new scout target?
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
trigger OnFollowWaiting(obj_id target)
{
if ( !utils.hasScriptVar(self, SCRIPTVAR_SCAN_STATUS) )
{
resizeable obj_id[] scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
if ( scanned != null && scanned.length > 0 )
{
if ( utils.getElementPositionInArray(scanned, target) > -1 )
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
}
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF,"probe_scan"));
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probe_scan_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
utils.setScriptVar(self, SCRIPTVAR_SCAN_STATUS, target);
dictionary d = new dictionary();
d.put("target", target);
messageTo(self, "handleScanComplete", d, 60f, false);
}
return SCRIPT_CONTINUE;
}
messageHandler handleScanComplete()
{
if ( ai_lib.isAiDead(self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat(self) )
return SCRIPT_CONTINUE;
utils.removeScriptVar(self, SCRIPTVAR_SCAN_STATUS);
if ( utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT) || ai_lib.isDead(self) )
return SCRIPT_CONTINUE;
obj_id target = params.getObjId("target");
obj_id oldTarget = utils.getObjIdScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if ( !isIdValid(target) || target != oldTarget )
return SCRIPT_CONTINUE;
utils.setScriptVar(target, "scan_successful",1);
if (ai_lib.checkForSmuggler(target))
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
int myFac = pvpGetAlignedFaction(self);
int tFac = pvpGetAlignedFaction(target);
if ( pvpAreFactionsOpposed(myFac, tFac) )
{
if ( isPlayer(target) && pvpGetType( target ) == PVPTYPE_DECLARED)
{
string_id msg = new string_id(CONTRABAND_SEARCH_STF, "probot_support_fly");
showFlyText(self, msg, 1.0f, colors.TOMATO);
utils.setScriptVar (target, "scan_successful", 1);
int actionCode = gcw.AC_ATTACK;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", target);
messageTo(self, "callLambdaSupport", d1, 10f, false);
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
}
//debugSpeakMsg(self, "OnFollowWaiting("+target+"): -> scanning...");
float rating = gcw.scan(self, target);
resizeable obj_id[] scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
scanned = utils.addElement(scanned, target);
if ( scanned != null && scanned.length > 0 )
utils.setScriptVar(self, SCRIPTVAR_SCANNED, scanned);
//debugSpeakMsg(self, "scan rating for target("+target+") = " + rating);
if ( rating > 15f )
{
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "probe_scan_positive"));
//call lambda squad
int actionCode = gcw.AC_SCAN;
dictionary d1 = new dictionary();
d1.put("actionCode", actionCode);
d1.put("target", target);
messageTo(self, "callLambdaSupport", d1, 10f, false);
acquireNewTarget(self);
}
else
{
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF, "probe_scan_negative"));
acquireNewTarget(self);
}
return SCRIPT_CONTINUE;
}
trigger OnFleeTargetLost(obj_id oldTarget)
{
//need new scout target?
if ( !ai_lib.isInCombat(self) )
{
obj_id target = utils.getObjIdScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if ( !isIdValid(target) || !exists(target) || !target.isLoaded() )
acquireNewTarget(self);
else
scoutTarget(self, target);
}
return SCRIPT_CONTINUE;
}
void acquireNewTarget(obj_id self)
{
if ( !isIdValid(self) )
return;
if (utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT) )
return;
utils.removeScriptVar(self, SCRIPTVAR_SCOUT_TARGET);
if ( ai_lib.isInCombat(self) )
{
messageTo(self, "handleNeedTarget", null, 10f, false);
return;
}
obj_id[] players = getPlayerCreaturesInRange(self, 100f);
if ( players == null || players.length == 0 )
{
destroyObject(self);
return;
}
utils.removeScriptVar(self, SCRIPTVAR_ATTACKED);
resizeable obj_id[] scanned = utils.getResizeableObjIdArrayScriptVar(self, SCRIPTVAR_SCANNED);
resizeable obj_id[] unscanned = utils.removeElements(new Vector(Arrays.asList(players)), scanned);
if ( unscanned != null && unscanned.length > 0 )
{
obj_id target = unscanned[rand(0,unscanned.length-1)];
if ( isIdValid(target) && (!utils.hasScriptVar(target, "scan_successful")))
{
scoutTarget(self, target);
return;
}
}
ai_lib.wander(self);
messageTo(self, "handleNeedTarget", null, 15f, false);
}
messageHandler handleNeedTarget()
{
acquireNewTarget(self);
return SCRIPT_CONTINUE;
}
messageHandler callLambdaSupport()
{
if (ai_lib.isDead(self))
return SCRIPT_CONTINUE;
obj_id target = params.getObjId("target");
int actionCode = params.getInt("actionCode");
if ( !isIdValid(self) || !isIdValid(target) )
return SCRIPT_CONTINUE;
if ( utils.hasScriptVar(self, SCRIPTVAR_CALLED_SUPPORT) )
return SCRIPT_CONTINUE;
//debugSpeakMsg(self, "calling lambda support");
utils.setScriptVar(self, SCRIPTVAR_CALLED_SUPPORT, getGameTime());
dictionary d = new dictionary();
d.put("actionCode", actionCode);
d.put("actionTarget", target);
if ( actionCode == gcw.AC_SCAN )
{
int interests = utils.getIntScriptVar(self, gcw.SCRIPTVAR_SCAN_INTEREST);
d.put("scanInterests", interests);
}
location there = getLocation(target);
if(there == null)
{ // I don't think that this would happen, but that
// null pointer exception came from somewhere...
utils.removeScriptVar(self, SCRIPTVAR_CALLED_SUPPORT);
return SCRIPT_CONTINUE;
}
location tmp = utils.getRandomLocationInRing(there, 5f, 10f);
if ( tmp != null )
there = (location)tmp.clone();
if ( there != null )
gcw.spawnViaLambdaPerGeo(there, d);
messageTo(self, "handleClearSupportCall", null, 180f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleClearSupportCall()
{
if ( ai_lib.isDead(self) )
return SCRIPT_CONTINUE;
if (utils.hasScriptVar(self, "lambda_strike"))
utils.removeScriptVar(self, "lambda_strike");
utils.removeScriptVar(self, SCRIPTVAR_CALLED_SUPPORT);
return SCRIPT_CONTINUE;
}
messageHandler reportActivities ()
{
if (ai_lib.isDead(self) )
return SCRIPT_CONTINUE;
obj_id target = params.getObjId("target");
int actionCode = params.getInt("actionCode");
if (!isIdValid(target))
return SCRIPT_CONTINUE;
if( utils.hasScriptVar(self, "lambda_strike"))
return SCRIPT_CONTINUE;
if(target == null) // Weird stuff going on in this method with null pointer
return SCRIPT_CONTINUE; // exceptions. Adding in an extra check just in case.
sendSystemMessage(target, new string_id(CONTRABAND_SEARCH_STF,"report_activities"));
utils.setScriptVar(self, "lambda_strike", getGameTime());
if(!isJedi(target))
{
pvpMakeDeclared(target);
//CustomerServiceLog("CONTRABAND_SCANNING: ", "("+ target + ")"+ getFirstName(target) + " made Overt by Probot Scan");
CustomerServiceLog("CONTRABAND_SCANNING: ", "%TU made Overt by Probot Scan", target, null);
}
else
{
jedi.doJediTEF(target);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,77 @@
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.create;
public class parasite extends script.base_script
{
public parasite()
{
}
public static final String SCRIPT_NAME = "ai.parasite";
public int OnAttach(obj_id self) throws InterruptedException
{
if (!hasObjVar(self, "host"))
{
detachScript(self, SCRIPT_NAME);
}
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
if (!hasObjVar(self, "host"))
{
detachScript(self, SCRIPT_NAME);
}
return SCRIPT_CONTINUE;
}
public int OnIncapacitated(obj_id self, obj_id killer) throws InterruptedException
{
if (!hasObjVar(self, "host"))
{
return SCRIPT_CONTINUE;
}
dictionary d = new dictionary();
d.put("killer", killer);
messageTo(self, "handleParasiteExplosion", d, 1.0f, false);
return SCRIPT_CONTINUE;
}
public int handleParasiteExplosion(obj_id self, dictionary params) throws InterruptedException
{
if (!hasObjVar(self, "host"))
{
return SCRIPT_CONTINUE;
}
obj_id killer = params.getObjId("killer");
if (isIdValid(killer))
{
playClientEffectLoc(killer, "clienteffect/cr_parasite_explosion.cef", getLocation(self), 0.5f);
}
String parasite = getStringObjVar(self, "host");
int numToSpawn = rand(1, 3);
for (int i = 0; i < numToSpawn; i++)
{
location here = getLocation(self);
int randX = rand(-10, 10);
int randZ = rand(-10, 10);
float rX = ((float)randX) / 10f;
float rZ = ((float)randZ) / 10f;
here.x += rX;
here.z += rZ;
obj_id critter = create.object(parasite, here);
if (isIdValid(critter) && isIdValid(killer))
{
addHate(critter, killer, 100f);
addHate(killer, critter, 0f);
}
}
return SCRIPT_CONTINUE;
}
}
@@ -1,68 +0,0 @@
include library.create;
const string SCRIPT_NAME = "ai.parasite";
trigger OnAttach()
{
if(!hasObjVar(self, "host"))
detachScript(self, SCRIPT_NAME);
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
if(!hasObjVar(self, "host"))
detachScript(self, SCRIPT_NAME);
return SCRIPT_CONTINUE;
}
trigger OnIncapacitated(obj_id killer)
{
if(!hasObjVar(self, "host"))
return SCRIPT_CONTINUE;
dictionary d = new dictionary();
d.put("killer", killer);
messageTo(self, "handleParasiteExplosion", d, 1.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleParasiteExplosion()
{
if(!hasObjVar(self, "host"))
return SCRIPT_CONTINUE;
obj_id killer = params.getObjId("killer");
if(isIdValid(killer))
playClientEffectLoc(killer, "clienteffect/cr_parasite_explosion.cef", getLocation(self), 0.5f);
string parasite = getStringObjVar(self, "host");
int numToSpawn = rand(1, 3);
for(int i = 0; i < numToSpawn; i++)
{
location here = getLocation(self);
int randX = rand(-10, 10);
int randZ = rand(-10, 10);
float rX = ((float)randX)/10f;
float rZ = ((float)randZ)/10f;
here.x += rX;
here.z += rZ;
obj_id critter = create.object(parasite, here);
if(isIdValid(critter) && isIdValid(killer))
{
addHate(critter, killer, 100f);
addHate(killer, critter, 0f);
}
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,120 @@
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.callable;
import script.library.utils;
public class pcd_ping_response extends script.base_script
{
public pcd_ping_response()
{
}
public static final String PCDPING_MESSAGE_PCD_ID_NAME = "pcdId";
public static final String PCDPING_MESSAGE_PET_ID_NAME = "petId";
public static final String PCDPING_MESSAGE_MESSAGE_ID_NAME = "messageId";
public static final String PCDPING_MESSAGE_RIDER_ID_NAME = "riderId";
public static final String PCDPING_PET_MESSAGEHANDLER_POSITIVE_ACK_NAME = "handlePositiveAcknowledgementFromPcd";
public static final String PCDPING_PET_MESSAGEHANDLER_NEGATIVE_ACK_NAME = "handleNegativeAcknowledgementFromPcd";
public static final String PCDPING_PET_MESSAGEHANDLER_PACK_REQUEST_NAME = "handlePackRequest";
public static final boolean debug = false;
public int OnAttach(obj_id self) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pcd_ping_response.OnAttach(): self=[" + self + "] entered");
}
if (debug)
{
LOG("pcdping-debug", "pcd_ping_response.OnAttach(): self=[" + self + "] exited");
}
return SCRIPT_CONTINUE;
}
public int handlePetPing(obj_id self, dictionary params) throws InterruptedException
{
final obj_id pingPetId = params.getObjId(PCDPING_MESSAGE_PET_ID_NAME);
final obj_id riderId = params.getObjId(PCDPING_MESSAGE_RIDER_ID_NAME);
final int pingMessageNumber = params.getInt(PCDPING_MESSAGE_MESSAGE_ID_NAME);
obj_id currentPetId = callable.getCDCallable(self);
final boolean shouldHavePet = isIdValid(currentPetId);
if (shouldHavePet)
{
if (pingPetId == currentPetId)
{
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
return SCRIPT_CONTINUE;
}
else
{
if (isIdValid(riderId) && isRiderOkayForPcd(self, riderId))
{
LOG("pcd-bug", "PCD id=[" + self + "]: received ping from pet id=[" + pingPetId + "] with rider id=[" + riderId + "]: PCD thinks pet id=[" + currentPetId + "] is out. Reassigning PCD pet due to on-board rider and packing pet id=[" + currentPetId + "].");
messageTo(currentPetId, PCDPING_PET_MESSAGEHANDLER_PACK_REQUEST_NAME, null, 1, false);
callable.setCDCallable(self, pingPetId);
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
}
else
{
sendNegativeAcknowledgement(self, pingPetId, pingMessageNumber, "PCD does not expect pet=[" + pingPetId + "] to be the called pet. It thinks pet=[" + currentPetId + "] is called.");
}
}
}
else
{
if (isIdValid(riderId) && isRiderOkayForPcd(self, riderId))
{
LOG("pcd-bug", "PCD id=[" + self + "]: received ping from pet id=[" + pingPetId + "] with rider id=[" + riderId + "]: PCD thinks no pet is out. Reassigning PCD pet due to on-board rider.");
callable.setCDCallable(self, pingPetId);
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
}
else
{
sendNegativeAcknowledgement(self, pingPetId, pingMessageNumber, "PCD does not expecting its pet to exist");
}
}
return SCRIPT_CONTINUE;
}
public dictionary createResponseDictionary(obj_id pcdId, int messageNumber) throws InterruptedException
{
dictionary messageData = new dictionary();
messageData.put(PCDPING_MESSAGE_PCD_ID_NAME, pcdId);
messageData.put(PCDPING_MESSAGE_MESSAGE_ID_NAME, messageNumber);
return messageData;
}
public void sendPositiveAcknowledgement(obj_id pcdId, obj_id petId, int messageNumber) throws InterruptedException
{
dictionary messageData = createResponseDictionary(pcdId, messageNumber);
if (debug)
{
LOG("pcdping-debug", "pcd_ping_response.sendPositiveAcknowledgement(): pcdId=[" + pcdId + "], petId=[" + petId + "], messageNumber=[" + messageNumber + "]: sending positive ack now.");
}
messageTo(petId, PCDPING_PET_MESSAGEHANDLER_POSITIVE_ACK_NAME, messageData, 1, false);
}
public void sendNegativeAcknowledgement(obj_id pcdId, obj_id petId, int messageNumber, String reason) throws InterruptedException
{
dictionary messageData = createResponseDictionary(pcdId, messageNumber);
LOG("pcdping-pcd", "pcd_ping_response.sendNegativeAcknowledgement(): pcdId=[" + pcdId + "], petId=[" + petId + "], messageNumber=[" + messageNumber + "]: sending negative ack now: reason=[" + reason + "].");
messageTo(petId, PCDPING_PET_MESSAGEHANDLER_NEGATIVE_ACK_NAME, messageData, 1, false);
}
public boolean isRiderOkayForPcd(obj_id pcdId, obj_id riderId) throws InterruptedException
{
if (!isIdValid(pcdId) || !isIdValid(riderId))
{
return false;
}
for (obj_id testObjectId = getContainedBy(pcdId); isIdValid(testObjectId); testObjectId = getContainedBy(testObjectId))
{
if (testObjectId == riderId)
{
return true;
}
}
return false;
}
}
@@ -1,208 +0,0 @@
//----------------------------------------------------------
// pcd_ping_response.script
// -----------------------------------------------------------------------
// This script is a re-hash of pcd_ping_response.script, altered to function for pets
// Original script notes listed below.
//
// This script is attached to a PCD. It is setup to respond
// to a ping initiated by the pet_ping.script attached
// to a pet. If the PCD fails to respond to a certain
// number of ping requests or if the PCD does not think the
// pinging pet should exist, the pet will destroy
// itself, dismounting any players prior to destruction.
//----------------------------------------------------------
include library.callable;
include library.utils;
//----------------------------------------------------------
const string PCDPING_MESSAGE_PCD_ID_NAME = "pcdId";
const string PCDPING_MESSAGE_PET_ID_NAME = "petId";
const string PCDPING_MESSAGE_MESSAGE_ID_NAME = "messageId";
const string PCDPING_MESSAGE_RIDER_ID_NAME = "riderId";
const string PCDPING_PET_MESSAGEHANDLER_POSITIVE_ACK_NAME = "handlePositiveAcknowledgementFromPcd";
const string PCDPING_PET_MESSAGEHANDLER_NEGATIVE_ACK_NAME = "handleNegativeAcknowledgementFromPcd";
const string PCDPING_PET_MESSAGEHANDLER_PACK_REQUEST_NAME = "handlePackRequest";
const boolean debug = false;
//----------------------------------------------------------
trigger OnAttach()
{
if (debug)
LOG("pcdping-debug", "pcd_ping_response.OnAttach(): self=[" + self + "] entered");
if (debug)
LOG("pcdping-debug", "pcd_ping_response.OnAttach(): self=[" + self + "] exited");
return SCRIPT_CONTINUE;
}
//---------------------------------------------------------
/**
* This handles the message sent by pet_ping.script's petPingCallback messageHandler.
*
* The purpose of this messageHandler is to check whether the
* pinging pet should exist and respond with the results
* to that pet.
*/
messageHandler handlePetPing()
{
//-- Retrieve message parameters.
const obj_id pingPetId = params.getObjId(PCDPING_MESSAGE_PET_ID_NAME);
const obj_id riderId = params.getObjId(PCDPING_MESSAGE_RIDER_ID_NAME);
const int pingMessageNumber = params.getInt(PCDPING_MESSAGE_MESSAGE_ID_NAME);
//-- Check which pet we think should be out in the world.
obj_id currentPetId = callable.getCDCallable(self);
const boolean shouldHavePet = isIdValid(currentPetId);
if (shouldHavePet)
{
if (pingPetId == currentPetId)
{
//-- PCD is controlling a pet and it matches the pet doing the ping. Send positive acknowledgement.
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
return SCRIPT_CONTINUE;
}
else
{
//-- PCD is controlling a pet but received a ping from a
// different pet. This indicates that the pet doing the
// ping should not be out.
// -TRF- remove the block that adjusts the PCD's idea of the current pet
// once we have our bugs worked out.
//-- The ping pet is not the PCD's expected pet. For now,
// if there is a rider and that rider is the person holding the
// PCD, allow them to stay on board.
if (isIdValid(riderId) && isRiderOkayForPcd(self, riderId))
{
//-- Reset the PCD's idea of the current pet. This is a hack and should be removed.
LOG("pcd-bug", "PCD id=[" + self + "]: received ping from pet id=[" + pingPetId + "] with rider id=[" + riderId + "]: PCD thinks pet id=[" + currentPetId + "] is out. Reassigning PCD pet due to on-board rider and packing pet id=[" + currentPetId + "].");
// Destroy the pet that the PCD thinks is current since it is not what the PCD holder is riding.
messageTo(currentPetId, PCDPING_PET_MESSAGEHANDLER_PACK_REQUEST_NAME, null, 1, false);
// Reset our idea of the current pet to the one that is pinging us with the PCD owner on it.
callable.setCDCallable(self, pingPetId);
// Now the nasty part: tell the pet "you're cool!" when it really wasn't.
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
}
else
{
// Send the nack.
sendNegativeAcknowledgement(self, pingPetId, pingMessageNumber, "PCD does not expect pet=[" + pingPetId + "] to be the called pet. It thinks pet=[" + currentPetId + "] is called.");
}
}
}
else
{
//-- PCD does not think it should be controlling a pet but
// just received a ping from a pet. This indicates that the
// pet doing the ping should not be out.
// -TRF- remove the block that adjusts the PCD's idea of the
// current pet once we have our bugs worked
// out.
// No pet should be in the world. For now, if there is a rider and that
// rider is the person holding the PCD, allow them to stay on board.
if (isIdValid(riderId) && isRiderOkayForPcd(self, riderId))
{
//-- Reset the PCD's idea of the current pet. This is a hack and should be removed.
LOG("pcd-bug", "PCD id=[" + self + "]: received ping from pet id=[" + pingPetId + "] with rider id=[" + riderId + "]: PCD thinks no pet is out. Reassigning PCD pet due to on-board rider.");
// Reset our idea of the current pet to the one that is pinging us with the PCD owner on it.
callable.setCDCallable(self, pingPetId);
// Now the nasty part: tell the pet "you're cool!" when it really wasn't.
sendPositiveAcknowledgement(self, pingPetId, pingMessageNumber);
}
else
{
// Send negative ack.
sendNegativeAcknowledgement(self, pingPetId, pingMessageNumber, "PCD does not expecting its pet to exist");
}
}
return SCRIPT_CONTINUE;
}
//---------------------------------------------------------
dictionary createResponseDictionary(obj_id pcdId, int messageNumber)
{
//-- Create and populate the dictionary.
dictionary messageData = new dictionary();
messageData.put(PCDPING_MESSAGE_PCD_ID_NAME, pcdId);
messageData.put(PCDPING_MESSAGE_MESSAGE_ID_NAME, messageNumber);
return messageData;
}
//---------------------------------------------------------
void sendPositiveAcknowledgement(obj_id pcdId, obj_id petId, int messageNumber)
{
//-- Create the response dictionary.
dictionary messageData = createResponseDictionary(pcdId, messageNumber);
//-- Send message.
if (debug)
LOG("pcdping-debug", "pcd_ping_response.sendPositiveAcknowledgement(): pcdId=[" + pcdId + "], petId=[" + petId + "], messageNumber=[" + messageNumber + "]: sending positive ack now.");
messageTo(petId, PCDPING_PET_MESSAGEHANDLER_POSITIVE_ACK_NAME, messageData, 1, false);
}
//---------------------------------------------------------
void sendNegativeAcknowledgement(obj_id pcdId, obj_id petId, int messageNumber, string reason)
{
//-- Create the response dictionary.
dictionary messageData = createResponseDictionary(pcdId, messageNumber);
//-- Send message.
LOG("pcdping-pcd", "pcd_ping_response.sendNegativeAcknowledgement(): pcdId=[" + pcdId + "], petId=[" + petId + "], messageNumber=[" + messageNumber + "]: sending negative ack now: reason=[" + reason + "].");
messageTo(petId, PCDPING_PET_MESSAGEHANDLER_NEGATIVE_ACK_NAME, messageData, 1, false);
}
//---------------------------------------------------------
/**
* Determine whether the specified rider is valid for riding on a pet coming from the specified PCD.
*
* For now we will check if the PCD is ultimately contained by the rider.
*
* @return true if the PCD is held by the rider; false otherwise.
*/
boolean isRiderOkayForPcd(obj_id pcdId, obj_id riderId)
{
// Validate args.
if (!isIdValid(pcdId) || !isIdValid(riderId))
return false;
// Go up the containment chain of the pcd. If one of the containers
// is the rider, we're good.
for (obj_id testObjectId = getContainedBy(pcdId); isIdValid(testObjectId); testObjectId = getContainedBy(testObjectId))
{
if (testObjectId == riderId)
{
// One of the container parents of the pcd is the rider we're checking.
// This rider is fine to be riding on this pet.
return true;
}
}
// We didn't find the rider in the pcd's containment chain. This means the
// rider is not holding this PCD. The rider should not be on the pet.
return false;
}
//---------------------------------------------------------
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,16 @@
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;
public class pet_advance extends script.base_script
{
public pet_advance()
{
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,385 @@
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.beast_lib;
import script.library.buff;
import script.library.callable;
import script.library.utils;
import script.library.pet_lib;
import script.library.colors;
import script.library.ai_lib;
import script.library.chat;
import script.library.combat;
import script.library.scout;
import script.library.create;
import script.library.vehicle;
import script.library.sui;
import script.library.factions;
public class pet_master extends script.base_script
{
public pet_master()
{
}
public static final String CREATURE_TABLE = "datatables/mob/creatures.iff";
public static final String STF_FILE = "pet/droid_modules";
public static final string_id SID_SYS_EMBOLDEN = new string_id("pet/pet_menu", "sys_embolden");
public static final string_id SID_SYS_FAIL_EMBOLDEN = new string_id("pet/pet_menu", "sys_fail_embolden");
public static final string_id SID_SYS_ENRAGE = new string_id("pet/pet_menu", "sys_enrage");
public static final string_id SID_SYS_FAIL_ENRAGE = new string_id("pet/pet_menu", "sys_fail_enrage");
public static final string_id SID_SYS_CANT_BUFF = new string_id("pet/pet_menu", "sys_cant_buff");
public int OnRemovedFromGroup(obj_id self, obj_id group) throws InterruptedException
{
if (!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
obj_id[] memberList = getGroupMemberIds(group);
if (memberList == null || memberList.length < 1)
{
return SCRIPT_CONTINUE;
}
for (int i = 0; i < memberList.length; i++)
{
if (isIdValid(memberList[i]) && pet_lib.isMyPet(memberList[i], self))
{
queueCommand(memberList[i], (1348589140), group, "", COMMAND_PRIORITY_DEFAULT);
}
}
return SCRIPT_CONTINUE;
}
public int OnDefenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
obj_id pet = callable.getCallable(self, callable.CALLABLE_TYPE_COMBAT_PET);
if (isIdValid(pet) && exists(pet) && !ai_lib.isInCombat(pet) && !beast_lib.isBeast(pet) && utils.hasScriptVar(pet, "ai.pet.guarding"))
{
addHate(pet, attacker, 0.0f);
}
return SCRIPT_CONTINUE;
}
public int failPetBuff(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
sendSystemMessage(self, SID_SYS_CANT_BUFF);
return SCRIPT_CONTINUE;
}
public int OnSkillGranted(obj_id self, String skillName) throws InterruptedException
{
if (hasObjVar(self, "familiar"))
{
obj_id pet = getObjIdObjVar(self, "familiar");
if (exists(pet) && isInWorld(pet))
{
dictionary trickData = new dictionary();
trickData.put("pet", pet);
trickData.put("trickNum", 2);
trickData.put("heartBeat", false);
messageTo(pet, "doFamiliarTrick", trickData, 1, false);
}
}
return SCRIPT_CONTINUE;
}
public int OnRemovingFromWorld(obj_id self) throws InterruptedException
{
if (!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
callable.storeCallables(self);
return SCRIPT_CONTINUE;
}
public int OnDeath(obj_id self, obj_id killer, obj_id corpseId) throws InterruptedException
{
if (!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
if (pet_lib.isPet(killer))
{
killer = getMaster(killer);
}
callable.killCallables(self, killer);
return SCRIPT_CONTINUE;
}
public int cmdDetonateDroid(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
LOG("droid_module", "ai.pet_master.cmdDetonateDroid");
if (!isIdValid(target))
{
target = getLookAtTarget(self);
if (!isIdValid(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "invalid_droid_bomb"));
return SCRIPT_CONTINUE;
}
}
if (!pet_lib.isDroidPet(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "invalid_droid_bomb"));
return SCRIPT_CONTINUE;
}
if (getMaster(target) != self)
{
sendSystemMessage(self, new string_id(STF_FILE, "must_be_owner_droid_bomb"));
return SCRIPT_CONTINUE;
}
if (ai_lib.isAiDead(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "droid_disabled_detonate"));
return SCRIPT_CONTINUE;
}
int bomb_level = getIntObjVar(target, "module_data.bomb_level");
if (bomb_level < 1)
{
sendSystemMessage(self, new string_id(STF_FILE, "no_bomb_module"));
return SCRIPT_CONTINUE;
}
if (!hasSkill(self, "class_smuggler_phase1_novice") && !hasSkill(self, "class_bountyhunter_phase1_novice"))
{
sendSystemMessage(self, new string_id(STF_FILE, "insufficient_skill_detonate"));
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(target, "droid_module.countdown"))
{
sendSystemMessage(self, new string_id(STF_FILE, "countdown_already_started"));
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "droid.bomb_droid_active") && utils.getIntScriptVar(self, "droid.bomb_droid_active") > getGameTime())
{
sendSystemMessage(self, new string_id(STF_FILE, "countdown_already_started"));
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(target, "module_data.detonation_warmup"))
{
sendSystemMessage(self, new string_id(STF_FILE, "detonation_warmup"));
return SCRIPT_CONTINUE;
}
utils.setScriptVar(target, "droid_module.countdown", 1);
dictionary d = new dictionary();
d.put("master", self);
d.put("count", 3);
messageTo(target, "msgDetonationCountdown", d, 1.0f, false);
sendSystemMessage(self, new string_id(STF_FILE, "countdown_started"));
utils.setScriptVar(self, "droid.bomb_droid_active", (getGameTime() + 10));
return SCRIPT_CONTINUE;
}
public int clearBombDroidTimer(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, "droid.bomb_droid_active"))
{
utils.removeScriptVar(self, "droid.bomb_droid_active");
}
return SCRIPT_CONTINUE;
}
public boolean hasPrereq(obj_id pet, int ability) throws InterruptedException
{
if (!isIdValid(pet) || !exists(pet))
{
return false;
}
obj_id pcd = callable.getCallableCD(pet);
int[] abilityList = getIntArrayObjVar(pcd, "ai.petAbility.abilityList");
if (abilityList == null || abilityList.length == 0)
{
return false;
}
return (hasPrereq(abilityList, ability));
}
public boolean hasPrereq(int[] abilityList, int ability) throws InterruptedException
{
int row = dataTableSearchColumnForInt(ability, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if (row == -1)
{
return false;
}
dictionary abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
String prereq = abilityData.getString("prereq");
if (prereq == null || prereq.equals(""))
{
return true;
}
int prereqCrc = getStringCrc(prereq.toLowerCase());
if (utils.getElementPositionInArray(abilityList, prereqCrc) != -1)
{
return true;
}
return false;
}
public int[] buildPrereqList(int ability) throws InterruptedException
{
Vector prereqList = new Vector();
prereqList.setSize(0);
int row = dataTableSearchColumnForInt(ability, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if (row == -1)
{
return null;
}
dictionary abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
String prereq = abilityData.getString("prereq");
if (prereq == null || prereq.equals(""))
{
return null;
}
int prereqCrc = getStringCrc(prereq.toLowerCase());
while (prereqCrc != 0)
{
row = dataTableSearchColumnForInt(prereqCrc, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if (row == -1)
{
break;
}
prereqList = utils.addElement(prereqList, prereqCrc);
abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
prereq = abilityData.getString("prereq");
if (prereq == null || prereq.equals(""))
{
break;
}
prereqCrc = getStringCrc(prereq.toLowerCase());
}
int[] _prereqList = new int[0];
if (prereqList != null)
{
_prereqList = new int[prereqList.size()];
for (int _i = 0; _i < prereqList.size(); ++_i)
{
_prereqList[_i] = ((Integer)prereqList.get(_i)).intValue();
}
}
return _prereqList;
}
public int droid_follow(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_follow_other(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW_OTHER))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_stay(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_STAY))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_guard(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_GUARD))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_friend(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_FRIEND))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_attack(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_ATTACK))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_patrol(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_PATROL))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_patrol_point(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_SET_PATROL_POINT))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_patrol_clear(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_CLEAR_PATROL_POINTS))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_store(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_RELEASE))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_transfer(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRANSFER))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_group(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_GROUP))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_trick_1(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_1))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_trick_2(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_2))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_trick_3(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_3))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public int droid_trick_4(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException
{
if (!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_4))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
}
@@ -1,465 +0,0 @@
include library.beast_lib;
include library.buff;
include library.callable;
include library.utils;
include library.pet_lib;
include library.colors;
include library.ai_lib;
include library.chat;
include library.combat;
include library.scout;
include library.create;
include library.vehicle;
include library.sui;
include library.factions;
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
const string STF_FILE = "pet/droid_modules";
const string_id SID_SYS_EMBOLDEN = new string_id("pet/pet_menu","sys_embolden");
const string_id SID_SYS_FAIL_EMBOLDEN = new string_id("pet/pet_menu","sys_fail_embolden");
const string_id SID_SYS_ENRAGE = new string_id("pet/pet_menu","sys_enrage");
const string_id SID_SYS_FAIL_ENRAGE = new string_id("pet/pet_menu","sys_fail_enrage");
const string_id SID_SYS_CANT_BUFF = new string_id("pet/pet_menu","sys_cant_buff");
trigger OnRemovedFromGroup(obj_id group)
{
if(!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
obj_id[] memberList = getGroupMemberIds(group);
if(memberList == null || memberList.length < 1)
{
return SCRIPT_CONTINUE;
}
for (int i = 0; i < memberList.length; i++)
{
if(isIdValid(memberList[i]) && pet_lib.isMyPet(memberList[i], self))
{
queueCommand(memberList[i], ##"leaveGroup", group, "", COMMAND_PRIORITY_DEFAULT);
}
}
return SCRIPT_CONTINUE;
}
trigger OnDefenderCombatAction(obj_id attacker, obj_id weapon, int combatResult)
{
obj_id pet = callable.getCallable(self, callable.CALLABLE_TYPE_COMBAT_PET);
if(isIdValid(pet) && exists(pet) && !ai_lib.isInCombat(pet) && !beast_lib.isBeast(pet) && utils.hasScriptVar(pet, "ai.pet.guarding"))
{
addHate(pet, attacker, 0.0f);
}
return SCRIPT_CONTINUE;
}
commandHandler failPetBuff()
{
// The player can't buff. Probably because of his position.
sendSystemMessage(self, SID_SYS_CANT_BUFF);
return SCRIPT_CONTINUE;
}
trigger OnSkillGranted(string skillName)
{
if(hasObjVar(self, "familiar"))
{
obj_id pet = getObjIdObjVar(self, "familiar");
if(exists(pet) && isInWorld(pet))
{
dictionary trickData = new dictionary();
trickData.put("pet", pet);
trickData.put("trickNum", 2);
trickData.put("heartBeat", false);
messageTo(pet, "doFamiliarTrick", trickData, 1, false);
}
}
return SCRIPT_CONTINUE;
}
trigger OnRemovingFromWorld()
{
if(!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
callable.storeCallables(self);
return SCRIPT_CONTINUE;
}
trigger OnDeath(obj_id killer, obj_id corpseId)
{
if(!callable.hasAnyCallable(self))
{
return SCRIPT_CONTINUE;
}
if(pet_lib.isPet(killer))
{
killer = getMaster(killer);
}
callable.killCallables(self, killer);
return SCRIPT_CONTINUE;
}
commandHandler cmdDetonateDroid()
{
LOG("droid_module", "ai.pet_master.cmdDetonateDroid");
if(!isIdValid(target))
{
target = getLookAtTarget(self);
if(!isIdValid(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "invalid_droid_bomb"));
return SCRIPT_CONTINUE;
}
}
if(!pet_lib.isDroidPet(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "invalid_droid_bomb"));
return SCRIPT_CONTINUE;
}
if(getMaster(target) != self)
{
sendSystemMessage(self, new string_id(STF_FILE, "must_be_owner_droid_bomb"));
return SCRIPT_CONTINUE;
}
if(ai_lib.isAiDead(target))
{
sendSystemMessage(self, new string_id(STF_FILE, "droid_disabled_detonate"));
return SCRIPT_CONTINUE;
}
int bomb_level = getIntObjVar(target, "module_data.bomb_level");
if(bomb_level < 1)
{
sendSystemMessage(self, new string_id(STF_FILE, "no_bomb_module"));
return SCRIPT_CONTINUE;
}
if(!hasSkill(self, "class_smuggler_phase1_novice") && !hasSkill(self, "class_bountyhunter_phase1_novice"))
{
sendSystemMessage(self, new string_id(STF_FILE, "insufficient_skill_detonate"));
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(target, "droid_module.countdown"))
{
sendSystemMessage(self, new string_id(STF_FILE, "countdown_already_started"));
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(self, "droid.bomb_droid_active") &&
utils.getIntScriptVar(self, "droid.bomb_droid_active") > getGameTime())
{
sendSystemMessage(self, new string_id(STF_FILE, "countdown_already_started"));
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(target, "module_data.detonation_warmup"))
{
sendSystemMessage(self, new string_id(STF_FILE, "detonation_warmup"));
return SCRIPT_CONTINUE;
}
// Start the countdown
utils.setScriptVar(target, "droid_module.countdown", 1);
dictionary d = new dictionary();
d.put("master", self);
d.put("count", 3);
messageTo(target, "msgDetonationCountdown", d, 1.0f, false);
sendSystemMessage(self, new string_id(STF_FILE, "countdown_started"));
// Flag player with active detonation droid
utils.setScriptVar(self, "droid.bomb_droid_active", (getGameTime() + 10));
return SCRIPT_CONTINUE;
}
messageHandler clearBombDroidTimer()
{
if(utils.hasScriptVar(self, "droid.bomb_droid_active"))
{
utils.removeScriptVar(self, "droid.bomb_droid_active");
}
return SCRIPT_CONTINUE;
}
boolean hasPrereq(obj_id pet, int ability)
{
if(!isIdValid(pet) || !exists(pet))
{
return false;
}
obj_id pcd = callable.getCallableCD(pet);
int[] abilityList = getIntArrayObjVar(pcd, "ai.petAbility.abilityList");
if(abilityList == null || abilityList.length == 0)
{
return false;
}
return (hasPrereq(abilityList, ability));
}
boolean hasPrereq(int[] abilityList, int ability)
{
int row = dataTableSearchColumnForInt(ability, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if(row == -1)
{
return false;
}
dictionary abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
string prereq = abilityData.getString("prereq");
if(prereq == null || prereq.equals(""))
{
return true;
}
int prereqCrc = getStringCrc(prereq.toLowerCase());
if(utils.getElementPositionInArray(abilityList, prereqCrc) != -1)
{
return true;
}
return false;
}
int[] buildPrereqList(int ability)
{
resizeable int[] prereqList = new int[0];
// Create list of pre & post-reqs for a given ability
int row = dataTableSearchColumnForInt(ability, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if(row == -1)
{
return null;
}
dictionary abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
string prereq = abilityData.getString("prereq");
if(prereq == null || prereq.equals(""))
{
return null;
}
int prereqCrc = getStringCrc(prereq.toLowerCase());
while(prereqCrc != 0)
{
// Validate prereq
row = dataTableSearchColumnForInt(prereqCrc, "abilityCrc", pet_lib.PET_ABILITY_TABLE);
if(row == -1)
{
break;
}
// Add prereq to list
prereqList = utils.addElement(prereqList, prereqCrc);
// Find next prereq
abilityData = dataTableGetRow(pet_lib.PET_ABILITY_TABLE, row);
prereq = abilityData.getString("prereq");
if(prereq == null || prereq.equals(""))
{
break;
}
prereqCrc = getStringCrc(prereq.toLowerCase());
}
return prereqList;
}
commandHandler droid_follow()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_follow_other()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_FOLLOW_OTHER))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_stay()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_STAY))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_guard()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_GUARD))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_friend()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_FRIEND))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_attack()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_ATTACK))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_patrol()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_PATROL))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_patrol_point()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_SET_PATROL_POINT))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_patrol_clear()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_CLEAR_PATROL_POINTS))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_store()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_RELEASE))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_transfer()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRANSFER))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_group()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_GROUP))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_trick_1()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_1))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_trick_2()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_2))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_trick_3()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_3))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
commandHandler droid_trick_4()
{
if(!pet_lib.doCommandNum(self, pet_lib.COMMAND_TRICK_4))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,214 @@
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.callable;
import script.library.pet_lib;
import script.library.utils;
public class pet_ping extends script.base_script
{
public pet_ping()
{
}
public static final String PCDPING_PCD_SCRIPT_NAME = "ai.pcd_ping_response";
public static final String PCDPING_SEND_MESSAGE_NUMBER = "pcdping.sendMsgNumber";
public static final String PCDPING_LAST_ACK_MESSAGE_NUMBER = "pcdping.lastAckNumber";
public static final String PCDPING_MESSAGE_PET_ID_NAME = "petId";
public static final String PCDPING_MESSAGE_MESSAGE_ID_NAME = "messageId";
public static final String PCDPING_MESSAGE_RIDER_ID_NAME = "riderId";
public static final String PCDPING_PING_CALLBACK_NAME = "petPingCallback";
public static final String PCDPING_PCD_MESSAGEHANDLER_NAME = "handlePetPing";
public static final int PCDPING_MAX_UNACKNOWLEDGED_MESSAGE_COUNT = 3;
public static final int PCDPING_PING_INTERVAL_INITIAL = 1;
public static final int PCDPING_PING_INTERVAL_STANDARD = 300;
public static final int PCDPING_PING_INTERVAL_RETRY = 30;
public static final boolean debug = false;
public int OnAttach(obj_id self) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.OnAttach(): self = [" + self + "] entered");
}
setObjVar(self, PCDPING_SEND_MESSAGE_NUMBER, 0);
setObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER, 0);
messageTo(self, PCDPING_PING_CALLBACK_NAME, null, PCDPING_PING_INTERVAL_INITIAL, false);
if (debug)
{
LOG("pcdping-debug", "pet_ping.OnAttach(): self = [" + self + "] exited");
}
return SCRIPT_CONTINUE;
}
public int petPingCallback(obj_id self, dictionary params) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] entered");
}
obj_id player = getRiderId(self);
if (!isValidId(player) && pet_lib.isMount(self))
{
pet_lib.storePet(self);
return SCRIPT_CONTINUE;
}
final int previousMessageNumber = getIntObjVar(self, PCDPING_SEND_MESSAGE_NUMBER);
final int newMessageNumber = previousMessageNumber + 1;
setObjVar(self, PCDPING_SEND_MESSAGE_NUMBER, newMessageNumber);
if (previousMessageNumber == 0)
{
ensurePcdHasSisterScript(self);
}
final int mostRecentAcknowledgedMessageNumber = getIntObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER);
final int unacknowledgedGap = previousMessageNumber - mostRecentAcknowledgedMessageNumber;
if (unacknowledgedGap > PCDPING_MAX_UNACKNOWLEDGED_MESSAGE_COUNT)
{
boolean killSuccess = doPingBasedKill(self, "pet received no acknowledgement from PCD, killing pet with unacknowleged gap=[" + unacknowledgedGap + "]. PCD appears to be unloaded.");
if (killSuccess)
{
return SCRIPT_CONTINUE;
}
else
{
LOG("mounts-bug", "pet_ping.petPingCallback(): doPingBasedKill() failed for pet=[" + self + "], continuing ping loop so that we can try to kill it later.");
}
}
final int nextCallbackInterval = (unacknowledgedGap <= 0) ? PCDPING_PING_INTERVAL_STANDARD : PCDPING_PING_INTERVAL_RETRY;
obj_id controlDevice = callable.getCallableCD(self);
final boolean hasValidPcd = isIdValid(controlDevice);
if (!hasValidPcd)
{
boolean killSuccess = doPingBasedKill(self, "pet does not have a valid PCD objvar");
if (killSuccess)
{
return SCRIPT_CONTINUE;
}
else
{
LOG("mounts-bug", "pet_ping.petPingCallback(): doPingBasedKill() failed for pet=[" + self + "], continuing ping loop so that we can try to kill it later.");
}
}
else
{
dictionary messageData = new dictionary();
messageData.put(PCDPING_MESSAGE_PET_ID_NAME, self);
messageData.put(PCDPING_MESSAGE_MESSAGE_ID_NAME, newMessageNumber);
obj_id riderId = getRiderId(self);
if (isIdValid(riderId))
{
messageData.put(PCDPING_MESSAGE_RIDER_ID_NAME, riderId);
}
messageTo(controlDevice, PCDPING_PCD_MESSAGEHANDLER_NAME, messageData, 1, false);
if (debug)
{
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] sent ping message to PCD.");
}
}
messageTo(self, PCDPING_PING_CALLBACK_NAME, null, nextCallbackInterval, false);
if (debug)
{
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] exited");
}
return SCRIPT_CONTINUE;
}
public int handlePositiveAcknowledgementFromPcd(obj_id self, dictionary params) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): self = [" + self + "] entered");
}
final int ackMessageNumber = params.getInt(PCDPING_MESSAGE_MESSAGE_ID_NAME);
final int mostRecentAckMessageNumber = getIntObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER);
if (ackMessageNumber > mostRecentAckMessageNumber)
{
setObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER, ackMessageNumber);
if (debug)
{
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): processed newer positive PCD ack number=[" + ackMessageNumber + "]");
}
}
else
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): discarded older positive PCD ack number=[" + ackMessageNumber + "], highest ack is [" + mostRecentAckMessageNumber + "]");
}
}
if (debug)
{
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): self = [" + self + "] exited");
}
return SCRIPT_CONTINUE;
}
public int handleNegativeAcknowledgementFromPcd(obj_id self, dictionary params) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] entered");
}
final boolean killSuccess = doPingBasedKill(self, "PCD indicated that this pet should not exist");
if (debug)
{
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] attempted to kill pet per PCD request. killSuccess=[" + killSuccess + "]");
}
if (debug)
{
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] exited");
}
return SCRIPT_CONTINUE;
}
public boolean doPingBasedKill(obj_id pet, String reason) throws InterruptedException
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.doPingBasedKill(): pet = [" + pet + "] entered");
}
LOG("pcdping-kill", "Killing pet id=[" + pet + "]: reason=[" + reason + "]");
obj_id rider = getRiderId(pet);
if (isIdValid(rider))
{
boolean dismountSuccess = pet_lib.doDismountNow(rider);
if (!dismountSuccess)
{
LOG("mounts-bug", "pet_ping.doPingBasedKill(): creature [" + pet + "], rider [" + rider + "] failed to dismount. Will still try to kill the pet.");
}
}
obj_id petControlDevice = callable.getCallableCD(pet);
pet_lib.savePetInfo(pet, petControlDevice);
utils.setScriptVar(pet, "stored", true);
boolean killSuccess = destroyObject(pet);
if (!killSuccess)
{
LOG("pcdping-kill", "failed to destroy pet=[" + pet + "].");
}
if (debug)
{
LOG("pcdping-debug", "pet_ping.doPingBasedKill(): pet = [" + pet + "] exited");
}
return killSuccess;
}
public void ensurePcdHasSisterScript(obj_id pet) throws InterruptedException
{
obj_id controlDevice = callable.getCallableCD(pet);
if (isIdValid(controlDevice) && !hasScript(controlDevice, PCDPING_PCD_SCRIPT_NAME))
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.ensurePcdHasSisterScript(): attaching script [" + PCDPING_PCD_SCRIPT_NAME + "] to PCD id=[" + controlDevice + "]");
}
attachScript(controlDevice, PCDPING_PCD_SCRIPT_NAME);
}
else
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.ensurePcdHasSisterScript(): couldn't attach script [" + PCDPING_PCD_SCRIPT_NAME + "] to PCD because didn't have objvar");
}
}
}
}
@@ -1,297 +0,0 @@
//----------------------------------------------------------
// pet_ping.script
// -----------------------------------------------------------------------
// This script is a re-hash of vehicle_ping.script, altered to function for pets
// Original script notes listed below.
//
// This script is attached to a vehicle. It is setup to
// send a ping to the vehicle's vehicle control device (PCD).
// If the PCD does not respond to the ping in a timely fashion
// or it responds with an indication that this vehicle is not
// supposed to be out, the vehicle is destroyed. A positive
// acknowledgement from the PCD is required for the vehicle
// to continue to exist in the world.
//----------------------------------------------------------
include library.callable;
include library.pet_lib;
include library.utils;
//----------------------------------------------------------
const string PCDPING_PCD_SCRIPT_NAME = "ai.pcd_ping_response";
const string PCDPING_SEND_MESSAGE_NUMBER = "pcdping.sendMsgNumber";
const string PCDPING_LAST_ACK_MESSAGE_NUMBER = "pcdping.lastAckNumber";
const string PCDPING_MESSAGE_PET_ID_NAME = "petId";
const string PCDPING_MESSAGE_MESSAGE_ID_NAME = "messageId";
const string PCDPING_MESSAGE_RIDER_ID_NAME = "riderId";
const string PCDPING_PING_CALLBACK_NAME = "petPingCallback";
const string PCDPING_PCD_MESSAGEHANDLER_NAME = "handlePetPing";
const int PCDPING_MAX_UNACKNOWLEDGED_MESSAGE_COUNT = 3;
const int PCDPING_PING_INTERVAL_INITIAL = 1;
const int PCDPING_PING_INTERVAL_STANDARD = 300;
const int PCDPING_PING_INTERVAL_RETRY = 30;
const boolean debug = false;
//----------------------------------------------------------
trigger OnAttach()
{
if (debug)
LOG("pcdping-debug", "pet_ping.OnAttach(): self = [" + self + "] entered");
//-- Initialize pcd ping variables.
// Note: these objvars are not expensive because pets are not persisted.
setObjVar(self, PCDPING_SEND_MESSAGE_NUMBER, 0);
setObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER, 0);
//-- Kick off the first ping heartbeat now.
messageTo(self, PCDPING_PING_CALLBACK_NAME, null, PCDPING_PING_INTERVAL_INITIAL, false);
if (debug)
LOG("pcdping-debug", "pet_ping.OnAttach(): self = [" + self + "] exited");
return SCRIPT_CONTINUE;
}
//----------------------------------------------------------
/**
* This is the heartbeat callback function for the pet/pcd ping system.
*/
messageHandler petPingCallback()
{
if (debug)
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] entered");
obj_id player = getRiderId(self);
if(!isValidId(player) && pet_lib.isMount(self))
{
pet_lib.storePet(self);
return SCRIPT_CONTINUE;
}
//-- Setup the new pet ping message number. These get incremented by 1 each ping callback.
const int previousMessageNumber = getIntObjVar(self, PCDPING_SEND_MESSAGE_NUMBER);
const int newMessageNumber = previousMessageNumber + 1;
setObjVar(self, PCDPING_SEND_MESSAGE_NUMBER, newMessageNumber);
//-- If previousMessageNumber == 0, this means we're just starting.
if (previousMessageNumber == 0)
ensurePcdHasSisterScript(self);
//-- Retrieve the last PCD-acknowledged message number.
const int mostRecentAcknowledgedMessageNumber = getIntObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER);
//-- Check if we've exceeded the maximum number of unacknowledged
const int unacknowledgedGap = previousMessageNumber - mostRecentAcknowledgedMessageNumber;
if (unacknowledgedGap > PCDPING_MAX_UNACKNOWLEDGED_MESSAGE_COUNT)
{
boolean killSuccess = doPingBasedKill(self, "pet received no acknowledgement from PCD, killing pet with unacknowleged gap=[" + unacknowledgedGap + "]. PCD appears to be unloaded.");
if (killSuccess)
return SCRIPT_CONTINUE;
else
{
LOG("mounts-bug", "pet_ping.petPingCallback(): doPingBasedKill() failed for pet=[" + self + "], continuing ping loop so that we can try to kill it later.");
// continue through here so we requeue the callback for another attempt (or possible recovery) later.
}
}
//-- Determine next callback interval based on whether our most recent send was acknowledged.
// If our most recent send has been acknowledged, use the infrequent, standard time interval
// for this callback. Otherwise accelerate the ping so we get rid of this suspect pet
// more rapidly.
const int nextCallbackInterval = (unacknowledgedGap <= 0) ? PCDPING_PING_INTERVAL_STANDARD : PCDPING_PING_INTERVAL_RETRY;
//-- Setup ping message to the pet control device.
// Get the PCD id.
obj_id controlDevice = callable.getCallableCD(self);
const boolean hasValidPcd = isIdValid(controlDevice);
if (!hasValidPcd)
{
boolean killSuccess = doPingBasedKill(self, "pet does not have a valid PCD objvar");
if (killSuccess)
return SCRIPT_CONTINUE;
else
{
LOG("mounts-bug", "pet_ping.petPingCallback(): doPingBasedKill() failed for pet=[" + self + "], continuing ping loop so that we can try to kill it later.");
// continue through here so we requeue the callback for another attempt (or possible recovery) later.
}
}
else
{
// Construct the dictionary of info about this pet that we'll pass to the PCD.
dictionary messageData = new dictionary();
messageData.put(PCDPING_MESSAGE_PET_ID_NAME, self);
messageData.put(PCDPING_MESSAGE_MESSAGE_ID_NAME, newMessageNumber);
// If this pet has a rider, include the rider id.
obj_id riderId = getRiderId(self);
if (isIdValid(riderId))
messageData.put(PCDPING_MESSAGE_RIDER_ID_NAME, riderId);
// Send the ping message to the PCD, get it there as fast as possible.
messageTo(controlDevice, PCDPING_PCD_MESSAGEHANDLER_NAME, messageData, 1, false);
if (debug)
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] sent ping message to PCD.");
}
//-- Enqueue next pet ping callback.
messageTo(self, PCDPING_PING_CALLBACK_NAME, null, nextCallbackInterval, false);
if (debug)
LOG("pcdping-debug", "pet_ping.petPingCallback(): self = [" + self + "] exited");
return SCRIPT_CONTINUE;
}
//----------------------------------------------------------
/**
* This message is sent by the PCD and received by the pet
* when the PCD is in agreement that this pet should be out.
*/
messageHandler handlePositiveAcknowledgementFromPcd()
{
if (debug)
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): self = [" + self + "] entered");
//-- Extract the acknowledgement message number from the message data.
const int ackMessageNumber = params.getInt(PCDPING_MESSAGE_MESSAGE_ID_NAME);
//-- Retrieve the last acknowledged message number for the pet.
const int mostRecentAckMessageNumber = getIntObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER);
//-- Apply message ack number if it is larger than the largest ack number we've seen so far.
if (ackMessageNumber > mostRecentAckMessageNumber)
{
// This message is an ack to a newer message number than the previous highest ack. Store it.
setObjVar(self, PCDPING_LAST_ACK_MESSAGE_NUMBER, ackMessageNumber);
if (debug)
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): processed newer positive PCD ack number=[" + ackMessageNumber + "]");
}
else
{
// Skip this ack --- it's an ack for an older message when we've already received a newer one.
if (debug)
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): discarded older positive PCD ack number=[" + ackMessageNumber + "], highest ack is [" + mostRecentAckMessageNumber + "]");
}
if (debug)
LOG("pcdping-debug", "pet_ping.handlePositiveAcknowledgementFromPcd(): self = [" + self + "] exited");
return SCRIPT_CONTINUE;
}
//----------------------------------------------------------
/**
* This message is sent by the PCD and received by the pet
* when the PCD does not believe this pet should be out.
*/
messageHandler handleNegativeAcknowledgementFromPcd()
{
if (debug)
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] entered");
//-- Destroy the pet now.
const boolean killSuccess = doPingBasedKill(self, "PCD indicated that this pet should not exist");
if (debug)
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] attempted to kill pet per PCD request. killSuccess=[" + killSuccess + "]");
if (debug)
LOG("pcdping-debug", "pet_ping.handleNegativeAcknowledgementFromPcd(): self = [" + self + "] exited");
return SCRIPT_CONTINUE;
}
//----------------------------------------------------------
boolean doPingBasedKill(obj_id pet, string reason)
{
if(debug)
LOG("pcdping-debug", "pet_ping.doPingBasedKill(): pet = [" + pet + "] entered");
//-- Log the ping-based kill.
LOG("pcdping-kill", "Killing pet id=[" + pet + "]: reason=[" + reason + "]");
//-- Destroy the pet.
// Dismount the rider of this mount/pet if there's anything on it.
obj_id rider = getRiderId(pet);
if(isIdValid(rider))
{
// Do the dismount immediately.
boolean dismountSuccess = pet_lib.doDismountNow(rider);
if(!dismountSuccess)
{
LOG("mounts-bug", "pet_ping.doPingBasedKill(): creature [" + pet + "], rider [" + rider + "] failed to dismount. Will still try to kill the pet.");
}
}
// Destroy the pet.
obj_id petControlDevice = callable.getCallableCD(pet);
pet_lib.savePetInfo(pet, petControlDevice);
utils.setScriptVar(pet, "stored", true);
boolean killSuccess = destroyObject(pet);
if(!killSuccess)
{
LOG("pcdping-kill", "failed to destroy pet=[" + pet + "].");
}
if(debug)
{
LOG("pcdping-debug", "pet_ping.doPingBasedKill(): pet = [" + pet + "] exited");
}
return killSuccess;
}
//----------------------------------------------------------
void ensurePcdHasSisterScript(obj_id pet)
{
//-- Double check that the PCD for this pet has the PCD sister script attached.
// @todo might as well handle this here and remove the one that attaches the script
// to the PCD via the pet_control_device.script's OnInitialize() trigger.
// Get the pet control device.
obj_id controlDevice = callable.getCallableCD(pet);
// Ensure that the PCD has the pet ping response script attached.
if(isIdValid(controlDevice) && !hasScript(controlDevice, PCDPING_PCD_SCRIPT_NAME))
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.ensurePcdHasSisterScript(): attaching script [" + PCDPING_PCD_SCRIPT_NAME + "] to PCD id=[" + controlDevice + "]");
}
attachScript(controlDevice, PCDPING_PCD_SCRIPT_NAME);
}
else
{
if (debug)
{
LOG("pcdping-debug", "pet_ping.ensurePcdHasSisterScript(): couldn't attach script [" + PCDPING_PCD_SCRIPT_NAME + "] to PCD because didn't have objvar");
}
}
}
//----------------------------------------------------------
@@ -0,0 +1,57 @@
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.stealth;
import script.library.utils;
public class random_player_target extends script.base_script
{
public random_player_target()
{
}
public void addHateToTarget(obj_id self) throws InterruptedException
{
if (ai_lib.isDead(self))
{
return;
}
obj_id target = null;
obj_id[] targets = getPlayerCreaturesInRange(getLocation(self), 64f);
if (targets == null || targets.length <= 0)
{
return;
}
target = targets[rand(0, targets.length - 1)];
if (!isIdValid(target) || isIncapacitated(target) || isDead(target) || stealth.hasInvisibleBuff(target))
{
return;
}
if (!canSee(self, target))
{
stopCombat(self);
}
utils.setScriptVar(self, "lastTargetSwitchTime", getGameTime());
addHate(self, target, 5000);
}
public int OnAiCombatFrame(obj_id self) throws InterruptedException
{
if (!isIdValid(self))
{
return SCRIPT_CONTINUE;
}
int lastTime = utils.getIntScriptVar(self, "lastTargetSwitchTime");
if (getGameTime() - lastTime > 10)
{
addHateToTarget(self);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,57 +0,0 @@
include library.ai_lib;
include library.stealth;
include library.utils;
void addHateToTarget(obj_id self)
{
if(ai_lib.isDead(self))
{
return;
}
obj_id target = null;
// debugSpeakMsg(self, "Acquiring target...");
// Get a new target
obj_id[] targets = getPlayerCreaturesInRange(getLocation(self), 64f);
if(targets == null || targets.length <= 0)
{
return;
}
target = targets[rand(0, targets.length - 1)];
if(!isIdValid(target) || isIncapacitated(target) || isDead(target) || stealth.hasInvisibleBuff(target))
{
return;
}
if(!canSee(self, target))
{
stopCombat(self);
}
utils.setScriptVar(self, "lastTargetSwitchTime", getGameTime());
// Add more hate to a random target
addHate(self, target, 5000);
}
trigger OnAiCombatFrame()
{
if(!isIdValid(self))
{
return SCRIPT_CONTINUE;
}
int lastTime = utils.getIntScriptVar(self, "lastTargetSwitchTime");
if(getGameTime() - lastTime > 10)
{
addHateToTarget(self);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,138 @@
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.chat;
import script.library.prose;
import script.library.utils;
import script.library.xp;
public class smuggler_buddy extends script.base_script
{
public smuggler_buddy()
{
}
public static final float BUDDY_DURATION = 62.0f;
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "handleGreeting", null, 2.0f, false);
messageTo(self, "handleRunAway", null, BUDDY_DURATION, false);
setObjVar(self, "ai.pet", true);
return SCRIPT_CONTINUE;
}
public int OnExitedCombat(obj_id self) throws InterruptedException
{
if (utils.hasScriptVar(self, "runningaway"))
{
return SCRIPT_CONTINUE;
}
messageTo(self, "handleNewTarget", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
public int handleGreeting(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
String name = getFirstName(master);
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", "smuggler_buddy_greeting"));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
return SCRIPT_CONTINUE;
}
public int handleNewTarget(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
obj_id newTarget = getHateTarget(master);
if (isIdValid(newTarget))
{
startCombat(self, newTarget);
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
return SCRIPT_CONTINUE;
}
public int handleRunAway(obj_id self, dictionary params) throws InterruptedException
{
if (isDead(self))
{
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "runningaway"))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master))
{
String name = getFirstName(master);
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", "smuggler_buddy_goodbye"));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
stopCombat(self);
setMaster(self, null);
setInvulnerable(self, true);
if (isIdValid(master))
{
ai_lib.pathAwayFrom(self, master);
}
utils.setScriptVar(self, "runningaway", 1);
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
public int handleCleanUp(obj_id self, dictionary params) throws InterruptedException
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
public int OnIncapacitated(obj_id self, obj_id attacker) throws InterruptedException
{
obj_id weapon = getCurrentWeapon(self);
if (isIdValid(weapon) && !isDefaultWeapon(weapon))
{
destroyObject(weapon);
}
obj_id cInv = utils.getInventoryContainer(self);
if (isIdValid(cInv))
{
utils.emptyContainerExceptStorytellerLoot(cInv);
}
ai_lib.clearCombatData();
setObjVar(self, xp.VAR_LANDED_DEATHBLOW, attacker);
if (!kill(self))
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for (int i = 0; i < haters.length; i++)
{
removeHateTarget(haters[i], self);
}
}
destroyObject(self);
}
clearCondition(self, CONDITION_INTERESTING);
return SCRIPT_CONTINUE;
}
}
@@ -1,154 +0,0 @@
include library.ai_lib;
include library.chat;
include library.prose;
include library.utils;
include library.xp;
// This is the length of time that the buddy stays around before running away.
const float BUDDY_DURATION = 62.0f;
trigger OnAttach()
{
messageTo(self, "handleGreeting", null, 2.0f, false);
messageTo(self, "handleRunAway", null, BUDDY_DURATION, false);
setObjVar( self, "ai.pet", true );
return SCRIPT_CONTINUE;
}
trigger OnExitedCombat()
{
if(utils.hasScriptVar(self, "runningaway"))
return SCRIPT_CONTINUE;
messageTo(self, "handleNewTarget", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleGreeting()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
string name = getFirstName(master);
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", "smuggler_buddy_greeting"));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
return SCRIPT_CONTINUE;
}
messageHandler handleNewTarget()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
obj_id newTarget = getHateTarget(master);
if(isIdValid(newTarget))
startCombat(self, newTarget);
else
messageTo(self, "handleRunAway", null, 2.0f, false);
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
return SCRIPT_CONTINUE;
}
messageHandler handleRunAway()
{
if(isDead(self))
{
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(self, "runningaway"))
return SCRIPT_CONTINUE;
obj_id master = getMaster(self);
if(isIdValid(master))
{
string name = getFirstName(master);
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", "smuggler_buddy_goodbye"));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
stopCombat(self);
setMaster(self, null);
setInvulnerable(self, true);
if(isIdValid(master))
ai_lib.pathAwayFrom(self, master);
utils.setScriptVar(self, "runningaway", 1);
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleCleanUp()
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
trigger OnIncapacitated(obj_id attacker)
{
obj_id weapon = getCurrentWeapon(self);
if( isIdValid(weapon) && !isDefaultWeapon(weapon) )
{
destroyObject(weapon);
}
//clear corpse inventory
obj_id cInv = utils.getInventoryContainer(self);
if(isIdValid(cInv))
{
utils.emptyContainerExceptStorytellerLoot(cInv);
}
ai_lib.clearCombatData();
setObjVar(self, xp.VAR_LANDED_DEATHBLOW, attacker);
if(!kill(self))
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for(int i=0;i<haters.length;i++)
{
removeHateTarget(haters[i], self);
}
}
destroyObject(self);
}
clearCondition(self, CONDITION_INTERESTING);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,185 @@
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.buff;
import script.library.chat;
import script.library.prose;
import script.library.utils;
import script.library.xp;
public class smuggler_medic extends script.base_script
{
public smuggler_medic()
{
}
public static final float BUDDY_DURATION = 62.0f;
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "handleGreeting", null, 2.0f, false);
messageTo(self, "handleRunAway", null, BUDDY_DURATION, false);
messageTo(self, "castOnMaster", null, 1.0f, false);
setObjVar(self, "ai.pet", true);
return SCRIPT_CONTINUE;
}
public int OnExitedCombat(obj_id self) throws InterruptedException
{
if (utils.hasScriptVar(self, "runningaway"))
{
return SCRIPT_CONTINUE;
}
messageTo(self, "handleNewTarget", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
public int castOnMaster(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
float healthPercent = (float)getAttrib(master, HEALTH) / (float)getMaxAttrib(master, HEALTH);
int myLevel = getLevel(self);
if (healthPercent < 0.50f)
{
if (myLevel < 10)
{
queueCommand(self, (1178893546), master, "", COMMAND_PRIORITY_FRONT);
}
else if (myLevel < 30)
{
queueCommand(self, (1258773043), master, "", COMMAND_PRIORITY_FRONT);
}
else if (myLevel < 58)
{
queueCommand(self, (1338394500), master, "", COMMAND_PRIORITY_FRONT);
}
else if (myLevel < 78)
{
queueCommand(self, (1367414657), master, "", COMMAND_PRIORITY_FRONT);
}
else if (myLevel < 91)
{
queueCommand(self, (1430260278), master, "", COMMAND_PRIORITY_FRONT);
}
}
else
{
if (myLevel >= 46 && !buff.hasBuff(master, "me_buff_health"))
{
queueCommand(self, (-1176506063), master, "", COMMAND_PRIORITY_FRONT);
}
}
}
messageTo(self, "castOnMaster", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
public int handleGreeting(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
String name = getFirstName(master);
int phraseId = rand(1, 6);
String greeting = "smuggler_medic_greeting_" + phraseId;
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", greeting));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
return SCRIPT_CONTINUE;
}
public int handleNewTarget(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
obj_id newTarget = getHateTarget(master);
if (isIdValid(newTarget))
{
startCombat(self, newTarget);
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
return SCRIPT_CONTINUE;
}
public int handleRunAway(obj_id self, dictionary params) throws InterruptedException
{
if (isDead(self))
{
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "runningaway"))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master))
{
String name = getFirstName(master);
int phraseId = rand(1, 6);
String goodbye = "smuggler_medic_goodbye_" + phraseId;
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", goodbye));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
stopCombat(self);
setMaster(self, null);
setInvulnerable(self, true);
if (isIdValid(master))
{
ai_lib.pathAwayFrom(self, master);
}
utils.setScriptVar(self, "runningaway", 1);
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
public int handleCleanUp(obj_id self, dictionary params) throws InterruptedException
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
public int OnIncapacitated(obj_id self, obj_id attacker) throws InterruptedException
{
obj_id weapon = getCurrentWeapon(self);
if (isIdValid(weapon) && !isDefaultWeapon(weapon))
{
destroyObject(weapon);
}
obj_id cInv = utils.getInventoryContainer(self);
if (isIdValid(cInv))
{
utils.emptyContainerExceptStorytellerLoot(cInv);
}
ai_lib.clearCombatData();
setObjVar(self, xp.VAR_LANDED_DEATHBLOW, attacker);
if (!kill(self))
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for (int i = 0; i < haters.length; i++)
{
removeHateTarget(haters[i], self);
}
}
destroyObject(self);
}
clearCondition(self, CONDITION_INTERESTING);
return SCRIPT_CONTINUE;
}
}
@@ -1,216 +0,0 @@
include library.ai_lib;
include library.buff;
include library.chat;
include library.prose;
include library.utils;
include library.xp;
// This is the length of time that the buddy stays around before running away.
const float BUDDY_DURATION = 62.0f;
trigger OnAttach()
{
messageTo(self, "handleGreeting", null, 2.0f, false);
messageTo(self, "handleRunAway", null, BUDDY_DURATION, false);
messageTo(self, "castOnMaster", null, 1.0f, false);
setObjVar( self, "ai.pet", true );
return SCRIPT_CONTINUE;
}
trigger OnExitedCombat()
{
if(utils.hasScriptVar(self, "runningaway"))
return SCRIPT_CONTINUE;
messageTo(self, "handleNewTarget", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
// This function does not need to take into account current action, as the summoned medic only lasts for a short time.
messageHandler castOnMaster()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
float healthPercent = (float)getAttrib(master, HEALTH) / (float)getMaxAttrib(master, HEALTH);
int myLevel = getLevel(self);
if(healthPercent < 0.50f)
{
if(myLevel < 10)
{
queueCommand(self, ##"me_bacta_grenade_1", master, "", COMMAND_PRIORITY_FRONT);
}
else
if(myLevel < 30)
{
queueCommand(self, ##"me_bacta_grenade_2", master, "", COMMAND_PRIORITY_FRONT);
}
else
if(myLevel < 58)
{
queueCommand(self, ##"me_bacta_grenade_3", master, "", COMMAND_PRIORITY_FRONT);
}
else
if(myLevel < 78)
{
queueCommand(self, ##"me_bacta_grenade_4", master, "", COMMAND_PRIORITY_FRONT);
}
else
if(myLevel < 91)
{
queueCommand(self, ##"me_bacta_grenade_5", master, "", COMMAND_PRIORITY_FRONT);
}
}
else
{
// Medic's Health Buff is gained at level 46.
if(myLevel >= 46 && !buff.hasBuff(master, "me_buff_health"))
{
queueCommand(self, ##"me_buff_health_1", master, "", COMMAND_PRIORITY_FRONT);
}
}
}
messageTo(self, "castOnMaster", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleGreeting()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
string name = getFirstName(master);
int phraseId = rand(1, 6);
string greeting = "smuggler_medic_greeting_" + phraseId;
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", greeting));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
return SCRIPT_CONTINUE;
}
messageHandler handleNewTarget()
{
obj_id master = getMaster(self);
if(isIdValid(master))
{
obj_id newTarget = getHateTarget(master);
if(isIdValid(newTarget))
startCombat(self, newTarget);
else
messageTo(self, "handleRunAway", null, 2.0f, false);
}
else
{
messageTo(self, "handleRunAway", null, 2.0f, false);
}
return SCRIPT_CONTINUE;
}
messageHandler handleRunAway()
{
if(isDead(self))
{
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
if(utils.hasScriptVar(self, "runningaway"))
return SCRIPT_CONTINUE;
obj_id master = getMaster(self);
if(isIdValid(master))
{
string name = getFirstName(master);
int phraseId = rand(1, 6);
string goodbye = "smuggler_medic_goodbye_" + phraseId;
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("combat_effects", goodbye));
pp = prose.setTU(pp, name);
chat.chat(self, master, chat.CHAT_SAY, null, chat.ChatFlag_targetGroupOnly, pp);
}
stopCombat(self);
setMaster(self, null);
setInvulnerable(self, true);
if(isIdValid(master))
ai_lib.pathAwayFrom(self, master);
utils.setScriptVar(self, "runningaway", 1);
messageTo(self, "handleCleanUp", null, 15.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleCleanUp()
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
trigger OnIncapacitated(obj_id attacker)
{
obj_id weapon = getCurrentWeapon(self);
if( isIdValid(weapon) && !isDefaultWeapon(weapon) )
{
destroyObject(weapon);
}
//clear corpse inventory
obj_id cInv = utils.getInventoryContainer(self);
if(isIdValid(cInv))
{
utils.emptyContainerExceptStorytellerLoot(cInv);
}
ai_lib.clearCombatData();
setObjVar(self, xp.VAR_LANDED_DEATHBLOW, attacker);
if(!kill(self))
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for(int i=0;i<haters.length;i++)
{
removeHateTarget(haters[i], self);
}
}
destroyObject(self);
}
clearCondition(self, CONDITION_INTERESTING);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,514 @@
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.chat;
import script.library.buff;
import script.library.utils;
import script.library.combat;
import script.library.groundquests;
import script.library.factions;
import script.library.smuggler;
public class smuggler_spawn_enemy extends script.base_script
{
public smuggler_spawn_enemy()
{
}
public static final String STRING_FILE = "smuggler/enemy";
public static final int FLAG_CLEAN_UP = 1;
public static final int FLAG_ATTACK = 2;
public static final int FLAG_FOLLOW = 3;
public static final String VOL_PATROL_WATCH = "smugglerPatrolWatch";
public static final float VOL_PATROL_RANGE = 12.0f;
public int OnAttach(obj_id self) throws InterruptedException
{
messageTo(self, "startContrabandCheck", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
public void doSnare(obj_id playerSmuggler, obj_id npc) throws InterruptedException
{
if (isIncapacitated(npc))
{
return;
}
if (isIncapacitated(playerSmuggler))
{
return;
}
if (utils.hasScriptVar(npc, "fastTalked"))
{
return;
}
int taunt = rand(1, 5);
if (taunt == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_snare");
chat.chat(npc, barkString);
}
buff.applyBuff(playerSmuggler, "caltropSnare");
return;
}
public void broadcastCondition(obj_id playerSmuggler, obj_id npc, int flag) throws InterruptedException
{
location here = getLocation(npc);
obj_id[] objects = getObjectsInRange(here, 32);
for (int i = 0; i < objects.length; i++)
{
if (hasObjVar(objects[i], "quest.owner"))
{
if ((getObjIdObjVar(objects[i], "quest.owner") == playerSmuggler) && (npc != objects[i]))
{
switch (flag)
{
case FLAG_CLEAN_UP:
messageTo(objects[i], "handleCleanUp", null, 1.0f, false);
break;
case FLAG_ATTACK:
if (isIncapacitated(playerSmuggler))
{
break;
}
if (!ai_lib.isInCombat(objects[i]))
{
if (!utils.hasScriptVar(objects[i], "fastTalked"))
{
startCombat(objects[i], playerSmuggler);
}
}
else
{
obj_id enemyTarget = getHateTarget(objects[i]);
if (!isIdValid(enemyTarget))
{
break;
}
if (enemyTarget != playerSmuggler)
{
if (!utils.hasScriptVar(objects[i], "fastTalked"))
{
float hate = getMaxHate(objects[i]);
addHate(objects[i], playerSmuggler, (hate + 1000f));
}
}
}
messageTo(objects[i], "combatLoop", null, 11.0f, false);
break;
case FLAG_FOLLOW:
ai_lib.aiFollow(objects[i], npc, 3f, 6f);
messageTo(objects[i], "handleCleanUp", null, 9.0f, false);
break;
default:
break;
}
}
}
}
return;
}
public void enemyPickFight(obj_id npc, obj_id victimNpc, obj_id playerSmuggler) throws InterruptedException
{
clearHateList(npc);
clearHateList(victimNpc);
utils.setScriptVar(npc, "fastTalked", playerSmuggler);
setMaster(npc, playerSmuggler);
utils.setScriptVar(victimNpc, "fastTalked", playerSmuggler);
startCombat(npc, victimNpc);
startCombat(victimNpc, npc);
addHate(npc, victimNpc, 9999.0f);
addHate(victimNpc, npc, 9999.0f);
string_id barkString = new string_id(STRING_FILE, "bark_myfriend");
chat.chat(npc, barkString);
barkString = new string_id(STRING_FILE, "bark_huh");
chat.chat(victimNpc, barkString);
dictionary params = new dictionary();
params.put("playerSmuggler", playerSmuggler);
messageTo(npc, "endConfusion", params, 15.0f, false);
messageTo(victimNpc, "endConfusion", params, 15.0f, false);
return;
}
public void doConfuse(obj_id playerSmuggler, obj_id npc) throws InterruptedException
{
removeHateTarget(npc, playerSmuggler);
stopCombat(npc);
string_id barkString = new string_id(STRING_FILE, "bark_confused");
chat.chat(npc, barkString);
utils.setScriptVar(npc, "fastTalked", playerSmuggler);
ai_lib.aiStopFollowing(npc);
ai_lib.pathAwayFrom(npc, playerSmuggler);
dictionary params = new dictionary();
params.put("playerSmuggler", playerSmuggler);
messageTo(npc, "endConfusion", params, 15.0f, false);
return;
}
public void doConfuseAttack(obj_id playerSmuggler, obj_id npc) throws InterruptedException
{
location here = getLocation(npc);
obj_id[] objects = getObjectsInRange(here, 25);
obj_id victimEnemy = null;
obj_id enemyTarget = null;
for (int i = 0; i < objects.length; i++)
{
if (hasScript(objects[i], "ai.smuggler_spawn_enemy"))
{
if (objects[i] != npc)
{
victimEnemy = objects[i];
if (ai_lib.isInCombat(objects[i]))
{
enemyTarget = getHateTarget(objects[i]);
if (isIdValid(enemyTarget))
{
if (enemyTarget == playerSmuggler)
{
enemyPickFight(npc, objects[i], playerSmuggler);
return;
}
}
}
}
}
}
if (isIdValid(victimEnemy))
{
enemyPickFight(npc, victimEnemy, playerSmuggler);
}
else
{
doConfuse(playerSmuggler, npc);
}
return;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(breacher))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(VOL_PATROL_WATCH))
{
if (utils.getPlayerProfession(breacher) == utils.SMUGGLER)
{
if (groundquests.isDoingSmugglerMission(breacher))
{
int taunt = rand(1, 10);
if (taunt == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_smuggler");
chat.chat(self, barkString);
int smugglerLevel = combat.getLevel(breacher);
int myLevel = combat.getLevel(self);
if (smugglerLevel > myLevel)
{
int levelDifference = (smugglerLevel - myLevel);
if (levelDifference > 5)
{
barkString = new string_id(STRING_FILE, "bark_help");
chat.chat(self, barkString);
groundquests.sendSignal(breacher, "smugglerPatrolHelp");
}
}
}
doSnare(breacher, self);
startCombat(self, breacher);
}
}
}
return SCRIPT_CONTINUE;
}
public int combatLoop(obj_id self, dictionary params) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "fastTalked"))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if (!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(playerSmuggler))
{
messageTo(self, "handleCleanUp", null, 1.0f, false);
}
float distanceRange = (getLocation(self)).distance(getLocation(playerSmuggler));
if (distanceRange > 256.0f)
{
messageTo(self, "handleCleanUp", null, 1.0f, false);
return SCRIPT_CONTINUE;
}
if (!ai_lib.isInCombat(self))
{
if (!utils.hasScriptVar(self, "fastTalked"))
{
startCombat(self, playerSmuggler);
}
}
if (!buff.hasBuff(playerSmuggler, "caltropSnare"))
{
doSnare(playerSmuggler, self);
}
messageTo(self, "combatLoop", null, 11.0f, false);
}
return SCRIPT_CONTINUE;
}
public int smugglerKilled(obj_id self, dictionary params) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
string_id barkString = new string_id(STRING_FILE, "bark_smack_talk");
chat.chat(self, barkString);
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if (!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
messageTo(self, "handleCleanUp", null, 3.0f, false);
broadcastCondition(playerSmuggler, self, FLAG_CLEAN_UP);
}
return SCRIPT_CONTINUE;
}
public int startContrabandCheck(obj_id self, dictionary params) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
setBaseWalkSpeed(self, 6.0f);
setBaseRunSpeed(self, 9.0f);
setAILeashTime(self, 999999);
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
int randStr = rand(1, 3);
string_id barkString = new string_id(STRING_FILE, "bark_s" + randStr);
if (!ai_lib.isInCombat(self))
{
faceTo(self, playerSmuggler);
chat.chat(self, barkString);
ai_lib.aiFollow(self, playerSmuggler, 3f, 6f);
}
if (hasObjVar(self, "quest.count"))
{
int boss = getIntObjVar(self, "quest.count");
if (boss == 0)
{
if (!ai_lib.isInCombat(self))
{
messageTo(self, "contrabandCheckResult", null, 11.0f, false);
utils.setScriptVar(self, "contrabandCheck", 1);
}
else
{
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
}
}
else
{
createTriggerVolume(VOL_PATROL_WATCH, VOL_PATROL_RANGE, true);
}
return SCRIPT_CONTINUE;
}
public int contrabandCheckResult(obj_id self, dictionary params) throws InterruptedException
{
utils.removeScriptVar(self, "contrabandCheck");
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if (!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
int expertiseIncrease = 0;
int rankIncrease = 0;
if (utils.hasScriptVar(self, "slyLie"))
{
float underworldFaction = factions.getFactionStanding(playerSmuggler, "underworld");
int smugglerRank = smuggler.getSmugglerRank(underworldFaction);
expertiseIncrease = 10 + (int)getSkillStatisticModifier(playerSmuggler, "expertise_sly_lie_bonus");
rankIncrease = (int)getSkillStatisticModifier(self, "expertise_sly_lie_rank") * smugglerRank;
utils.removeScriptVar(self, "slyLie");
}
int finalChance = expertiseIncrease + rankIncrease;
if (rand(1, 100) > (finalChance + 5))
{
string_id barkString = new string_id(STRING_FILE, "bark_attack");
if (finalChance > 0)
{
barkString = new string_id(STRING_FILE, "bark_lies_failed");
}
chat.chat(self, barkString);
doSnare(playerSmuggler, self);
if (!ai_lib.isInCombat(self))
{
startCombat(self, playerSmuggler);
}
else
{
obj_id enemyTarget = getHateTarget(self);
if (!isIdValid(enemyTarget))
{
return SCRIPT_CONTINUE;
}
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate + 1000f));
}
}
messageTo(self, "combatLoop", null, 11.0f, false);
if (!hasObjVar(self, "bossEnemy"))
{
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
else
{
if (!ai_lib.isInCombat(self))
{
string_id barkString = new string_id(STRING_FILE, "bark_sorry");
chat.chat(self, barkString);
ai_lib.pathAwayFrom(self, playerSmuggler);
messageTo(self, "handleCleanUp", null, 9.0f, false);
if (!hasObjVar(self, "bossEnemy"))
{
broadcastCondition(playerSmuggler, self, FLAG_FOLLOW);
}
}
else
{
if (!hasObjVar(self, "bossEnemy"))
{
obj_id enemyTarget = getHateTarget(self);
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate + 1000f));
}
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
}
}
utils.removeScriptVar(self, "slyLie");
return SCRIPT_CONTINUE;
}
public int fastTalkReaction(obj_id self, dictionary params) throws InterruptedException
{
obj_id playerSmuggler = params.getObjId("playerSmuggler");
if (!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
float underworldFaction = factions.getFactionStanding(playerSmuggler, "underworld");
int smugglerRank = smuggler.getSmugglerRank(underworldFaction);
int expertiseIncrease = (int)getSkillStatisticModifier(playerSmuggler, "expertise_fast_talk_bonus");
int rankIncrease = (int)getSkillStatisticModifier(self, "expertise_fast_talk_rank") * smugglerRank;
int finalChance = expertiseIncrease + rankIncrease;
int roll = rand(1, 100);
if (roll > (finalChance + 25))
{
string_id barkString = new string_id(STRING_FILE, "bark_fast_talk_failed");
chat.chat(self, barkString);
return SCRIPT_CONTINUE;
}
if (roll < (finalChance - 10))
{
doConfuseAttack(playerSmuggler, self);
return SCRIPT_CONTINUE;
}
doConfuse(playerSmuggler, self);
return SCRIPT_CONTINUE;
}
public int endConfusion(obj_id self, dictionary params) throws InterruptedException
{
obj_id playerSmuggler = params.getObjId("playerSmuggler");
setMaster(self, null);
utils.removeScriptVar(self, "fastTalked");
if (!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
if ((rand(1, 5)) == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_notfooled");
chat.chat(self, barkString);
}
if (!ai_lib.isInCombat(self))
{
startCombat(self, playerSmuggler);
}
else
{
obj_id enemyTarget = getHateTarget(self);
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate + 1000f));
}
}
messageTo(self, "combatLoop", null, 1.0f, false);
return SCRIPT_CONTINUE;
}
public int handleCleanUp(obj_id self, dictionary params) throws InterruptedException
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
public int OnEnteredCombat(obj_id self) throws InterruptedException
{
if (utils.hasScriptVar(self, "fastTalked"))
{
obj_id noAttack = utils.getObjIdScriptVar(self, "fastTalked");
if (!isIdValid(noAttack))
{
return SCRIPT_CONTINUE;
}
string_id barkString = new string_id(STRING_FILE, "bark_confused");
chat.chat(self, barkString);
removeHateTarget(self, noAttack);
ai_lib.aiStopFollowing(self);
ai_lib.pathAwayFrom(self, noAttack);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,600 +0,0 @@
include library.ai_lib;
include library.chat;
include library.buff;
include library.utils;
include library.combat;
include library.groundquests;
include library.factions;
include library.smuggler;
const string STRING_FILE = "smuggler/enemy";
const int FLAG_CLEAN_UP = 1;
const int FLAG_ATTACK = 2;
const int FLAG_FOLLOW = 3;
const string VOL_PATROL_WATCH = "smugglerPatrolWatch";
const float VOL_PATROL_RANGE = 12.0f;
trigger OnAttach()
{
messageTo(self, "startContrabandCheck", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
void doSnare(obj_id playerSmuggler, obj_id npc)
{
if (isIncapacitated(npc))
{
return;
}
if (isIncapacitated(playerSmuggler))
{
return;
}
if (utils.hasScriptVar(npc, "fastTalked"))
{
return;
}
int taunt = rand(1,5);
if (taunt == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_snare");
chat.chat(npc, barkString);
}
buff.applyBuff(playerSmuggler, "caltropSnare");
return;
}
void broadcastCondition(obj_id playerSmuggler, obj_id npc, int flag)
{
location here = getLocation(npc);
obj_id[] objects = getObjectsInRange(here, 32);
for(int i = 0; i < objects.length; i++)
if (hasObjVar(objects[i], "quest.owner"))
{
if ( (getObjIdObjVar(objects[i], "quest.owner") == playerSmuggler) && (npc != objects[i]) )
{
switch (flag)
{
case FLAG_CLEAN_UP:
messageTo(objects[i], "handleCleanUp", null, 1.0f, false);
break;
case FLAG_ATTACK:
if (isIncapacitated(playerSmuggler))
{
break;
}
if(!ai_lib.isInCombat(objects[i]))
{
if (!utils.hasScriptVar(objects[i], "fastTalked"))
{
startCombat(objects[i], playerSmuggler);
}
}
else
{
obj_id enemyTarget = getHateTarget(objects[i]);
if(!isIdValid(enemyTarget))
{
break;
}
if (enemyTarget != playerSmuggler)
{
if (!utils.hasScriptVar(objects[i], "fastTalked"))
{
float hate = getMaxHate(objects[i]);
addHate(objects[i], playerSmuggler, (hate+1000f));
}
}
}
messageTo(objects[i], "combatLoop", null, 11.0f, false);
break;
case FLAG_FOLLOW:
ai_lib.aiFollow( objects[i], npc, 3f, 6f );
messageTo(objects[i], "handleCleanUp", null, 9.0f, false);
break;
default:
break;
}
}
}
return;
}
void enemyPickFight(obj_id npc, obj_id victimNpc, obj_id playerSmuggler)
{
clearHateList(npc);
clearHateList(victimNpc);
utils.setScriptVar(npc, "fastTalked", playerSmuggler);
setMaster(npc, playerSmuggler);
utils.setScriptVar(victimNpc, "fastTalked", playerSmuggler);
startCombat(npc, victimNpc);
startCombat(victimNpc, npc);
addHate(npc, victimNpc, 9999.0f);
addHate(victimNpc, npc, 9999.0f);
string_id barkString = new string_id(STRING_FILE, "bark_myfriend");
chat.chat(npc, barkString);
barkString = new string_id(STRING_FILE, "bark_huh");
chat.chat(victimNpc, barkString);
dictionary params = new dictionary();
params.put("playerSmuggler", playerSmuggler);
messageTo(npc, "endConfusion", params, 15.0f, false);
messageTo(victimNpc, "endConfusion", params, 15.0f, false);
return;
}
void doConfuse(obj_id playerSmuggler, obj_id npc)
{
removeHateTarget(npc, playerSmuggler);
stopCombat(npc);
string_id barkString = new string_id(STRING_FILE, "bark_confused");
chat.chat(npc, barkString);
utils.setScriptVar(npc, "fastTalked", playerSmuggler);
ai_lib.aiStopFollowing (npc);
ai_lib.pathAwayFrom(npc, playerSmuggler);
dictionary params = new dictionary();
params.put("playerSmuggler", playerSmuggler);
messageTo(npc, "endConfusion", params, 15.0f, false);
return;
}
void doConfuseAttack(obj_id playerSmuggler, obj_id npc)
{
location here = getLocation(npc);
obj_id[] objects = getObjectsInRange(here, 25);
obj_id victimEnemy = null;
obj_id enemyTarget = null;
for(int i = 0; i < objects.length; i++)
{
if (hasScript(objects[i], "ai.smuggler_spawn_enemy"))
{
if (objects[i] != npc)
{
victimEnemy = objects[i];
if(ai_lib.isInCombat(objects[i]))
{
enemyTarget = getHateTarget(objects[i]);
if(isIdValid(enemyTarget))
{
if (enemyTarget == playerSmuggler)
{
enemyPickFight(npc, objects[i],playerSmuggler);
return;
}
}
}
}
}
}
if(isIdValid(victimEnemy))
{
enemyPickFight(npc, victimEnemy, playerSmuggler);
}
else
{
doConfuse(playerSmuggler, npc);
}
return;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if ( breacher == self )
{
return SCRIPT_CONTINUE;
}
if ( isIncapacitated(self) )
{
return SCRIPT_CONTINUE;
}
if ( isIncapacitated(breacher) )
{
return SCRIPT_CONTINUE;
}
if ( volumeName == VOL_PATROL_WATCH )
{
if(utils.getPlayerProfession(breacher) == utils.SMUGGLER)
{
if (groundquests.isDoingSmugglerMission(breacher))
{
int taunt = rand(1,10);
if (taunt == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_smuggler");
chat.chat(self, barkString);
int smugglerLevel = combat.getLevel(breacher);
int myLevel = combat.getLevel(self);
if (smugglerLevel > myLevel)
{
int levelDifference = (smugglerLevel - myLevel);
if (levelDifference > 5)
{
barkString = new string_id(STRING_FILE, "bark_help");
chat.chat(self, barkString);
groundquests.sendSignal(breacher, "smugglerPatrolHelp");
}
}
}
doSnare(breacher, self);
startCombat(self, breacher);
}
}
}
return SCRIPT_CONTINUE;
}
messageHandler combatLoop()
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "fastTalked"))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if(!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(playerSmuggler))
{
messageTo(self, "handleCleanUp", null, 1.0f, false);
}
float distanceRange = getLocation(self).distance(getLocation(playerSmuggler));
if (distanceRange > 256.0f)
{
// Gonna Bail here - smuggler got away
messageTo(self, "handleCleanUp", null, 1.0f, false);
return SCRIPT_CONTINUE;
}
if(!ai_lib.isInCombat(self))
{
if (!utils.hasScriptVar(self, "fastTalked"))
{ startCombat(self, playerSmuggler);
}
}
if (!buff.hasBuff(playerSmuggler, "caltropSnare"))
{
doSnare(playerSmuggler, self);
}
messageTo(self, "combatLoop", null, 11.0f, false);
}
return SCRIPT_CONTINUE;
}
messageHandler smugglerKilled()
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
string_id barkString = new string_id(STRING_FILE, "bark_smack_talk");
chat.chat(self, barkString);
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if(!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
messageTo(self, "handleCleanUp", null, 3.0f, false);
broadcastCondition(playerSmuggler, self, FLAG_CLEAN_UP);
}
return SCRIPT_CONTINUE;
}
messageHandler startContrabandCheck()
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
setBaseWalkSpeed(self, 6.0f);
setBaseRunSpeed(self, 9.0f);
setAILeashTime(self, 999999);
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
// Pick a random number for string to bark
int randStr = rand(1, 3);
string_id barkString = new string_id(STRING_FILE, "bark_s" + randStr);
// If I'm not in combat
if(!ai_lib.isInCombat(self))
{
faceTo(self, playerSmuggler);
chat.chat(self, barkString);
ai_lib.aiFollow( self, playerSmuggler, 3f, 6f );
}
if (hasObjVar(self, "quest.count"))
{
int boss = getIntObjVar(self, "quest.count");
if (boss == 0)
{
if(!ai_lib.isInCombat(self))
{
messageTo(self, "contrabandCheckResult", null, 11.0f, false);
utils.setScriptVar(self, "contrabandCheck", 1);
}
else
{
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
}
}
else
// This is not a mission spawned enemy - patrolers need a trigger volume to agro
{
createTriggerVolume(VOL_PATROL_WATCH, VOL_PATROL_RANGE, true);
}
return SCRIPT_CONTINUE;
}
messageHandler contrabandCheckResult()
{
utils.removeScriptVar(self, "contrabandCheck");
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "quest.owner"))
{
obj_id playerSmuggler = (getObjIdObjVar(self, "quest.owner"));
if(!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
int expertiseIncrease = 0;
int rankIncrease = 0;
if (utils.hasScriptVar(self, "slyLie"))
{
float underworldFaction = factions.getFactionStanding( playerSmuggler, "underworld" );
int smugglerRank = smuggler.getSmugglerRank(underworldFaction);
expertiseIncrease = 10 + (int)getSkillStatisticModifier(playerSmuggler, "expertise_sly_lie_bonus");
rankIncrease = (int)getSkillStatisticModifier(self, "expertise_sly_lie_rank") * smugglerRank;
utils.removeScriptVar(self, "slyLie");
}
int finalChance = expertiseIncrease + rankIncrease;
// Smuggler has a 5% base chance that mission enemies will not find contraband
// Expertise and rank can modify this chance by 45%
// The max chance to avoid an encounter using sly lie is 50%
if (rand(1,100) > (finalChance + 5))
{
string_id barkString = new string_id(STRING_FILE, "bark_attack");
if (finalChance > 0 )
{
barkString = new string_id(STRING_FILE, "bark_lies_failed");
}
// Start Attacking
chat.chat(self, barkString);
doSnare(playerSmuggler, self);
if(!ai_lib.isInCombat(self))
{
startCombat(self, playerSmuggler);
}
else
{
obj_id enemyTarget = getHateTarget(self);
if(!isIdValid(enemyTarget))
{
return SCRIPT_CONTINUE;
}
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate+1000f));
}
}
messageTo(self, "combatLoop", null, 11.0f, false);
if (!hasObjVar(self, "bossEnemy"))
{
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
else
{
if(!ai_lib.isInCombat(self))
{
string_id barkString = new string_id(STRING_FILE, "bark_sorry");
chat.chat(self, barkString);
ai_lib.pathAwayFrom(self, playerSmuggler);
messageTo(self, "handleCleanUp", null, 9.0f, false);
if (!hasObjVar(self, "bossEnemy"))
{
broadcastCondition(playerSmuggler, self, FLAG_FOLLOW);
}
}
else
{
if (!hasObjVar(self, "bossEnemy"))
{
obj_id enemyTarget = getHateTarget(self);
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate+1000f));
}
broadcastCondition(playerSmuggler, self, FLAG_ATTACK);
}
}
}
}
utils.removeScriptVar(self, "slyLie");
return SCRIPT_CONTINUE;
}
messageHandler fastTalkReaction()
{
obj_id playerSmuggler = params.getObjId("playerSmuggler");
if(!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
float underworldFaction = factions.getFactionStanding( playerSmuggler, "underworld" );
int smugglerRank = smuggler.getSmugglerRank(underworldFaction);
int expertiseIncrease = (int)getSkillStatisticModifier(playerSmuggler, "expertise_fast_talk_bonus");
int rankIncrease = (int)getSkillStatisticModifier(self, "expertise_fast_talk_rank") * smugglerRank;
int finalChance = expertiseIncrease + rankIncrease;
// 75% max chance with expertise
// 25% min chance
int roll = rand(1,100);
if (roll > (finalChance +25) )
{
// Failed roll
string_id barkString = new string_id(STRING_FILE, "bark_fast_talk_failed");
chat.chat(self, barkString);
return SCRIPT_CONTINUE;
}
// Requires min bonus of 11 from expertise to trigger enemies to attack each other
// At the max 40% chance for enemies to fight each other
// At the min 1% chance for enemies to attack each other
if (roll < (finalChance - 10) )
{
doConfuseAttack(playerSmuggler, self);
return SCRIPT_CONTINUE;
}
// I am confused
doConfuse(playerSmuggler, self);
return SCRIPT_CONTINUE;
}
messageHandler endConfusion()
{
obj_id playerSmuggler = params.getObjId("playerSmuggler");
setMaster(self, null);
utils.removeScriptVar(self, "fastTalked");
if(!isIdValid(playerSmuggler))
{
return SCRIPT_CONTINUE;
}
if ( (rand(1,5)) == 1)
{
string_id barkString = new string_id(STRING_FILE, "bark_notfooled");
chat.chat(self, barkString);
}
if(!ai_lib.isInCombat(self))
{
startCombat(self, playerSmuggler);
}
else
{
obj_id enemyTarget = getHateTarget(self);
if (enemyTarget != playerSmuggler)
{
float hate = getMaxHate(self);
addHate(self, playerSmuggler, (hate+1000f));
}
}
messageTo(self, "combatLoop", null, 1.0f, false);
return SCRIPT_CONTINUE;
}
messageHandler handleCleanUp()
{
destroyObject(self);
return SCRIPT_CONTINUE;
}
trigger OnEnteredCombat()
{
// Strange the Ais want to keep fighting the smuggler - so we will grant them immunity till the 15 seconds pass
if (utils.hasScriptVar(self, "fastTalked"))
{
obj_id noAttack = utils.getObjIdScriptVar(self, "fastTalked");
if(!isIdValid(noAttack))
{
return SCRIPT_CONTINUE;
}
string_id barkString = new string_id(STRING_FILE, "bark_confused");
chat.chat(self, barkString);
removeHateTarget(self, noAttack);
ai_lib.aiStopFollowing (self);
ai_lib.pathAwayFrom(self, noAttack);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,161 @@
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.ai.ai_aggro;
import script.ai.ai_combat;
import script.library.ai_lib;
import script.library.attrib;
import script.library.factions;
import script.library.pet_lib;
import script.library.utils;
public class soldier extends script.base_script
{
public soldier()
{
}
public static final String ACTION_ALERT = "alert";
public static final String ACTION_THREATEN = "threaten";
public int OnAttach(obj_id self) throws InterruptedException
{
if (!hasObjVar(self, "ai.diction"))
{
setObjVar(self, "ai.diction", "military");
}
setAttributeAttained(self, attrib.GUARD);
setAttributeInterested(self, attrib.THUG);
setAttributeInterested(self, attrib.HERBIVORE);
setAttributeInterested(self, attrib.CARNIVORE);
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(ai_lib.ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange(self), true);
}
setObjVar(self, "ai.rangedOnly", true);
if (!hasObjVar(self, "ai.grenadeType"))
{
setObjVar(self, "ai.grenadeType", "object/weapon/ranged/grenade/grenade_fragmentation");
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (!isMob(breacher))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isMonster(breacher))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(self, "ai.inFormation"))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME))
{
final int reaction = factions.getFactionReaction(self, breacher);
switch (reaction)
{
case factions.REACTION_NEGATIVE:
if (!hasObjVar(self, "ai.inFormation"))
{
ai_lib.barkString(self, "hi_mean");
}
break;
case factions.REACTION_POSITIVE:
if (!hasObjVar(self, "ai.inFormation"))
{
ai_lib.barkString(self, "hi_nice");
}
break;
default:
if (!hasObjVar(self, "ai.inFormation"))
{
ai_lib.barkString(self, "hi_mid");
}
break;
}
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_OVERRIDE;
}
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME) && (isMob(breacher) && !ai_lib.isMonster(breacher)) && !ai_lib.isInCombat(self) && !ai_lib.isAiDead(breacher) && !hasObjVar(self, "ai.inFormation"))
{
int reaction = factions.getFactionReaction(self, breacher);
switch (reaction)
{
case factions.REACTION_NEGATIVE:
ai_lib.barkString(self, "bye_mean");
break;
case factions.REACTION_POSITIVE:
ai_lib.barkString(self, "bye_nice");
break;
default:
ai_lib.barkString(self, "bye_mid");
break;
}
}
return SCRIPT_CONTINUE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (ai_lib.isAiDead(self))
{
return SCRIPT_OVERRIDE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_OVERRIDE;
}
if (newBehavior > oldBehavior)
{
if (newBehavior >= BEHAVIOR_THREATEN && newBehavior < BEHAVIOR_ATTACK)
{
doAgitateBehavior(self, newBehavior);
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
else if (newBehavior == BEHAVIOR_CALM)
{
ai_lib.barkString(self, "calm");
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public void doAgitateBehavior(obj_id npc, int behavior) throws InterruptedException
{
if (isInvulnerable(npc))
{
return;
}
if (getConfigSetting("GameServer", "disableAICombat") != null)
{
return;
}
}
}
@@ -1,173 +0,0 @@
include ai.ai_aggro;
include ai.ai_combat;
include library.ai_lib;
include library.attrib;
include library.factions;
include library.pet_lib;
include library.utils;
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
trigger OnAttach()
{
if ( !hasObjVar( self, "ai.diction") )
setObjVar( self, "ai.diction", "military" );
setAttributeAttained(self, attrib.GUARD);
setAttributeInterested(self, attrib.THUG);
setAttributeInterested(self, attrib.HERBIVORE);
setAttributeInterested(self, attrib.CARNIVORE);
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
createTriggerVolume( ai_lib.ALERT_VOLUME_NAME, ai_lib.aiGetApproachTriggerRange( self ), true );
setObjVar( self, "ai.rangedOnly", true );
if ( !hasObjVar( self, "ai.grenadeType" ))
{
setObjVar( self, "ai.grenadeType", "object/weapon/ranged/grenade/grenade_fragmentation" );
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if (ai_lib.isInCombat(self))
return SCRIPT_CONTINUE;
if (breacher == self)
return SCRIPT_CONTINUE;
if (isIncapacitated(self))
return SCRIPT_CONTINUE;
if (!isMob( breacher))
return SCRIPT_CONTINUE;
if (ai_lib.isMonster(breacher))
return SCRIPT_CONTINUE;
if (hasObjVar( self, "ai.inFormation" ))
return SCRIPT_CONTINUE;
if (volumeName == ai_lib.ALERT_VOLUME_NAME)
{
const int reaction = factions.getFactionReaction( self, breacher );
switch ( reaction )
{
case factions.REACTION_NEGATIVE :
if (!hasObjVar( self, "ai.inFormation" ))
ai_lib.barkString( self, "hi_mean" );
break;
case factions.REACTION_POSITIVE:
if (!hasObjVar( self, "ai.inFormation" ))
ai_lib.barkString( self, "hi_nice" );
break;
default:
if (!hasObjVar( self, "ai.inFormation" ))
ai_lib.barkString( self, "hi_mid" );
break;
}
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
if (ai_lib.isAiDead(self))
return SCRIPT_OVERRIDE;
if ( volumeName == ai_lib.ALERT_VOLUME_NAME && ( isMob( breacher)
&& !ai_lib.isMonster( breacher) ) && !ai_lib.isInCombat( self )
&& !ai_lib.isAiDead( breacher ) && !hasObjVar( self, "ai.inFormation" )
)
{
int reaction = factions.getFactionReaction( self, breacher );
switch ( reaction )
{
case factions.REACTION_NEGATIVE :
ai_lib.barkString( self, "bye_mean" );
break;
case factions.REACTION_POSITIVE:
ai_lib.barkString( self, "bye_nice" );
break;
default:
ai_lib.barkString( self, "bye_mid" );
break;
}
}
return SCRIPT_CONTINUE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( ai_lib.isAiDead( self ) )
return SCRIPT_OVERRIDE;
if ( ai_lib.isInCombat( self ))
return SCRIPT_OVERRIDE;
if ( newBehavior > oldBehavior )
{
if ( newBehavior >= BEHAVIOR_THREATEN && newBehavior < BEHAVIOR_ATTACK )
{
doAgitateBehavior( self, newBehavior );
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
return SCRIPT_CONTINUE;
}
else if ( newBehavior == BEHAVIOR_CALM )
{
//debugSpeakMsg( self, "I AM CALM AGAIN" );
ai_lib.barkString( self, "calm" );
return SCRIPT_CONTINUE;
}
//do default behavior stuff:
return SCRIPT_CONTINUE;
}
void doAgitateBehavior( obj_id npc, int behavior )
{
if ( isInvulnerable( npc ) )
return;
if ( getConfigSetting("GameServer", "disableAICombat")!=null )
return;
//debugSpeakMsg( npc, "doing custom thing" );
//obj_id threat = ai_lib.getBehaviorTarget( npc, behavior );
//if ( threat == null )
// return;
//else
// setObjVar( npc, "ai.threat", threat );
//
//switch ( behavior )
//{
// case BEHAVIOR_ALERT:
// stop( npc );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// break;
// case BEHAVIOR_THREATEN:
// //debugSpeakMsg( npc, "Grrr!");
// faceTo( npc, threat );
// doAnimationAction( npc, ACTION_THREATEN );
// ai_lib.setMood( npc, ai_lib.MOOD_THREATEN );
// break;
// case BEHAVIOR_FLEE:
// startCombat(npc, threat);
// break;
// case BEHAVIOR_PANIC:
// startCombat(npc, threat);
// break;
// default :
// //debugSpeakMsg( npc, "default: " + behavior );
// break;
//}
}
@@ -0,0 +1,43 @@
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.trial;
public class som_lava_beetle_explosion_script extends script.base_script
{
public som_lava_beetle_explosion_script()
{
}
public int OnIncapacitated(obj_id self, obj_id killer) throws InterruptedException
{
int explodeRoll = rand(1, 100);
if (explodeRoll < 25)
{
playClientEffectObj(self, trial.PRT_KUBAZA_WARNING, self, "");
messageTo(self, "nukeSelf", null, 5, false);
}
return SCRIPT_CONTINUE;
}
public int nukeSelf(obj_id self, dictionary params) throws InterruptedException
{
obj_id[] targets = trial.getValidPlayersInRadius(self, 7);
playClientEffectLoc(self, trial.PRT_KUBAZA_EXPLODE, getLocation(self), 0.4f);
destroyObject(self);
if (targets == null || targets.length == 0)
{
return SCRIPT_CONTINUE;
}
for (int i = 0; i < targets.length; i++)
{
damage(targets[i], DAMAGE_ELEMENTAL_HEAT, HIT_LOCATION_BODY, 500);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,32 +0,0 @@
include library.trial;
trigger OnIncapacitated(obj_id killer)
{
int explodeRoll = rand(1, 100);
if (explodeRoll < 25)
{
playClientEffectObj(self, trial.PRT_KUBAZA_WARNING, self, "");
messageTo(self, "nukeSelf", null, 5, false);
}
return SCRIPT_CONTINUE;
}
messageHandler nukeSelf()
{
obj_id[] targets = trial.getValidPlayersInRadius(self, 7);
playClientEffectLoc(self, trial.PRT_KUBAZA_EXPLODE, getLocation(self), 0.4f);
destroyObject(self);
if (targets == null || targets.length == 0)
{
return SCRIPT_CONTINUE;
}
for (int i=0;i<targets.length;i++)
{
damage(targets[i], DAMAGE_ELEMENTAL_HEAT, HIT_LOCATION_BODY, 500);
}
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,93 @@
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.buff;
import script.library.trial;
import script.library.utils;
public class spy_decoy extends script.base_script
{
public spy_decoy()
{
}
public int OnAttach(obj_id self) throws InterruptedException
{
detachScript(self, "systems.combat.credit_for_kills");
dictionary dict = new dictionary();
dict.put("degrade", 0);
messageTo(self, "destroyDecoy", null, 8.0f, false);
return SCRIPT_CONTINUE;
}
public int OnAboutToLoseItem(obj_id self, obj_id destContainer, obj_id transferer, obj_id item) throws InterruptedException
{
return SCRIPT_OVERRIDE;
}
public int OnIncapacitated(obj_id self, obj_id killer) throws InterruptedException
{
messageTo(self, "handleDecoyCleanup", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
public int OnCreatureDamaged(obj_id self, obj_id attacker, obj_id weapon, int[] damage) throws InterruptedException
{
if (pvpCanAttack(self, attacker) && isFlanking(self))
{
buff.applyBuff(attacker, "sp_decoy_debuff");
}
return SCRIPT_CONTINUE;
}
public int destroyDecoy(obj_id self, dictionary params) throws InterruptedException
{
int stage = params.getInt("degrade");
switch (stage)
{
case 0:
setHologramType(self, HOLOGRAM_TYPE1_QUALITY4);
break;
case 1:
setCreatureCoverVisibility(self, false);
kill(self);
messageTo(self, "handleDecoyCleanup", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
stage++;
params.put("degrade", stage);
messageTo(self, "destroyDecoy", params, 2.0f, false);
return SCRIPT_CONTINUE;
}
public boolean isFlanking(obj_id self) throws InterruptedException
{
return utils.getBooleanScriptVar(self, "flank");
}
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info mi) throws InterruptedException
{
mi.addRootMenu(menu_info_types.ITEM_USE, new string_id("spam", "decoy_start_trade"));
mi.addRootMenu(menu_info_types.ELEVATOR_UP, new string_id("spam", "decoy_character_sheet"));
mi.addRootMenu(menu_info_types.ELEVATOR_DOWN, new string_id("spam", "invite_to_group"));
return SCRIPT_CONTINUE;
}
public int handleDecoyCleanup(obj_id self, dictionary params) throws InterruptedException
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for (int i = 0; i < haters.length; i++)
{
removeHateTarget(haters[i], self);
}
}
trial.cleanupObject(self);
return SCRIPT_CONTINUE;
}
public int queue_ad(obj_id self, dictionary params) throws InterruptedException
{
queueCommand(self, (-1782321567), self, "", COMMAND_PRIORITY_DEFAULT);
return SCRIPT_CONTINUE;
}
}
@@ -1,91 +0,0 @@
include library.buff;
include library.trial;
include library.utils;
trigger OnAttach()
{
detachScript(self, "systems.combat.credit_for_kills");
dictionary dict = new dictionary();
dict.put("degrade", 0);
messageTo(self, "destroyDecoy", null, 8.0f, false);
return SCRIPT_CONTINUE;
}
trigger OnAboutToLoseItem(obj_id destContainer, obj_id transferer, obj_id item)
{
return SCRIPT_OVERRIDE;
}
trigger OnIncapacitated(obj_id killer)
{
messageTo(self, "handleDecoyCleanup", null, 2.0f, false);
return SCRIPT_CONTINUE;
}
trigger OnCreatureDamaged(obj_id attacker, obj_id weapon, int[] damage)
{
if (pvpCanAttack(self, attacker) && isFlanking(self))
{
buff.applyBuff(attacker, "sp_decoy_debuff");
}
return SCRIPT_CONTINUE;
}
messageHandler destroyDecoy()
{
int stage = params.getInt("degrade");
switch(stage)
{
case 0:
setHologramType(self, HOLOGRAM_TYPE1_QUALITY4);
break;
case 1:
setCreatureCoverVisibility(self, false);
kill(self);
messageTo(self, "handleDecoyCleanup",null, 2.0f, false);
return SCRIPT_CONTINUE;
}
stage++;
params.put("degrade", stage);
messageTo(self, "destroyDecoy", params, 2.0f, false);
return SCRIPT_CONTINUE;
}
boolean isFlanking(obj_id self)
{
return utils.getBooleanScriptVar(self, "flank");
}
trigger OnObjectMenuRequest(obj_id player, menu_info mi)
{
mi.addRootMenu(menu_info_types.ITEM_USE, new string_id("spam", "decoy_start_trade"));
mi.addRootMenu(menu_info_types.ELEVATOR_UP, new string_id("spam", "decoy_character_sheet"));
mi.addRootMenu(menu_info_types.ELEVATOR_DOWN, new string_id("spam", "invite_to_group"));
return SCRIPT_CONTINUE;
}
messageHandler handleDecoyCleanup()
{
obj_id[] haters = getHateList(self);
if (haters.length > 0)
{
for(int i=0;i<haters.length;i++)
{
removeHateTarget(haters[i], self);
}
}
trial.cleanupObject(self);
return SCRIPT_CONTINUE;
}
messageHandler queue_ad()
{
queueCommand(self, ##"sp_avoid_damage", self, "", COMMAND_PRIORITY_DEFAULT);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,188 @@
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.ai.ai_aggro;
import script.library.ai_lib;
import script.library.attrib;
import script.library.factions;
import script.library.utils;
public class thug extends script.base_script
{
public thug()
{
}
public static final String ACTION_ALERT = "alert";
public static final String ACTION_THREATEN = "threaten";
public int OnAttach(obj_id self) throws InterruptedException
{
setAttributeAttained(self, attrib.THUG);
setAttributeInterested(self, attrib.VICTIM);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
setAttributeAttained(self, attrib.THUG);
setAttributeInterested(self, attrib.VICTIM);
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (!isMob(breacher))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isMonster(breacher))
{
return SCRIPT_CONTINUE;
}
if (isPlayer(breacher))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.AGGRO_VOLUME_NAME))
{
int reaction = factions.getFactionReaction(self, breacher);
if (hasAttributeAttained(breacher, attrib.VICTIM))
{
reaction = factions.REACTION_NEGATIVE;
}
else if (reaction != factions.REACTION_NEGATIVE)
{
reaction = factions.REACTION_LIKE;
}
switch (reaction)
{
case factions.REACTION_NEGATIVE:
{
ai_lib.barkString(self, "hi_mean");
ai_aggro.requestAggroCheck(breacher);
return SCRIPT_OVERRIDE;
}
case factions.REACTION_POSITIVE:
case factions.REACTION_LIKE:
{
ai_lib.barkString(self, "hi_nice");
}
break;
default:
{
}
break;
}
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (isPlayer(breacher))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.AGGRO_VOLUME_NAME))
{
if (isMob(breacher) && !ai_lib.isMonster(breacher))
{
int reaction = factions.getFactionReaction(self, breacher);
if (hasAttributeAttained(breacher, attrib.VICTIM))
{
reaction = factions.REACTION_NEGATIVE;
}
else if (reaction != factions.REACTION_NEGATIVE)
{
reaction = factions.REACTION_LIKE;
}
switch (reaction)
{
case factions.REACTION_NEGATIVE:
{
ai_lib.barkString(self, "bye_mean");
if (rand(1, 2) == 1)
{
ai_aggro.requestAggroCheck(breacher);
return SCRIPT_OVERRIDE;
}
}
case factions.REACTION_POSITIVE:
case factions.REACTION_LIKE:
{
ai_lib.barkString(self, "bye_nice");
}
break;
default:
{
ai_lib.barkString(self, "bye_mean");
}
break;
}
}
}
return SCRIPT_CONTINUE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_OVERRIDE;
}
if (newBehavior > oldBehavior)
{
if (newBehavior >= BEHAVIOR_THREATEN && newBehavior < BEHAVIOR_ATTACK)
{
doAgitateBehavior(self, newBehavior);
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
else if (newBehavior == BEHAVIOR_CALM)
{
ai_lib.barkString(self, "calm");
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public void doAgitateBehavior(obj_id npc, int behavior) throws InterruptedException
{
if (isInvulnerable(npc))
{
return;
}
}
}
@@ -1,221 +0,0 @@
include ai.ai_aggro;
include library.ai_lib;
include library.attrib;
include library.factions;
include library.utils;
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
trigger OnAttach()
{
setAttributeAttained( self, attrib.THUG );
setAttributeInterested( self, attrib.VICTIM );
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
setAttributeAttained( self, attrib.THUG );
setAttributeInterested( self, attrib.VICTIM );
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ))
return SCRIPT_CONTINUE;
if ( breacher == self )
return SCRIPT_CONTINUE;
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
if ( !isMob( breacher) )
return SCRIPT_CONTINUE;
if ( ai_lib.isMonster( breacher ))
return SCRIPT_CONTINUE;
if (isPlayer(breacher))
return SCRIPT_CONTINUE;
if ( volumeName == ai_lib.AGGRO_VOLUME_NAME )
{
int reaction = factions.getFactionReaction( self, breacher );
if ( hasAttributeAttained( breacher, attrib.VICTIM ))
{
reaction = factions.REACTION_NEGATIVE;
}
else if (reaction != factions.REACTION_NEGATIVE )
{
reaction = factions.REACTION_LIKE;
}
switch ( reaction )
{
case factions.REACTION_NEGATIVE :
{
ai_lib.barkString(self, "hi_mean");
ai_aggro.requestAggroCheck(breacher);
return SCRIPT_OVERRIDE;
}
case factions.REACTION_POSITIVE:
case factions.REACTION_LIKE:
{
ai_lib.barkString( self, "hi_nice" );
}
break;
default:
{
//if (isPlayer(breacher))
//{
// ai_lib.barkString( self, "hi_mean" );
//
// if (rand(1, 5) == 1)
// {
// ai_combat.requestLosAggroCheck(breacher);
//
// return SCRIPT_OVERRIDE;
// }
//}
}
break;
}
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
if (ai_lib.isInCombat(self))
return SCRIPT_CONTINUE;
if (isPlayer(breacher))
return SCRIPT_CONTINUE;
if (volumeName == ai_lib.AGGRO_VOLUME_NAME)
{
if ( isMob(breacher)
&& !ai_lib.isMonster(breacher))
{
int reaction = factions.getFactionReaction( self, breacher );
if (hasAttributeAttained(breacher, attrib.VICTIM))
{
reaction = factions.REACTION_NEGATIVE;
}
else if (reaction != factions.REACTION_NEGATIVE)
{
reaction = factions.REACTION_LIKE;
}
switch (reaction)
{
case factions.REACTION_NEGATIVE:
{
ai_lib.barkString( self, "bye_mean" );
if ( rand(1,2)==1 )
{
//debugSpeakMsg( self, "attack 12" );
ai_aggro.requestAggroCheck(breacher);
return SCRIPT_OVERRIDE;
}
}
case factions.REACTION_POSITIVE:
case factions.REACTION_LIKE:
{
ai_lib.barkString(self, "bye_nice");
}
break;
default:
{
ai_lib.barkString(self, "bye_mean");
//if ( isPlayer( breacher ) )
//{
// if ( rand(1,4)==1 )
// {
// ai_lib.requestLosAggroCheck(breacher);
// }
//}
}
break;
}
}
}
return SCRIPT_CONTINUE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ))
return SCRIPT_OVERRIDE;
if ( newBehavior > oldBehavior )
{
if ( newBehavior >= BEHAVIOR_THREATEN && newBehavior < BEHAVIOR_ATTACK )
{
doAgitateBehavior( self, newBehavior );
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
return SCRIPT_CONTINUE;
}
else if ( newBehavior == BEHAVIOR_CALM )
{
//debugSpeakMsg( self, "I AM CALM AGAIN" );
ai_lib.barkString( self, "calm" );
return SCRIPT_CONTINUE;
}
//do default behavior stuff:
return SCRIPT_CONTINUE;
}
void doAgitateBehavior( obj_id npc, int behavior )
{
if ( isInvulnerable( npc ) )
return;
//debugSpeakMsg( npc, "doing custom thing" );
//obj_id threat = ai_lib.getBehaviorTarget( npc, behavior );
//if ( threat == null )
// return;
//else
// setObjVar( npc, "ai.threat", threat );
//
//switch ( behavior )
//{
// case BEHAVIOR_ALERT:
// stop( npc );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// break;
// case BEHAVIOR_THREATEN:
// //debugSpeakMsg( npc, "Grrr!");
// faceTo( npc, threat );
// ai_lib.doThreatenAnimation( npc );
// ai_lib.setMood( npc, ai_lib.MOOD_THREATEN );
// break;
// case BEHAVIOR_FLEE:
// case BEHAVIOR_PANIC:
// //debugSpeakMsg( npc, "attack 14" );
// startCombat( npc, threat );
// break;
// default :
// //debugSpeakMsg( npc, "default: " + behavior );
// break;
//}
}
@@ -0,0 +1,353 @@
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.ai.ai_combat;
import script.library.factions;
import script.library.chat;
import script.library.attrib;
import script.library.utils;
public class townperson extends script.base_script
{
public townperson()
{
}
public static final String ALERT_VOLUME_NAME = "alertTriggerVolume";
public static final String SOCIAL_VOLUME = "npc_socialization";
public static final float SOCIAL_RANGE = 15f;
public static final String ACTION_ALERT = "alert";
public static final String ACTION_THREATEN = "threaten";
public static final int CONVO_LENGTH = 300;
public static final String CREATURE_TABLE = "datatables/mob/creatures.iff";
public int OnAttach(obj_id self) throws InterruptedException
{
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
}
String diction = "townperson";
switch (rand(1, 3))
{
case 1:
diction = "townperson_fancy";
break;
case 2:
diction = "townperson_slang";
break;
case 3:
diction = "townperson";
break;
}
setObjVar(self, "ai.diction", diction);
factions.setFaction(self, "townperson");
switch (rand(1, 5))
{
case 1:
factions.setFaction(self, "ImperialCitizen");
break;
case 2:
factions.setFaction(self, "RebelCitizen");
break;
}
attachScript(self, "theme_park.tatooine.city_convo");
return SCRIPT_CONTINUE;
}
public int OnAddedToWorld(obj_id self) throws InterruptedException
{
utils.removeScriptVar(self, "ai.speaking");
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
}
setAttributeAttained(self, attrib.TOWNSPERSON);
setAttributeInterested(self, attrib.TOWNSPERSON);
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ALERT_VOLUME_NAME))
{
if (hasScript(breacher, "ai.townperson"))
{
addTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
return SCRIPT_CONTINUE;
}
if (volumeName.equals(SOCIAL_VOLUME))
{
if (!isPlayer(breacher))
{
initiateDialog(self, breacher);
}
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (volumeName.equals(ALERT_VOLUME_NAME))
{
if (hasScript(breacher, "ai.townperson"))
{
removeTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public int cancelFacing(obj_id self, dictionary params) throws InterruptedException
{
utils.removeScriptVar(self, "ai.speaking");
if (getBehavior(self) == BEHAVIOR_CALM)
{
messageTo(self, "resumeDefaultCalmBehavior", null, 5, false);
}
return SCRIPT_CONTINUE;
}
public void initiateDialog(obj_id talker, obj_id listener) throws InterruptedException
{
if (ai_lib.isInCombat(talker) || ai_lib.isInCombat(listener))
{
return;
}
if (ai_lib.isFollowing(talker) || ai_lib.isFollowing(listener))
{
return;
}
aiUnEquipWeapons(talker);
aiUnEquipWeapons(listener);
if (utils.hasScriptVar(talker, "ai.speaking") || utils.hasScriptVar(listener, "ai.speaking"))
{
return;
}
if (getBehavior(talker) >= BEHAVIOR_THREATEN || getBehavior(listener) >= BEHAVIOR_THREATEN)
{
return;
}
if (getIntObjVar(listener, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL || getIntObjVar(talker, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL)
{
return;
}
utils.setScriptVar(talker, "ai.speaking", listener);
utils.setScriptVar(listener, "ai.speaking", talker);
stop(talker);
stop(listener);
faceTo(listener, talker);
utils.setScriptVar(talker, "ai.pathingToSocialize", listener);
utils.setScriptVar(listener, "ai.pathingToSocialize", talker);
location pathToLoc = new location(getLocation(listener));
location myLoc = getLocation(talker);
if (pathToLoc.x < myLoc.x)
{
pathToLoc.x += 1.5f;
}
else
{
pathToLoc.x -= 1.5f;
}
if (pathToLoc.z < myLoc.z)
{
pathToLoc.z += 1.5f;
}
else
{
pathToLoc.z -= 1.5f;
}
pathTo(talker, pathToLoc);
}
public int OnMovePathComplete(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
if (exists(listener))
{
faceTo(self, listener);
faceTo(listener, self);
ai_lib.greet(self, listener);
ai_lib.doAction(self, "conversation_" + getGender(self));
ai_lib.doAction(listener, "conversation_" + getGender(listener));
}
messageTo(self, "handleEndSocializing", null, CONVO_LENGTH, isObjectPersisted(self));
return SCRIPT_CONTINUE;
}
public int handleEndSocializing(obj_id self, dictionary params) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
return SCRIPT_CONTINUE;
}
public int OnMovePathNotFound(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
return SCRIPT_CONTINUE;
}
public void endSocializing(obj_id talker, obj_id listener) throws InterruptedException
{
if (getBehavior(talker) == BEHAVIOR_CALM)
{
ai_lib.setMood(talker, ai_lib.MOOD_CALM);
ai_lib.dismiss(talker, listener);
messageTo(talker, "resumeDefaultCalmBehavior", null, 5, false);
}
if (getBehavior(listener) == BEHAVIOR_CALM)
{
ai_lib.setMood(listener, ai_lib.MOOD_CALM);
ai_lib.doAction(listener, "wave" + rand(1, 2));
messageTo(listener, "resumeDefaultCalmBehavior", null, 8, false);
}
utils.removeScriptVar(talker, "ai.pathingToSocialize");
utils.removeScriptVar(listener, "ai.pathingToSocialize");
utils.removeScriptVar(talker, "ai.speaking");
utils.removeScriptVar(listener, "ai.speaking");
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (newBehavior > oldBehavior)
{
if (utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
}
if (newBehavior >= BEHAVIOR_ALERT && newBehavior < BEHAVIOR_ATTACK)
{
doAgitateBehavior(self, newBehavior);
return SCRIPT_OVERRIDE;
}
else
{
}
return SCRIPT_CONTINUE;
}
else if (newBehavior == BEHAVIOR_CALM)
{
if (utils.hasScriptVar(self, "ai.speaking"))
{
ai_lib.setMood(self, ai_lib.MOOD_CALM);
return SCRIPT_OVERRIDE;
}
if (oldBehavior != BEHAVIOR_CALM)
{
chat.setNeutralMood(self);
ai_lib.barkString(self, "calm");
}
}
return SCRIPT_CONTINUE;
}
public void doAgitateBehavior(obj_id npc, int behavior) throws InterruptedException
{
if (isInvulnerable(npc))
{
return;
}
return;
}
public int OnTargeted(obj_id self, obj_id attacker) throws InterruptedException
{
if (isInvulnerable(self))
{
return SCRIPT_OVERRIDE;
}
addToMentalStateToward(self, attacker, FEAR, 100f);
return SCRIPT_OVERRIDE;
}
public int OnEnteredCombat(obj_id self) throws InterruptedException
{
if (isInvulnerable(self))
{
return SCRIPT_OVERRIDE;
}
return SCRIPT_OVERRIDE;
}
public int OnStartNpcConversation(obj_id self, obj_id speaker) throws InterruptedException
{
if (utils.hasScriptVar(self, "ai.speaking"))
{
obj_id listener = utils.getObjIdScriptVar(self, "ai.speaking");
if (listener != speaker)
{
endSocializing(self, listener);
}
}
utils.setScriptVar(self, "ai.speaking", speaker);
return SCRIPT_CONTINUE;
}
public int OnEndNpcConversation(obj_id self, obj_id speaker) throws InterruptedException
{
utils.removeScriptVar(self, "ai.speaking");
if (getBehavior(self) == BEHAVIOR_CALM)
{
messageTo(self, "resumeDefaultCalmBehavior", null, 5, false);
}
return SCRIPT_CONTINUE;
}
public int resumeDefaultCalmBehavior(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, "ai.speaking"))
{
return SCRIPT_OVERRIDE;
}
if (getBehavior(self) == BEHAVIOR_CALM)
{
aiUnEquipWeapons(self);
}
return SCRIPT_CONTINUE;
}
public int OnSawAttack(obj_id self, obj_id defender, obj_id[] attackers) throws InterruptedException
{
if (getConfigSetting("GameServer", "disableAICombat") != null)
{
setWantSawAttackTriggers(self, false);
return SCRIPT_OVERRIDE;
}
if (ai_lib.isAiDead(self) || isInvulnerable(self))
{
setWantSawAttackTriggers(self, false);
return SCRIPT_OVERRIDE;
}
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
setAnimationMood(self, "nervous");
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
return SCRIPT_CONTINUE;
}
}
@@ -1,388 +0,0 @@
include library.ai_lib;
include ai.ai_combat;
include library.factions;
include library.chat;
include library.attrib;
include library.utils;
const string ALERT_VOLUME_NAME = "alertTriggerVolume";
const string SOCIAL_VOLUME = "npc_socialization";
const float SOCIAL_RANGE = 15f;
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
const int CONVO_LENGTH = 300;
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
trigger OnAttach()
{
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
createTriggerVolume( SOCIAL_VOLUME, SOCIAL_RANGE, false );
//set diction:
string diction = "townperson";
switch ( rand( 1, 3 ))
{
case 1 :
diction = "townperson_fancy";
break;
case 2 :
diction = "townperson_slang";
break;
case 3 :
diction = "townperson";
break;
}
setObjVar( self, "ai.diction", diction );
//set faction:
factions.setFaction( self, "townperson" );
switch ( rand( 1,5) )
{
case 1 :
factions.setFaction( self, "ImperialCitizen" );
break;
case 2 :
factions.setFaction( self, "RebelCitizen" );
break;
}
attachScript( self, "theme_park.tatooine.city_convo" );
return SCRIPT_CONTINUE;
}
trigger OnAddedToWorld()
{
utils.removeScriptVar( self, "ai.speaking" );
if ( getConfigSetting("GameServer", "disableAITriggerVolumes") == null )
createTriggerVolume( SOCIAL_VOLUME, SOCIAL_RANGE, false );
setAttributeAttained(self, attrib.TOWNSPERSON );
setAttributeInterested(self, attrib.TOWNSPERSON );
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
if ( breacher == self )
return SCRIPT_CONTINUE;
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
if ( volumeName == ALERT_VOLUME_NAME )
{
if ( hasScript( breacher, "ai.townperson") )
{
//debugSpeakMsg( self, "adding " + breacher + " to " + SOCIAL_VOLUME );
addTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
return SCRIPT_CONTINUE;
}
if ( volumeName == SOCIAL_VOLUME )
{
if ( !isPlayer( breacher) )
initiateDialog( self, breacher );
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
//debugSpeakMsg( self, volumeName + " breached by " + breacher );
if ( volumeName == ALERT_VOLUME_NAME )
{
if ( hasScript( breacher, "ai.townperson") )
{
//debugSpeakMsg( self, "removing " + breacher + " from " + SOCIAL_VOLUME );
removeTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
messageHandler cancelFacing()
{
utils.removeScriptVar( self, "ai.speaking" );
if ( getBehavior( self ) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
return SCRIPT_CONTINUE;
}
void initiateDialog( obj_id talker, obj_id listener )
{
if ( ai_lib.isInCombat( talker ) || ai_lib.isInCombat( listener ) )
return;
if ( ai_lib.isFollowing(talker) || ai_lib.isFollowing(listener) )
return;
aiUnEquipWeapons(talker);
aiUnEquipWeapons(listener);
if ( utils.hasScriptVar( talker, "ai.speaking") || utils.hasScriptVar( listener, "ai.speaking" ))
return;
if ( getBehavior( talker ) >= BEHAVIOR_THREATEN || getBehavior( listener ) >= BEHAVIOR_THREATEN )
return;
if ( getIntObjVar( listener, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL ||
getIntObjVar( talker, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL )
return;
utils.setScriptVar( talker, "ai.speaking", listener );
utils.setScriptVar( listener, "ai.speaking", talker );
stop( talker );
stop( listener );
faceTo( listener, talker );
utils.setScriptVar( talker, "ai.pathingToSocialize", listener );
utils.setScriptVar( listener, "ai.pathingToSocialize", talker );
location pathToLoc = new location( getLocation( listener ) );
location myLoc = getLocation( talker );
if ( pathToLoc.x < myLoc.x )
pathToLoc.x += 1.5f;
else
pathToLoc.x -= 1.5f;
if ( pathToLoc.z < myLoc.z )
pathToLoc.z += 1.5f;
else
pathToLoc.z -= 1.5f;
pathTo( talker, pathToLoc );
}
trigger OnMovePathComplete()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
if ( exists(listener) )
{
faceTo( self, listener);
faceTo( listener, self );
ai_lib.greet( self, listener);
ai_lib.doAction( self, "conversation_"+getGender(self) );
ai_lib.doAction( listener, "conversation_"+getGender(listener) );
}
messageTo( self, "handleEndSocializing", null, CONVO_LENGTH, isObjectPersisted( self ) );
return SCRIPT_CONTINUE;
}
messageHandler handleEndSocializing()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
return SCRIPT_CONTINUE;
}
trigger OnMovePathNotFound()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
return SCRIPT_CONTINUE;
}
void endSocializing( obj_id talker, obj_id listener )
{
if ( getBehavior( talker ) == BEHAVIOR_CALM )
{
ai_lib.setMood( talker, ai_lib.MOOD_CALM );
ai_lib.dismiss( talker, listener );
messageTo( talker, "resumeDefaultCalmBehavior", null, 5, false );
}
if ( getBehavior( listener ) == BEHAVIOR_CALM )
{
ai_lib.setMood( listener, ai_lib.MOOD_CALM );
ai_lib.doAction( listener, "wave"+rand(1,2) );
messageTo( listener, "resumeDefaultCalmBehavior", null, 8, false );
}
utils.removeScriptVar( talker, "ai.pathingToSocialize" );
utils.removeScriptVar( listener, "ai.pathingToSocialize" );
utils.removeScriptVar( talker, "ai.speaking" );
utils.removeScriptVar( listener, "ai.speaking");
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
//debugSpeakMsg( self, "newbehavior: " + newBehavior );
if ( newBehavior > oldBehavior )
{
if ( utils.hasScriptVar( self, "ai.pathingToSocialize") )
{
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
}
if ( newBehavior >= BEHAVIOR_ALERT && newBehavior < BEHAVIOR_ATTACK )
{
doAgitateBehavior( self, newBehavior );
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
else
{
//debugSpeakMsg( self, newBehavior + " is not between " + BEHAVIOR_ALERT + " and " + BEHAVIOR_ATTACK );
}
return SCRIPT_CONTINUE;
}
else if ( newBehavior == BEHAVIOR_CALM )
{
//debugSpeakMsg( self, "now I am calm again" );
if ( utils.hasScriptVar( self, "ai.speaking"))
{
ai_lib.setMood( self, ai_lib.MOOD_CALM );
return SCRIPT_OVERRIDE;
}
if ( oldBehavior != BEHAVIOR_CALM )
{
chat.setNeutralMood( self );
ai_lib.barkString( self, "calm" );//newly calm and not conversing
}
}
return SCRIPT_CONTINUE;
}
void doAgitateBehavior( obj_id npc, int behavior )
{
if ( isInvulnerable( npc ) )
return;
//debugSpeakMsg( npc, "doing custom thing" );
//obj_id threat = ai_lib.getBehaviorTarget( npc, behavior );
//if ( threat == null )
return;
//else
// setObjVar( npc, "ai.threat", threat );
//
//switch ( behavior )
//{
// case BEHAVIOR_ALERT:
// if (!hasObjVar(npc, "ai.pathingAwayFrom" ))
// stop( npc );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// break;
// case BEHAVIOR_THREATEN:
// faceTo( npc, threat );
// ai_lib.doAction( npc, ACTION_THREATEN );
// ai_lib.setMood( npc, ai_lib.MOOD_THREATEN );
// break;
// case BEHAVIOR_FLEE:
// chat.setBadMood( npc );
// ai_lib.barkString( npc, "flee" );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// setMovementRun( npc );
// flee( npc, threat, 5f, 10f );
// break;
// case BEHAVIOR_PANIC:
// chat.setAngryMood( npc );
// ai_lib.barkString( npc, "flee" );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// setMovementRun( npc );
// flee( npc, threat, 5f, 10f );
// break;
// default :
// //debugSpeakMsg( npc, "default: " + behavior );
// break;
//}
}
trigger OnTargeted(obj_id attacker )
{
if ( isInvulnerable( self ) )
return SCRIPT_OVERRIDE;
addToMentalStateToward(self, attacker, FEAR, 100f );
return SCRIPT_OVERRIDE;
}
trigger OnEnteredCombat()
{
if ( isInvulnerable( self ) )
return SCRIPT_OVERRIDE;
return SCRIPT_OVERRIDE;
}
trigger OnStartNpcConversation (obj_id speaker)
{
if ( utils.hasScriptVar( self, "ai.speaking") )
{
obj_id listener = utils.getObjIdScriptVar( self, "ai.speaking" );
if ( listener != speaker )
endSocializing( self, listener );
}
utils.setScriptVar( self, "ai.speaking", speaker );
return SCRIPT_CONTINUE;
}
trigger OnEndNpcConversation(obj_id speaker )
{
utils.removeScriptVar( self, "ai.speaking" );
if ( getBehavior(self) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
return SCRIPT_CONTINUE;
}
messageHandler resumeDefaultCalmBehavior()
{
if ( utils.hasScriptVar( self, "ai.speaking" ))
return SCRIPT_OVERRIDE;
if ( getBehavior(self) == BEHAVIOR_CALM )
{
aiUnEquipWeapons(self);
}
return SCRIPT_CONTINUE;
}
trigger OnSawAttack(obj_id defender, obj_id[] attackers)
{
if ( getConfigSetting("GameServer", "disableAICombat")!=null )
{
setWantSawAttackTriggers(self, false);
return SCRIPT_OVERRIDE;
}
if ( ai_lib.isAiDead( self ) || isInvulnerable( self ) )
{
setWantSawAttackTriggers(self, false);
return SCRIPT_OVERRIDE;
}
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
setAnimationMood( self, "nervous" );
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,157 @@
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.factions;
import script.library.utils;
public class tusken_bantha extends script.base_script
{
public tusken_bantha()
{
}
public static final String SOCIAL_VOLUME = "npc_socialization";
public static final float SOCIAL_RANGE = 15f;
public int OnAttach(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.tusken"))
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
followTusken(self, utils.getObjIdScriptVar(self, "ai.tusken"));
factions.setFaction(self, "tusken");
return SCRIPT_CONTINUE;
}
public int OnDetach(obj_id self) throws InterruptedException
{
factions.setFaction(self, "bantha");
return SCRIPT_CONTINUE;
}
public int OnAddedToWorld(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.tusken"))
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
followTusken(self, utils.getObjIdScriptVar(self, "ai.tusken"));
return SCRIPT_CONTINUE;
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (newBehavior < oldBehavior)
{
if (!utils.hasScriptVar(self, "ai.tusken"))
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
followTusken(self, utils.getObjIdScriptVar(self, "ai.tusken"));
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
public void followTusken(obj_id bantha, obj_id target) throws InterruptedException
{
obj_id isFollowedBy = getObjIdObjVar(target, "ai.isFollowedBy");
if (isFollowedBy == null || isFollowedBy == bantha)
{
setMovementWalk(bantha);
follow(bantha, target, 2f, 5f);
setObjVar(target, "ai.isFollowedBy", bantha);
utils.setScriptVar(bantha, "ai.tusken", target);
setObjVar(bantha, "ai.isFollowing", target);
}
else
{
followTusken(bantha, isFollowedBy);
}
}
public int resumeLoitering(obj_id self, dictionary params) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.tusken"))
{
detachScript(self, "ai.tusken_bantha");
return SCRIPT_CONTINUE;
}
followTusken(self, utils.getObjIdScriptVar(self, "ai.tusken"));
return SCRIPT_OVERRIDE;
}
public void cancelFollowing(obj_id npc) throws InterruptedException
{
utils.removeScriptVar(npc, "ai.tusken");
obj_id isFollowing = getObjIdObjVar(npc, "ai.isFollowing");
if (isFollowing != null)
{
messageTo(isFollowing, "stopBeingFollowed", null, 0, isObjectPersisted(isFollowing));
}
removeObjVar(npc, "ai.isFollowing");
if (hasObjVar(npc, "ai.isFollowedBy"))
{
obj_id isFollowedBy = getObjIdObjVar(npc, "ai.isFollowedBy");
messageTo(isFollowedBy, "stopFollowing", null, 0, isObjectPersisted(isFollowedBy));
}
}
public int stopBeingFollowed(obj_id self, dictionary params) throws InterruptedException
{
removeObjVar(self, "ai.isFollowedBy");
return SCRIPT_CONTINUE;
}
public int stopFollowing(obj_id self, dictionary params) throws InterruptedException
{
removeObjVar(self, "ai.isFollowing");
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnFollowTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnFollowPathNotFound(obj_id self, obj_id target) throws InterruptedException
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME))
{
if (hasScript(breacher, "ai.tusken_raider"))
{
return SCRIPT_OVERRIDE;
}
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME))
{
ignoreCreatureMovement(self, breacher);
}
return SCRIPT_OVERRIDE;
}
}
@@ -1,153 +0,0 @@
include library.ai_lib;
include library.factions;
include library.utils;
const string SOCIAL_VOLUME = "npc_socialization";
const float SOCIAL_RANGE = 15f;
trigger OnAttach()
{
if ( !utils.hasScriptVar( self, "ai.tusken" ) )
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
//debugSpeakMsg( self, "following " + getObjIdObjVar( self, "ai.tusken" ));
followTusken( self, utils.getObjIdScriptVar( self, "ai.tusken" ) );
factions.setFaction( self, "tusken" );
return SCRIPT_CONTINUE;
}
trigger OnDetach()
{
factions.setFaction( self, "bantha" );
return SCRIPT_CONTINUE;
}
trigger OnAddedToWorld()
{
if ( !utils.hasScriptVar( self, "ai.tusken" ) )
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
followTusken( self, utils.getObjIdScriptVar( self, "ai.tusken" ) );
return SCRIPT_CONTINUE;
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
if ( newBehavior < oldBehavior )
{
if ( !utils.hasScriptVar( self, "ai.tusken" ) )
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
followTusken( self, utils.getObjIdScriptVar( self, "ai.tusken" ) );
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
return SCRIPT_CONTINUE;
}
void followTusken( obj_id bantha, obj_id target )
{
//debugSpeakMsg( bantha, "thinking about following: " + target );
obj_id isFollowedBy = getObjIdObjVar( target, "ai.isFollowedBy" );
if ( isFollowedBy == null || isFollowedBy == bantha
// || !exists( isFollowedBy)
)
{
setMovementWalk( bantha );
//debugSpeakMsg( bantha, "REALLY " + target );
follow( bantha, target, 2f, 5f );
setObjVar( target, "ai.isFollowedBy", bantha );
utils.setScriptVar( bantha, "ai.tusken", target );
setObjVar( bantha, "ai.isFollowing", target );
}
else
{
followTusken( bantha, isFollowedBy );
}
}
messageHandler resumeLoitering()
{
if ( !utils.hasScriptVar( self, "ai.tusken" ) )
{
detachScript( self, "ai.tusken_bantha" );
return SCRIPT_CONTINUE;
}
followTusken( self, utils.getObjIdScriptVar( self, "ai.tusken") );
return SCRIPT_OVERRIDE;
}
void cancelFollowing( obj_id npc )
{
utils.removeScriptVar( npc, "ai.tusken" );
obj_id isFollowing = getObjIdObjVar( npc, "ai.isFollowing" );
if ( isFollowing != null )
messageTo( isFollowing, "stopBeingFollowed", null, 0, isObjectPersisted( isFollowing ) );
removeObjVar( npc, "ai.isFollowing" );
if ( hasObjVar( npc, "ai.isFollowedBy" ) )
{
obj_id isFollowedBy = getObjIdObjVar( npc, "ai.isFollowedBy");
messageTo( isFollowedBy, "stopFollowing", null, 0, isObjectPersisted( isFollowedBy) );
}
}
messageHandler stopBeingFollowed()
{
removeObjVar( self, "ai.isFollowedBy" );
return SCRIPT_CONTINUE;
}
messageHandler stopFollowing()
{
removeObjVar( self, "ai.isFollowing" );
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
trigger OnFollowTargetLost(obj_id oldTarget)
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
trigger OnFollowPathNotFound(obj_id target)
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
if ( hasObjVar( breacher, "gm") )
return SCRIPT_CONTINUE;
if ( volumeName == ai_lib.ALERT_VOLUME_NAME )
{
if ( hasScript( breacher, "ai.tusken_raider") )
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited( string volumeName, obj_id breacher )
{
if ( volumeName == ai_lib.ALERT_VOLUME_NAME )
ignoreCreatureMovement(self, breacher);
return SCRIPT_OVERRIDE;
}
@@ -0,0 +1,406 @@
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.ai.ai_combat;
import script.library.factions;
import script.library.utils;
import script.library.attrib;
public class tusken_raider extends script.base_script
{
public tusken_raider()
{
}
public static final String SOCIAL_VOLUME = "npc_socialization";
public static final float SOCIAL_RANGE = 15.0f;
public static final String ACTION_ALERT = "alert";
public static final String ACTION_THREATEN = "threaten";
public static final String CREATURE_TABLE = "datatables/mob/creatures.iff";
public void initializeScript() throws InterruptedException
{
obj_id self = getSelf();
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::initializeScript() self(" + self + ":" + getName(self) + ")");
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
cancelFollowing(self);
setAttributeInterested(self, attrib.TUSKEN_RAIDER);
setAttributeInterested(self, attrib.HERBIVORE);
setAttributeAttained(self, attrib.TUSKEN_RAIDER);
setAttributeAttained(self, attrib.THUG);
}
public int OnAttach(obj_id self) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAttach() self(" + self + ":" + getName(self) + ")");
initializeScript();
return SCRIPT_CONTINUE;
}
public int OnAddedToWorld(obj_id self) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAddedToWorld() self(" + self + ":" + getName(self) + ")");
initializeScript();
return SCRIPT_CONTINUE;
}
public int OnAiTetherStart(obj_id self) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAiTetherStart() self(" + self + ":" + getName(self) + ")");
removeTriggerVolume(SOCIAL_VOLUME);
return SCRIPT_CONTINUE;
}
public int OnAiTetherComplete(obj_id self) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAiTetherComplete() self(" + self + ":" + getName(self) + ")");
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeEntered(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnTriggerVolumeEntered() self(" + self + ":" + getName(self) + ") volumeName(" + volumeName + ") breacher(" + breacher + ":" + getName(breacher) + ")");
if (hasObjVar(breacher, "gm"))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (breacher == self)
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (getIntObjVar(self, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL)
{
return SCRIPT_CONTINUE;
}
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME))
{
if (hasScript(breacher, "ai.tusken_raider"))
{
if (getIntObjVar(breacher, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL)
{
return SCRIPT_CONTINUE;
}
addTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
else
{
boolean isBantha = false;
final String creatureName = getCreatureName(breacher);
if (creatureName != null)
{
String species = dataTableGetString(CREATURE_TABLE, creatureName, "socialGroup");
if ((species != null) && species.equals("bantha"))
{
isBantha = true;
}
}
if (isBantha)
{
takeBantha(self, breacher);
return SCRIPT_OVERRIDE;
}
}
return SCRIPT_CONTINUE;
}
else if (volumeName.equals(SOCIAL_VOLUME))
{
if (!ai_lib.isInCombat(breacher))
{
if (getIntObjVar(breacher, "ai.defaultCalmBehavior") != ai_lib.BEHAVIOR_SENTINEL)
{
initiateDialog(self, breacher);
}
}
}
return SCRIPT_CONTINUE;
}
public int OnTriggerVolumeExited(obj_id self, String volumeName, obj_id breacher) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnTriggerVolumeExited() self(" + self + ":" + getName(self) + ") volumeName(" + volumeName + ") breacher(" + breacher + ":" + getName(breacher) + ")");
if (volumeName.equals(ai_lib.ALERT_VOLUME_NAME))
{
if (hasScript(breacher, "ai.tusken_raider"))
{
removeTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
}
return SCRIPT_CONTINUE;
}
public void initiateDialog(obj_id talker, obj_id listener) throws InterruptedException
{
if (!(isIdValid(talker) && isIdValid(listener)))
{
return;
}
if (talker.getValue() < listener.getValue())
{
return;
}
if (utils.hasScriptVar(talker, "ai.speaking") || utils.hasScriptVar(listener, "ai.speaking"))
{
return;
}
if (getBehavior(talker) >= BEHAVIOR_THREATEN || getBehavior(listener) >= BEHAVIOR_THREATEN)
{
return;
}
if (getIntObjVar(listener, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL || getIntObjVar(talker, "ai.defaultCalmBehavior") == ai_lib.BEHAVIOR_SENTINEL)
{
return;
}
location pathToLoc = getLocation(listener);
location myLoc = getLocation(talker);
if (pathToLoc == null || myLoc == null)
{
String msg = "ai.tusken_raider.initiateDialog(): ";
String msg2 = "Null location for listener (obj_id: " + listener + " pathToLoc: " + pathToLoc + ") and/or talker (obj_id: " + talker + " myLoc: " + myLoc + ")";
LOG("DESIGNER_FATAL", msg + msg2);
return;
}
else
{
utils.setScriptVar(talker, "ai.speaking", true);
utils.setScriptVar(listener, "ai.speaking", true);
stop(talker);
stop(listener);
faceTo(listener, talker);
utils.setScriptVar(talker, "ai.pathingToSocialize", listener);
utils.setScriptVar(listener, "ai.pathingToSocialize", talker);
if (pathToLoc.x < myLoc.x)
{
pathToLoc.x += 1.5f;
}
else
{
pathToLoc.x -= 1.5f;
}
if (pathToLoc.z < myLoc.z)
{
pathToLoc.z += 1.5f;
}
else
{
pathToLoc.z -= 1.5f;
}
pathTo(talker, pathToLoc);
messageTo(talker, "handleSocializingRecovery", null, 45, isObjectPersisted(talker));
messageTo(listener, "handleSocializingRecovery", null, 45, isObjectPersisted(listener));
}
}
public int handleSocializingRecovery(obj_id self, dictionary params) throws InterruptedException
{
if (utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
ai_lib.setMood(self, ai_lib.MOOD_CALM);
utils.removeScriptVar(self, "ai.pathingToSocialize");
utils.removeScriptVar(self, "ai.speaking");
messageTo(self, "resumeLoitering", null, 1, false);
}
return SCRIPT_CONTINUE;
}
public int OnMovePathComplete(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
faceTo(self, listener);
faceTo(listener, self);
ai_lib.doAction(self, "conversation_1");
ai_lib.doAction(listener, "conversation_1");
ai_lib.setMood(self, ai_lib.MOOD_CALM);
messageTo(self, "handleEndSocializing", null, 10, false);
return SCRIPT_CONTINUE;
}
public int handleEndSocializing(obj_id self, dictionary params) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
return SCRIPT_CONTINUE;
}
public int OnMovePathNotFound(obj_id self) throws InterruptedException
{
if (!utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
return SCRIPT_CONTINUE;
}
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
return SCRIPT_CONTINUE;
}
public void endSocializing(obj_id talker, obj_id listener) throws InterruptedException
{
ai_lib.setMood(talker, ai_lib.MOOD_CALM);
ai_lib.setMood(listener, ai_lib.MOOD_CALM);
messageTo(talker, "resumeLoitering", null, 1, false);
followTusken(listener, talker);
utils.removeScriptVar(talker, "ai.pathingToSocialize");
utils.removeScriptVar(listener, "ai.pathingToSocialize");
utils.removeScriptVar(talker, "ai.speaking");
removeTriggerVolumeEventSource(SOCIAL_VOLUME, listener);
}
public int OnBehaviorChange(obj_id self, int newBehavior, int oldBehavior, int[] changeFlags) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnBehaviorChange() self(" + self + ":" + getName(self) + ")");
if (isIncapacitated(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_OVERRIDE;
}
if (newBehavior > oldBehavior)
{
if (utils.hasScriptVar(self, "ai.pathingToSocialize"))
{
obj_id listener = utils.getObjIdScriptVar(self, "ai.pathingToSocialize");
endSocializing(self, listener);
}
if (newBehavior >= BEHAVIOR_ALERT && newBehavior < BEHAVIOR_ATTACK)
{
doAgitateBehavior(self, newBehavior);
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
if (newBehavior == BEHAVIOR_CALM)
{
if (utils.hasObjVar(self, "ai.isFollowing"))
{
followTusken(self, getObjIdObjVar(self, "ai.isFollowing"));
return SCRIPT_OVERRIDE;
}
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
public void doAgitateBehavior(obj_id npc, int behavior) throws InterruptedException
{
if (isInvulnerable(npc))
{
return;
}
if (getConfigSetting("GameServer", "disableAICombat") != null)
{
return;
}
return;
}
public void followTusken(obj_id npc, obj_id target) throws InterruptedException
{
if (!isIncapacitated(npc))
{
removeTriggerVolumeEventSource(SOCIAL_VOLUME, target);
if (!exists(target))
{
cancelFollowing(npc);
return;
}
if (target.getValue() < npc.getValue())
{
return;
}
obj_id isFollowedBy = getObjIdObjVar(target, "ai.isFollowedBy");
if (isFollowedBy == null || isFollowedBy == npc)
{
setMovementWalk(npc);
follow(npc, target, 2f, 5f);
setObjVar(target, "ai.isFollowedBy", npc);
setObjVar(npc, "ai.isFollowing", target);
}
else
{
followTusken(npc, isFollowedBy);
}
}
}
public int resumeLoitering(obj_id self, dictionary params) throws InterruptedException
{
obj_id isFollowing = getObjIdObjVar(self, "ai.isFollowing");
if (isFollowing == null)
{
if (getBehavior(self) == BEHAVIOR_CALM)
{
messageTo(self, "resumeDefaultCalmBehavior", null, 1, false);
}
return SCRIPT_CONTINUE;
}
else
{
followTusken(self, isFollowing);
return SCRIPT_OVERRIDE;
}
}
public void cancelFollowing(obj_id npc) throws InterruptedException
{
utils.removeScriptVar(npc, "ai.speaking");
obj_id isFollowing = getObjIdObjVar(npc, "ai.isFollowing");
if (isFollowing != null)
{
messageTo(isFollowing, "stopBeingFollowed", null, 0, false);
}
removeObjVar(npc, "ai.isFollowing");
}
public int stopBeingFollowed(obj_id self, dictionary params) throws InterruptedException
{
removeObjVar(self, "ai.isFollowedBy");
return SCRIPT_CONTINUE;
}
public int stopFollowing(obj_id self, dictionary params) throws InterruptedException
{
removeObjVar(self, "ai.isFollowing");
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnFollowTargetLost(obj_id self, obj_id oldTarget) throws InterruptedException
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public int OnFollowPathNotFound(obj_id self, obj_id target) throws InterruptedException
{
cancelFollowing(self);
messageTo(self, "resumeLoitering", null, 3, false);
return SCRIPT_CONTINUE;
}
public void takeBantha(obj_id tusken, obj_id bantha) throws InterruptedException
{
if (hasScript(bantha, "ai.tusken_bantha"))
{
return;
}
if (utils.hasScriptVar(tusken, "ai.bantha"))
{
return;
}
utils.setScriptVar(tusken, "ai.bantha", bantha);
utils.setScriptVar(bantha, "ai.tusken", tusken);
attachScript(bantha, "ai.tusken_bantha");
}
public int OnIncapacitated(obj_id self, obj_id attacker) throws InterruptedException
{
removeTriggerVolume(SOCIAL_VOLUME);
return SCRIPT_CONTINUE;
}
}
@@ -1,469 +0,0 @@
include library.ai_lib;
include ai.ai_combat;
include library.factions;
include library.utils;
include library.attrib;
const string SOCIAL_VOLUME = "npc_socialization";
const float SOCIAL_RANGE = 15.0f;
const string ACTION_ALERT = "alert";
const string ACTION_THREATEN = "threaten";
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
void initializeScript()
{
obj_id self = getSelf();
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::initializeScript() self(" + self + ":" + getName(self) + ")");
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
cancelFollowing(self);
setAttributeInterested(self, attrib.TUSKEN_RAIDER);
setAttributeInterested(self, attrib.HERBIVORE);
setAttributeAttained(self, attrib.TUSKEN_RAIDER);
setAttributeAttained(self, attrib.THUG);//so guard-types will attack them
}
/**
* This is called when a a script gets attached to the AI and the AI
* is not being restored from a persisted state. When an AI is restored
* from a persisted state, OnAddedToWorld() gets called.
*/
trigger OnAttach()
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAttach() self(" + self + ":" + getName(self) + ")");
initializeScript();
return SCRIPT_CONTINUE;
}
/**
* This is when an AI gets restored from a persisted state. This will
* not be called when an AI is first created because this script is
* not attached yet. When the object is first created, OnAttach() is
* called.
*/
trigger OnAddedToWorld()
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAddedToWorld() self(" + self + ":" + getName(self) + ")");
initializeScript();
return SCRIPT_CONTINUE;
}
trigger OnAiTetherStart()
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAiTetherStart() self(" + self + ":" + getName(self) + ")");
removeTriggerVolume(SOCIAL_VOLUME);
return SCRIPT_CONTINUE;
}
trigger OnAiTetherComplete()
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnAiTetherComplete() self(" + self + ":" + getName(self) + ")");
if (getConfigSetting("GameServer", "disableAITriggerVolumes") == null)
{
createTriggerVolume(SOCIAL_VOLUME, SOCIAL_RANGE, false);
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeEntered( string volumeName, obj_id breacher )
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnTriggerVolumeEntered() self(" + self + ":" + getName(self) + ") volumeName(" + volumeName + ") breacher(" + breacher + ":" + getName(breacher) + ")");
if (hasObjVar(breacher, "gm"))
return SCRIPT_CONTINUE;
if (ai_lib.isInCombat(self))
return SCRIPT_CONTINUE;
if ( breacher == self )
return SCRIPT_CONTINUE;
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
if ( getIntObjVar( self, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL )
return SCRIPT_CONTINUE;
if ( volumeName == ai_lib.ALERT_VOLUME_NAME )
{
if ( hasScript( breacher, "ai.tusken_raider") )
{
if ( getIntObjVar( breacher, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL )
return SCRIPT_CONTINUE;
addTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
else
{
boolean isBantha = false;
const string creatureName = getCreatureName(breacher);
if (creatureName != null)
{
string species = dataTableGetString( CREATURE_TABLE, creatureName, "socialGroup" );
if ( (species != null) && species.equals( "bantha" ) )
isBantha = true;
}
if ( isBantha )
{
takeBantha( self, breacher );
return SCRIPT_OVERRIDE;
}
}
return SCRIPT_CONTINUE;
}
else if (volumeName == SOCIAL_VOLUME)
{
if (!ai_lib.isInCombat(breacher))
{
if (getIntObjVar(breacher, "ai.defaultCalmBehavior") != ai_lib.BEHAVIOR_SENTINEL)
{
initiateDialog(self, breacher);
}
}
}
return SCRIPT_CONTINUE;
}
trigger OnTriggerVolumeExited(string volumeName, obj_id breacher)
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnTriggerVolumeExited() self(" + self + ":" + getName(self) + ") volumeName(" + volumeName + ") breacher(" + breacher + ":" + getName(breacher) + ")");
if (volumeName == ai_lib.ALERT_VOLUME_NAME)
{
if (hasScript( breacher, "ai.tusken_raider"))
{
removeTriggerVolumeEventSource(SOCIAL_VOLUME, breacher);
}
}
return SCRIPT_CONTINUE;
}
void initiateDialog( obj_id talker, obj_id listener )
{
if ( !(isIdValid( talker ) && isIdValid( listener )) )
return;
//only talk to tuskens with a higher obj_id than your own:
if ( talker.getValue() < listener.getValue() )
return;
if ( utils.hasScriptVar( talker, "ai.speaking") || utils.hasScriptVar( listener, "ai.speaking" ))
return;
if ( getBehavior( talker ) >= BEHAVIOR_THREATEN || getBehavior( listener ) >= BEHAVIOR_THREATEN )
return;
if ( getIntObjVar( listener, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL ||
getIntObjVar( talker, "ai.defaultCalmBehavior" ) == ai_lib.BEHAVIOR_SENTINEL )
return;
location pathToLoc = getLocation( listener );
location myLoc = getLocation( talker );
if ( pathToLoc == null || myLoc == null )
{
string msg = "ai.tusken_raider.initiateDialog(): ";
string msg2 = "Null location for listener (obj_id: " + listener + " pathToLoc: " + pathToLoc + ") and/or talker (obj_id: " + talker + " myLoc: " + myLoc + ")";
LOG("DESIGNER_FATAL", msg + msg2);
return;
}
else
{
utils.setScriptVar( talker, "ai.speaking", true );
utils.setScriptVar( listener, "ai.speaking", true );
stop( talker );
stop( listener );
faceTo( listener, talker );
utils.setScriptVar( talker, "ai.pathingToSocialize", listener );
utils.setScriptVar( listener, "ai.pathingToSocialize", talker );
if ( pathToLoc.x < myLoc.x )
pathToLoc.x += 1.5f;
else
pathToLoc.x -= 1.5f;
if ( pathToLoc.z < myLoc.z )
pathToLoc.z += 1.5f;
else
pathToLoc.z -= 1.5f;
pathTo( talker, pathToLoc );
//If in 45 seconds these objvars are still set, then we'll kill this
// socialization and resume default behavior:
messageTo( talker, "handleSocializingRecovery", null, 45, isObjectPersisted( talker) );
messageTo( listener, "handleSocializingRecovery", null, 45, isObjectPersisted(listener) );
}
}
messageHandler handleSocializingRecovery()
{
if ( utils.hasScriptVar( self, "ai.pathingToSocialize" ))
{
ai_lib.setMood( self, ai_lib.MOOD_CALM );
utils.removeScriptVar( self, "ai.pathingToSocialize" );
utils.removeScriptVar( self, "ai.speaking" );
messageTo( self, "resumeLoitering", null, 1, false );
}
return SCRIPT_CONTINUE;
}
trigger OnMovePathComplete()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
faceTo( self, listener);
faceTo( listener, self );
ai_lib.doAction( self, "conversation_1" );
ai_lib.doAction( listener, "conversation_1" );
ai_lib.setMood( self, ai_lib.MOOD_CALM );
messageTo( self, "handleEndSocializing", null, 10, false );
return SCRIPT_CONTINUE;
}
messageHandler handleEndSocializing()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
return SCRIPT_CONTINUE;
}
trigger OnMovePathNotFound()
{
if ( !utils.hasScriptVar( self, "ai.pathingToSocialize"))
return SCRIPT_CONTINUE;
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
return SCRIPT_CONTINUE;
}
void endSocializing( obj_id talker, obj_id listener )
{
//BUG: Currently this make humans play the flute:
ai_lib.setMood( talker, ai_lib.MOOD_CALM );
ai_lib.setMood( listener, ai_lib.MOOD_CALM );
messageTo( talker, "resumeLoitering", null, 1, false );
//messageTo( listener, "resumeLoitering", null, 3, true );
followTusken( listener, talker );//rather than socializing, this sandperson becomes a follower.
utils.removeScriptVar( talker, "ai.pathingToSocialize" );
utils.removeScriptVar( listener, "ai.pathingToSocialize" );
utils.removeScriptVar( talker, "ai.speaking" );
removeTriggerVolumeEventSource(SOCIAL_VOLUME, listener);
//removeObjVar( listener, "ai.speaking"); by not removing this objvar,
// the sandperson will no longer
// initiate or be invited to socialize
}
trigger OnBehaviorChange( int newBehavior, int oldBehavior, int[] changeFlags )
{
LOGC(aiLoggingEnabled(self), "debug_ai", "tusken_raider::OnBehaviorChange() self(" + self + ":" + getName(self) + ")");
if ( isIncapacitated(self) )
return SCRIPT_CONTINUE;
if ( ai_lib.isInCombat( self ))
return SCRIPT_OVERRIDE;
if ( newBehavior > oldBehavior )
{
if ( utils.hasScriptVar( self, "ai.pathingToSocialize") )
{
obj_id listener = utils.getObjIdScriptVar( self, "ai.pathingToSocialize");
endSocializing( self, listener );
}
if ( newBehavior >= BEHAVIOR_ALERT && newBehavior < BEHAVIOR_ATTACK )
{
doAgitateBehavior( self, newBehavior );
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
return SCRIPT_CONTINUE;
}
/*
if ( newBehavior <= BEHAVIOR_ALERT )
{
queueCommand(self, ##"combatTarget", null, "", COMMAND_PRIORITY_FRONT);
}
*/
if ( newBehavior == BEHAVIOR_CALM )
{
//debugSpeakMsg( self, "I AM CALM AGAIN" );
if ( utils.hasObjVar( self, "ai.isFollowing" ))
{
//debugSpeakMsg( self, "RESUMING FOLLOWING" );
//just resume following the guy:
followTusken( self, getObjIdObjVar( self, "ai.isFollowing" ));
return SCRIPT_OVERRIDE;//don't do the default AI thing
}
//debugSpeakMsg( self, "I AM CALM AGAIN and I AM THE LEADER" );
return SCRIPT_CONTINUE;
}
//do default behavior stuff:
return SCRIPT_CONTINUE;
}
void doAgitateBehavior( obj_id npc, int behavior )
{
if ( isInvulnerable( npc ) )
return;
if ( getConfigSetting("GameServer", "disableAICombat")!=null )
return;
//debugSpeakMsg( npc, "doing custom thing" );
//obj_id threat = ai_lib.getBehaviorTarget( npc, behavior );
//if ( threat == null )
return;
//else
// setObjVar( npc, "ai.threat", threat );
//
//switch ( behavior )
//{
// case BEHAVIOR_ALERT:
// stop( npc );
// ai_lib.setMood( npc, ai_lib.MOOD_NERVOUS );
// break;
// case BEHAVIOR_THREATEN:
// faceTo( npc, threat );
// doAnimationAction( npc, ACTION_THREATEN );
// //queueCommand(npc, ##"combatTarget", threat, "", COMMAND_PRIORITY_FRONT);
// ai_lib.setMood( npc, ai_lib.MOOD_THREATEN );
// break;
// case BEHAVIOR_FLEE:
// //queueCommand(npc, ##"combatTarget", null, "", COMMAND_PRIORITY_FRONT);
// cancelFollowing( npc );
// startCombat( npc, threat );
// break;
// case BEHAVIOR_PANIC:
// //queueCommand(npc, ##"combatTarget", null, "", COMMAND_PRIORITY_FRONT);
// cancelFollowing( npc );
// startCombat( npc, threat );
// break;
// default :
// //debugSpeakMsg( npc, "default: " + behavior );
// break;
//}
}
void followTusken( obj_id npc, obj_id target )
{
if ( !isIncapacitated(npc) )
{
removeTriggerVolumeEventSource(SOCIAL_VOLUME, target);
if ( !exists( target ) )
{
cancelFollowing( npc );
return;
}
//never follow anything with a lower obj_id that your own:
if ( target.getValue() < npc.getValue() )
return;
obj_id isFollowedBy = getObjIdObjVar( target, "ai.isFollowedBy" );
if ( isFollowedBy == null || isFollowedBy == npc )
{
setMovementWalk( npc );
follow( npc, target, 2f, 5f );
setObjVar( target, "ai.isFollowedBy", npc );
setObjVar( npc, "ai.isFollowing", target );
}
else
{
followTusken( npc, isFollowedBy );
}
}
}
messageHandler resumeLoitering()
{
obj_id isFollowing = getObjIdObjVar( self, "ai.isFollowing" );
if ( isFollowing == null )
{
if ( getBehavior(self) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 1, false );
return SCRIPT_CONTINUE;
}
else
{
followTusken( self, isFollowing );
return SCRIPT_OVERRIDE;
}
}
void cancelFollowing( obj_id npc )
{
utils.removeScriptVar( npc, "ai.speaking" );
obj_id isFollowing = getObjIdObjVar( npc, "ai.isFollowing" );
if ( isFollowing != null )
messageTo( isFollowing, "stopBeingFollowed", null, 0, false );
removeObjVar( npc, "ai.isFollowing" );
}
messageHandler stopBeingFollowed()
{
removeObjVar( self, "ai.isFollowedBy" );
return SCRIPT_CONTINUE;
}
messageHandler stopFollowing()
{
removeObjVar( self, "ai.isFollowing" );
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
trigger OnFollowTargetLost(obj_id oldTarget)
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
trigger OnFollowPathNotFound(obj_id target)
{
cancelFollowing( self );
messageTo( self, "resumeLoitering", null, 3, false );
return SCRIPT_CONTINUE;
}
void takeBantha( obj_id tusken, obj_id bantha )
{
if ( hasScript( bantha, "ai.tusken_bantha" ))
return;
if ( utils.hasScriptVar( tusken, "ai.bantha" ))
return;
utils.setScriptVar( tusken, "ai.bantha", bantha );
utils.setScriptVar( bantha, "ai.tusken", tusken );
attachScript( bantha, "ai.tusken_bantha" );
}
trigger OnIncapacitated(obj_id attacker)
{
removeTriggerVolume(SOCIAL_VOLUME);
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,28 @@
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.attrib;
public class victim extends script.base_script
{
public victim()
{
}
public int OnAttach(obj_id self) throws InterruptedException
{
setAttributeAttained(self, attrib.VICTIM);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
setAttributeAttained(self, attrib.VICTIM);
return SCRIPT_CONTINUE;
}
}
@@ -1,13 +0,0 @@
include library.attrib;
trigger OnAttach()
{
setAttributeAttained( self, attrib.VICTIM );
return SCRIPT_CONTINUE;
}
trigger OnInitialize()
{
setAttributeAttained( self, attrib.VICTIM );
return SCRIPT_CONTINUE;
}
@@ -0,0 +1,53 @@
package script.base;
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;
public class remote_object extends script.base_script
{
public remote_object()
{
}
public static final String REMOTE_OBJECT_MANAGER = "remote_object_manager";
public static final String BASE_NAME = "remote_object";
public static final String ATTACH_SCRIPTS = BASE_NAME + ".attachScripts";
public static final String CREATE_PARAMS = BASE_NAME + ".createParams";
public static final String CREATOR = BASE_NAME + ".creator";
public static final String IN_SPACE = BASE_NAME + ".inSpace";
public static final String OBJECT_NAME = BASE_NAME + ".objectName";
public static final String REMOTE_OBJECT = BASE_NAME + ".remoteObject";
public static final String REQUESTER = BASE_NAME + ".requester";
public static final String SCENE_NAME = BASE_NAME + ".sceneName";
public static final String USE_RANDOM_LOCATION = BASE_NAME + ".useRandomLocation";
public static final String X = BASE_NAME + ".x";
public static final String Y = BASE_NAME + ".y";
public static final String Z = BASE_NAME + ".z";
public static final String CREATE_REMOTE_OBJECT = "createRemoteObject";
public static final String CREATE_REMOTE_OBJECT_RESPONSE = "createRemoteObjectResponse";
public static final String RO = "RemoteObject";
public static final boolean LOGS_ENABLED = false;
public void log(String text) throws InterruptedException
{
log(text, LOGS_ENABLED);
}
public void logError(String text) throws InterruptedException
{
log("Error:" + text, true);
}
public void log(String text, boolean force) throws InterruptedException
{
if (LOGS_ENABLED || force)
{
LOG(RO, text);
}
}
public boolean logsEnabled() throws InterruptedException
{
return LOGS_ENABLED;
}
}
@@ -1,64 +0,0 @@
// =====================================================================
// remote_object.script
// =====================================================================
//-- cluster wide data object manager
const String REMOTE_OBJECT_MANAGER = "remote_object_manager";
//-- parameter prefix
const String BASE_NAME = "remote_object";
//-- parameters
const String ATTACH_SCRIPTS = BASE_NAME + ".attachScripts";
const String CREATE_PARAMS = BASE_NAME + ".createParams";
const String CREATOR = BASE_NAME + ".creator";
const String IN_SPACE = BASE_NAME + ".inSpace";
const String OBJECT_NAME = BASE_NAME + ".objectName";
const String REMOTE_OBJECT = BASE_NAME + ".remoteObject";
const String REQUESTER = BASE_NAME + ".requester";
const String SCENE_NAME = BASE_NAME + ".sceneName";
const String USE_RANDOM_LOCATION = BASE_NAME + ".useRandomLocation";
const String X = BASE_NAME + ".x";
const String Y = BASE_NAME + ".y";
const String Z = BASE_NAME + ".z";
//-- message handlers
const String CREATE_REMOTE_OBJECT = "createRemoteObject";
const String CREATE_REMOTE_OBJECT_RESPONSE= "createRemoteObjectResponse";
//-- logging
const String RO = "RemoteObject";
const boolean LOGS_ENABLED = false;
// ---------------------------------------------------------------------
void log(String text)
{
log(text, LOGS_ENABLED);
}
// ---------------------------------------------------------------------
void logError(String text)
{
log("Error:" + text, true);
}
// ---------------------------------------------------------------------
void log(String text, boolean force)
{
if (LOGS_ENABLED || force)
{
LOG(RO, text);
}
}
// ---------------------------------------------------------------------
boolean logsEnabled()
{
return LOGS_ENABLED;
}
// =====================================================================
@@ -0,0 +1,99 @@
package script.base;
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.create;
import script.library.space_create;
import script.library.space_quest;
import script.library.utils;
public class remote_object_creator extends script.base.remote_object
{
public remote_object_creator()
{
}
public void registerForRemoteObjectCreation(obj_id self) throws InterruptedException
{
log("registerForRemoteObjectCreation: setting cluster wide data.");
dictionary objectData = new dictionary();
objectData.put(CREATOR, self);
objectData.put(IN_SPACE, isSpaceScene());
replaceClusterWideData(REMOTE_OBJECT_MANAGER, getCurrentSceneName(), objectData, false, 0);
}
public int createRemoteObject(obj_id self, dictionary params) throws InterruptedException
{
log("createRemoteObject: message received.");
log("createRemoteObject: " + params.toString());
obj_id requester = params.getObjId(REQUESTER);
String objectName = params.getString(OBJECT_NAME);
boolean useRandomLocation = params.getBoolean(USE_RANDOM_LOCATION);
float x, y, z;
if (!useRandomLocation)
{
x = params.getFloat(X);
y = params.getFloat(Y);
z = params.getFloat(Z);
}
else
{
x = y = z = 0;
}
obj_id created;
if (isSpaceScene())
{
if (!useRandomLocation)
{
created = space_create.createShip(objectName, transform.identity.setPosition_p(x, y, z));
}
else
{
transform randomTransform = space_quest.getRandomPositionInSphere(transform.identity, 512, 2048);
vector pos = randomTransform.getPosition_p();
params.put(X, pos.x);
params.put(Y, pos.y);
params.put(Z, pos.z);
created = space_create.createShipHyperspace(objectName, randomTransform);
}
}
else
{
created = create.object(objectName, new location(x, y, z));
}
params.put(SCENE_NAME, getCurrentSceneName());
if (isValidId(created))
{
log("createRemoteObject: creation successful. [" + objectName + "][" + created + "]");
utils.setScriptVar(created, REQUESTER, requester);
utils.setScriptVar(created, CREATE_PARAMS, params);
if (params.containsKey(ATTACH_SCRIPTS))
{
String[] scripts = split(params.getString(ATTACH_SCRIPTS), ':');
for (int i = 0; i < scripts.length; ++i)
{
if (!hasScript(created, scripts[i]))
{
attachScript(created, scripts[i]);
}
}
}
}
else
{
logError("createRemoteObject: creation failed.");
}
params.put(REMOTE_OBJECT, created);
messageTo(requester, CREATE_REMOTE_OBJECT_RESPONSE, params, 0.0f, false);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException
{
registerForRemoteObjectCreation(self);
return SCRIPT_CONTINUE;
}
}
@@ -1,138 +0,0 @@
// =====================================================================
// remote_object_creator.script
// =====================================================================
include library.create;
include library.space_create;
include library.space_quest;
include library.utils;
// ---------------------------------------------------------------------
inherits base.remote_object;
// =====================================================================
/**
* Register an object for remote object creation.
* Self is registered to be available to create objects in its scene.
*/
void registerForRemoteObjectCreation(obj_id self)
{
log("registerForRemoteObjectCreation: setting cluster wide data.");
dictionary objectData = new dictionary();
objectData.put(CREATOR, self);
objectData.put(IN_SPACE, isSpaceScene());
//-- may want to put scene loading data here as well ... (and periodically update it)
replaceClusterWideData(REMOTE_OBJECT_MANAGER, getCurrentSceneName(), objectData, false, 0);
}
// ---------------------------------------------------------------------
/**
* Create a remote object.
* Set an script var on the created object to the object id of the requester for future communication.
* Send a message back to the requester with the object id of the object created.
* This will be an invalid id if creation fails.
*/
messageHandler createRemoteObject()
{
log("createRemoteObject: message received.");
log("createRemoteObject: " + params.toString());
//-- read input parameters
obj_id requester = params.getObjId(REQUESTER);
String objectName = params.getString(OBJECT_NAME);
boolean useRandomLocation = params.getBoolean(USE_RANDOM_LOCATION);
float x, y, z;
if (!useRandomLocation)
{
x = params.getFloat(X);
y = params.getFloat(Y);
z = params.getFloat(Z);
}
else
{
x = y = z = 0;
}
//-- create the object in the current scene
obj_id created;
if (isSpaceScene())
{
if (!useRandomLocation)
{
created = space_create.createShip(objectName, transform.identity.setPosition_p(x, y, z));
}
else
{
//-- determine a random location
transform randomTransform = space_quest.getRandomPositionInSphere(transform.identity, 512, 2048);
vector pos = randomTransform.getPosition_p();
params.put(X, pos.x);
params.put(Y, pos.y);
params.put(Z, pos.z);
//created = space_create.createShip(objectName, randomTransform);
created = space_create.createShipHyperspace(objectName, randomTransform);
}
}
else
{
created = create.object(objectName, new location(x, y, z));
}
params.put(SCENE_NAME, getCurrentSceneName());
//-- validation
if (isValidId(created))
{
log("createRemoteObject: creation successful. [" + objectName + "][" + created + "]");
utils.setScriptVar(created, REQUESTER, requester);
utils.setScriptVar(created, CREATE_PARAMS, params);
if (params.containsKey(ATTACH_SCRIPTS))
{
String[] scripts = split(params.getString(ATTACH_SCRIPTS), ':');
for (int i=0; i<scripts.length; ++i)
{
if (!hasScript(created, scripts[i]))
{
attachScript(created, scripts[i]);
}
}
}
}
else
{
logError("createRemoteObject: creation failed.");
}
//-- if the creation fails, the object id returned will be invalid
params.put(REMOTE_OBJECT, created);
//-- return message to requester
messageTo(requester, CREATE_REMOTE_OBJECT_RESPONSE, params, 0.0f, false);
return SCRIPT_CONTINUE;
}
// ---------------------------------------------------------------------
/**
* Register the object for remote object creation.
*/
trigger OnInitialize()
{
registerForRemoteObjectCreation(self);
return SCRIPT_CONTINUE;
}
// =====================================================================
@@ -0,0 +1,176 @@
package script.base;
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.utils;
public class remote_object_requester extends script.base.remote_object
{
public remote_object_requester()
{
}
public int OnClusterWideDataResponse(obj_id self, String managerName, String elementNameExp, int requestId, String[] elementNameList, dictionary[] dictionaryList, int lockKey) throws InterruptedException
{
if (logsEnabled())
{
log("OnClusterWideDataResponse() manager name (" + managerName + ") element name (" + elementNameExp + ") request id (" + requestId + ") match count (" + elementNameList.length + ") lock key (" + lockKey + ")");
for (int i = 0; i < elementNameList.length; ++i)
{
log("element " + (i + 1) + " is (" + elementNameList[i] + ")");
log("dictionary " + dictionaryList[i].toString());
}
}
if (managerName.equals(REMOTE_OBJECT_MANAGER))
{
if (dictionaryList.length < 1)
{
logError("No object available for remote creation. [" + elementNameExp + "]");
}
else if (!hasValidCreateScriptVars(self, requestId))
{
logError("Missing script vars for this request! [" + requestId + "]");
}
else if (utils.hasScriptVar(self, getSceneNameVarName(requestId)) && !elementNameExp.equals(getSceneName(self, requestId)))
{
logError("Wrong scene! [" + elementNameExp + "][" + getSceneName(self, requestId) + "]");
}
else
{
obj_id remoteObjectCreator = getRemoteObjectCreator(self, requestId, elementNameList, dictionaryList);
if (isValidId(remoteObjectCreator))
{
messageTo(remoteObjectCreator, CREATE_REMOTE_OBJECT, getRemoteCreateParams(self, requestId), 0.0f, false);
log("Remote object creation request sent!");
}
else
{
logError("No valid remote object creator found!");
}
}
removeRemoteCreateScriptVars(self, requestId);
}
return SCRIPT_CONTINUE;
}
public int createRemoteObjectResponse(obj_id self, dictionary params) throws InterruptedException
{
log("createRemoteObjectResponse: " + params.toString());
obj_id remoteObject = params.getObjId(REMOTE_OBJECT);
if (isValidId(remoteObject))
{
log("Successfully created " + remoteObject);
}
else
{
logError("Creation failed!");
}
return SCRIPT_CONTINUE;
}
public void remoteCreate(String sceneName, String objectName, float x, float y, float z) throws InterruptedException
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, sceneName, false, self);
utils.setScriptVar(self, getSceneNameVarName(requestId), sceneName);
utils.setScriptVar(self, getObjectNameVarName(requestId), objectName);
utils.setScriptVar(self, getUseRandomLocationVarName(requestId), false);
utils.setScriptVar(self, getXVarName(requestId), x);
utils.setScriptVar(self, getYVarName(requestId), y);
utils.setScriptVar(self, getZVarName(requestId), z);
}
public void remoteCreate(String sceneName, String objectName) throws InterruptedException
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, sceneName, false, self);
utils.setScriptVar(self, getSceneNameVarName(requestId), sceneName);
utils.setScriptVar(self, getObjectNameVarName(requestId), objectName);
utils.setScriptVar(self, getUseRandomLocationVarName(requestId), true);
}
public int remoteCreate() throws InterruptedException
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, "*", false, self);
return requestId;
}
public String getSceneNameVarName(int requestId) throws InterruptedException
{
return SCENE_NAME + "." + requestId;
}
public String getSceneName(obj_id self, int requestId) throws InterruptedException
{
return utils.getStringScriptVar(self, getSceneNameVarName(requestId));
}
public String getObjectNameVarName(int requestId) throws InterruptedException
{
return OBJECT_NAME + "." + requestId;
}
public String getObjectName(obj_id self, int requestId) throws InterruptedException
{
return utils.getStringScriptVar(self, getObjectNameVarName(requestId));
}
public String getXVarName(int requestId) throws InterruptedException
{
return X + "." + requestId;
}
public float getX(obj_id self, int requestId) throws InterruptedException
{
return utils.getFloatScriptVar(self, getXVarName(requestId));
}
public String getYVarName(int requestId) throws InterruptedException
{
return Y + "." + requestId;
}
public float getY(obj_id self, int requestId) throws InterruptedException
{
return utils.getFloatScriptVar(self, getYVarName(requestId));
}
public String getZVarName(int requestId) throws InterruptedException
{
return Z + "." + requestId;
}
public float getZ(obj_id self, int requestId) throws InterruptedException
{
return utils.getFloatScriptVar(self, getZVarName(requestId));
}
public String getUseRandomLocationVarName(int requestId) throws InterruptedException
{
return USE_RANDOM_LOCATION + "." + requestId;
}
public boolean getUseRandomLocationVarName(obj_id self, int requestId) throws InterruptedException
{
return utils.getBooleanScriptVar(self, getUseRandomLocationVarName(requestId));
}
public void removeRemoteCreateScriptVars(obj_id self, int requestId) throws InterruptedException
{
utils.removeScriptVar(self, getSceneNameVarName(requestId));
utils.removeScriptVar(self, getObjectNameVarName(requestId));
utils.removeScriptVar(self, getXVarName(requestId));
utils.removeScriptVar(self, getYVarName(requestId));
utils.removeScriptVar(self, getZVarName(requestId));
}
public boolean hasValidCreateScriptVars(obj_id self, int requestId) throws InterruptedException
{
return utils.hasScriptVar(self, getSceneNameVarName(requestId)) && utils.hasScriptVar(self, getObjectNameVarName(requestId));
}
public dictionary getRemoteCreateParams(obj_id self, int requestId) throws InterruptedException
{
dictionary createParams = new dictionary();
createParams.put(REQUESTER, self);
createParams.put(SCENE_NAME, getSceneName(self, requestId));
createParams.put(OBJECT_NAME, getObjectName(self, requestId));
createParams.put(X, getX(self, requestId));
createParams.put(Y, getY(self, requestId));
createParams.put(Z, getZ(self, requestId));
return createParams;
}
public obj_id getRemoteObjectCreator(obj_id self, int requestId, String[] elementNameList, dictionary[] dictionaryList) throws InterruptedException
{
int randomIndex = rand(0, dictionaryList.length);
obj_id remoteObjectCreator = dictionaryList[randomIndex].getObjId(CREATOR);
return remoteObjectCreator;
}
}
@@ -1,271 +0,0 @@
// =====================================================================
// remote_object_requester.script
// =====================================================================
include library.utils;
// ----------------------------------------------------------------------
inherits base.remote_object;
// ======================================================================
trigger OnClusterWideDataResponse(String managerName, String elementNameExp, int requestId,
String[] elementNameList, dictionary[] dictionaryList, int lockKey)
{
if (logsEnabled())
{
log("OnClusterWideDataResponse() manager name (" + managerName + ") element name ("
+ elementNameExp + ") request id (" + requestId + ") match count (" + elementNameList.length
+ ") lock key (" + lockKey + ")");
for (int i = 0; i < elementNameList.length; ++i)
{
log("element " + (i+1) + " is (" + elementNameList[i] + ")");
log("dictionary " + dictionaryList[i].toString());
}
}
if (managerName == REMOTE_OBJECT_MANAGER)
{
if (dictionaryList.length < 1)
{
logError("No object available for remote creation. [" + elementNameExp + "]");
}
else if (!hasValidCreateScriptVars(self, requestId))
{
logError("Missing script vars for this request! [" + requestId + "]");
}
else if (utils.hasScriptVar(self, getSceneNameVarName(requestId)) && !elementNameExp.equals(getSceneName(self, requestId)))
{
logError("Wrong scene! [" + elementNameExp + "][" + getSceneName(self, requestId) + "]");
}
else
{
obj_id remoteObjectCreator = getRemoteObjectCreator(self, requestId, elementNameList, dictionaryList);
if (isValidId(remoteObjectCreator))
{
messageTo(remoteObjectCreator, CREATE_REMOTE_OBJECT, getRemoteCreateParams(self, requestId), 0.0f, false);
log("Remote object creation request sent!");
}
else
{
logError("No valid remote object creator found!");
}
}
removeRemoteCreateScriptVars(self, requestId);
}
return SCRIPT_CONTINUE;
}
// ----------------------------------------------------------------------
messageHandler createRemoteObjectResponse()
{
log("createRemoteObjectResponse: " + params.toString());
obj_id remoteObject = params.getObjId(REMOTE_OBJECT);
if (isValidId(remoteObject))
{
log("Successfully created " + remoteObject);
}
else
{
logError("Creation failed!");
}
return SCRIPT_CONTINUE;
}
// ----------------------------------------------------------------------
void remoteCreate(String sceneName, String objectName, float x, float y, float z)
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, sceneName, false, self);
utils.setScriptVar(self, getSceneNameVarName(requestId), sceneName);
utils.setScriptVar(self, getObjectNameVarName(requestId), objectName);
utils.setScriptVar(self, getUseRandomLocationVarName(requestId), false);
utils.setScriptVar(self, getXVarName(requestId), x);
utils.setScriptVar(self, getYVarName(requestId), y);
utils.setScriptVar(self, getZVarName(requestId), z);
}
// ----------------------------------------------------------------------
void remoteCreate(String sceneName, String objectName)
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, sceneName, false, self);
utils.setScriptVar(self, getSceneNameVarName(requestId), sceneName);
utils.setScriptVar(self, getObjectNameVarName(requestId), objectName);
utils.setScriptVar(self, getUseRandomLocationVarName(requestId), true);
}
// ----------------------------------------------------------------------
/**
* Invoke remote create and the base class will provide all parameters
*/
int remoteCreate()
{
obj_id self = getSelf();
int requestId = getClusterWideData(REMOTE_OBJECT_MANAGER, "*", false, self);
return requestId;
}
// ----------------------------------------------------------------------
String getSceneNameVarName(int requestId)
{
return SCENE_NAME + "." + requestId;
}
// ----------------------------------------------------------------------
String getSceneName(obj_id self, int requestId)
{
return utils.getStringScriptVar(self, getSceneNameVarName(requestId));
}
// ----------------------------------------------------------------------
String getObjectNameVarName(int requestId)
{
return OBJECT_NAME + "." + requestId;
}
// ----------------------------------------------------------------------
String getObjectName(obj_id self, int requestId)
{
return utils.getStringScriptVar(self, getObjectNameVarName(requestId));
}
// ----------------------------------------------------------------------
String getXVarName(int requestId)
{
return X + "." + requestId;
}
// ----------------------------------------------------------------------
float getX(obj_id self, int requestId)
{
return utils.getFloatScriptVar(self, getXVarName(requestId));
}
// ----------------------------------------------------------------------
String getYVarName(int requestId)
{
return Y + "." + requestId;
}
// ----------------------------------------------------------------------
float getY(obj_id self, int requestId)
{
return utils.getFloatScriptVar(self, getYVarName(requestId));
}
// ----------------------------------------------------------------------
String getZVarName(int requestId)
{
return Z + "." + requestId;
}
// ----------------------------------------------------------------------
float getZ(obj_id self, int requestId)
{
return utils.getFloatScriptVar(self, getZVarName(requestId));
}
// ----------------------------------------------------------------------
String getUseRandomLocationVarName(int requestId)
{
return USE_RANDOM_LOCATION + "." + requestId;
}
// ----------------------------------------------------------------------
boolean getUseRandomLocationVarName(obj_id self, int requestId)
{
return utils.getBooleanScriptVar(self, getUseRandomLocationVarName(requestId));
}
// ----------------------------------------------------------------------
/**
* Base classes should override this method to remove creation parameters
*/
void removeRemoteCreateScriptVars(obj_id self, int requestId)
{
utils.removeScriptVar(self, getSceneNameVarName(requestId));
utils.removeScriptVar(self, getObjectNameVarName(requestId));
utils.removeScriptVar(self, getXVarName(requestId));
utils.removeScriptVar(self, getYVarName(requestId));
utils.removeScriptVar(self, getZVarName(requestId));
}
// ----------------------------------------------------------------------
/**
* Base classes should override this method if sceneName and objectName are not stored
*/
boolean hasValidCreateScriptVars(obj_id self, int requestId)
{
return utils.hasScriptVar(self, getSceneNameVarName(requestId)) &&
utils.hasScriptVar(self, getObjectNameVarName(requestId));
}
// ----------------------------------------------------------------------
/**
* Base classes should override this method to control creation parameters
*/
dictionary getRemoteCreateParams(obj_id self, int requestId)
{
dictionary createParams = new dictionary();
createParams.put(REQUESTER, self);
createParams.put(SCENE_NAME, getSceneName(self, requestId));
createParams.put(OBJECT_NAME, getObjectName(self, requestId));
createParams.put(X, getX(self, requestId));
createParams.put(Y, getY(self, requestId));
createParams.put(Z, getZ(self, requestId));
return createParams;
}
// ----------------------------------------------------------------------
/**
* Base classes should override this method to control which remote creator to use
*/
obj_id getRemoteObjectCreator(obj_id self, int requestId, String[] elementNameList, dictionary[] dictionaryList)
{
int randomIndex = rand(0, dictionaryList.length);
obj_id remoteObjectCreator = dictionaryList[randomIndex].getObjId(CREATOR);
return remoteObjectCreator;
}
// ======================================================================
@@ -0,0 +1,245 @@
package script;
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 java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
public class base_script extends script.base_class
{
public base_script()
{
}
public int OnLocateObject(obj_id self, dictionary params) throws InterruptedException
{
location l = getLocation(self);
obj_id requestor = params.getObjId("requestor");
if (requestor != null)
{
String callbackMethod = params.getString("callback");
if (callbackMethod != null)
{
params.put("location", l);
messageTo(requestor, callbackMethod, params, 0, false);
}
}
return SCRIPT_CONTINUE;
}
public int OnSetWaypointActive(obj_id self, dictionary params) throws InterruptedException
{
obj_id waypoint = params.getObjId("waypoint");
if (waypoint != null)
{
boolean isActive = params.getBoolean("isActive");
_setWaypointActiveNative(waypoint, isActive);
}
return SCRIPT_CONTINUE;
}
public int OnSetWaypointLocation(obj_id self, dictionary params) throws InterruptedException
{
obj_id waypoint = params.getObjId("waypoint");
if (waypoint != null)
{
location loc = params.getLocation("loc");
if (loc != null)
{
_setWaypointLocationNative(waypoint, loc);
}
}
return SCRIPT_CONTINUE;
}
public int getFirstFreeIndex(String[] array) throws InterruptedException
{
if (array != null)
{
for (int i = 0; i < array.length; i++)
{
if (array[i] == null || array[i].length() == 0)
{
return i;
}
}
}
return -1;
}
public void dumpObjvars(obj_id s, obj_var_list objvars, String[] names, String[] attribs) throws InterruptedException
{
if (s == null || objvars == null || names == null || attribs == null || names.length != attribs.length)
{
return;
}
int count = objvars.getNumItems();
int elem = getFirstFreeIndex(names);
for (int i = 0; i < count && elem >= 0 && elem < names.length; ++i)
{
obj_var o = objvars.getObjVar(i);
if (o != null)
{
if (o instanceof obj_var_list)
{
dumpObjvars(s, (obj_var_list)o, names, attribs);
elem = getFirstFreeIndex(names);
}
else
{
String name = "\"" + o.getName();
Object v = o.getData();
if (v != null)
{
String val = v.toString();
names[elem] = name;
attribs[elem] = val;
elem++;
}
}
}
}
}
public void dumpScriptvars(String[] names, String[] attribs) throws InterruptedException
{
if ((names == null) || (attribs == null) || (names.length != attribs.length))
{
return;
}
int i = getFirstFreeIndex(names);
if (i != -1 && i < names.length)
{
final obj_id self = getSelf();
deltadictionary scriptvars = self.getScriptVars();
java.util.Enumeration keys = scriptvars.keys();
names[i] = "\"***SCRIPTVARS***";
attribs[i] = "******";
i++;
Map sortedValues = new TreeMap();
while (keys.hasMoreElements() && i < names.length)
{
Object k = keys.nextElement();
String oldname = "\"" + k.toString();
String name = oldname.replace('.', '+');
debugServerConsoleMsg(self, "scriptvar name: " + name);
Object v = scriptvars.getObject(k);
String attrib = v.toString();
sortedValues.put(name, attrib);
}
Iterator keysSet = (sortedValues.keySet()).iterator();
while (keysSet.hasNext() && i < names.length)
{
names[i] = (String)keysSet.next();
attribs[i] = (String)sortedValues.get((String)names[i]);
++i;
}
}
}
public int OnGetScriptvars(obj_id self, obj_id player, String[] names, String[] attribs) throws InterruptedException
{
if (player != null)
{
ArrayList scripts = self.getScriptArrayList();
if (scripts == null || scripts.size() == 0)
{
return SCRIPT_CONTINUE;
}
String lastScript = (String)(scripts.get(scripts.size() - 1));
if (lastScript == null)
{
return SCRIPT_CONTINUE;
}
if (!lastScript.equals((getClass()).getName()))
{
return SCRIPT_CONTINUE;
}
if (isGod(player))
{
dumpScriptvars(names, attribs);
}
}
return SCRIPT_CONTINUE;
}
public int OnGetAttributes(obj_id self, obj_id player, String[] names, String[] attribs) throws InterruptedException
{
if ((names == null) || (attribs == null) || (names.length != attribs.length))
{
return SCRIPT_CONTINUE;
}
if (player != null)
{
ArrayList scripts = self.getScriptArrayList();
if (scripts == null || scripts.size() == 0)
{
return SCRIPT_CONTINUE;
}
String lastScript = (String)(scripts.get(scripts.size() - 1));
if (lastScript == null)
{
return SCRIPT_CONTINUE;
}
if (!lastScript.equals((getClass()).getName()))
{
return SCRIPT_CONTINUE;
}
if (isGod(player))
{
dumpScriptvars(names, attribs);
final int firstFreeIndex = getFirstFreeIndex(names);
if ((firstFreeIndex >= 0) && (firstFreeIndex < names.length))
{
names[firstFreeIndex] = "\"***OBJVARS***";
attribs[firstFreeIndex] = "******";
}
obj_var_list rootList = getObjVarList(self, "");
if (rootList != null)
{
dumpObjvars(self, rootList, names, attribs);
}
}
}
return SCRIPT_CONTINUE;
}
public String UploadCharacter(obj_id player) throws InterruptedException
{
dictionary params = new dictionary();
Object[] triggerParams = new Object[2];
triggerParams[0] = player;
triggerParams[1] = params;
try
{
int err = script_entry.runScripts("OnUploadCharacter", triggerParams);
if (err == SCRIPT_CONTINUE)
{
byte[] packedData = params.pack();
return new String(packedData);
}
}
catch(Throwable t)
{
return null;
}
return null;
}
public String DownloadCharacter(obj_id player, String packedData) throws InterruptedException
{
byte[] data = packedData.getBytes();
dictionary params = dictionary.unpack(data);
Object[] triggerParams = new Object[2];
triggerParams[0] = player;
triggerParams[1] = params;
try
{
script_entry.runScripts("OnDownloadCharacter", triggerParams);
}
catch(Throwable t)
{
return null;
}
return "OK";
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
package script.beta;
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;
public class character_age extends script.base_script
{
public character_age()
{
}
public int OnSpeaking(obj_id self, String text) throws InterruptedException
{
obj_id target = getLookAtTarget(self);
if (target == null)
{
target = self;
}
if (text.equals("age"))
{
int age = getCurrentBirthDate() - getPlayerBirthDate(target);
sendSystemMessageTestingOnly(self, "Age ->" + age);
}
return SCRIPT_CONTINUE;
}
}
@@ -1,18 +0,0 @@
/***** TRIGGERS ********************************************************/
trigger OnSpeaking(string text)
{
obj_id target = getLookAtTarget(self);
if (target == null)
target = self;
if (text == "age")
{
int age = getCurrentBirthDate() - getPlayerBirthDate(target);
//debugSpeakMsg(self, "Age ->" + age);
sendSystemMessageTestingOnly(self, "Age ->" + age);
}
return SCRIPT_CONTINUE;
}

Some files were not shown because too many files have changed in this diff Show More