mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-13 22:01:04 -04:00
who isn't sick of converting the freaking scripts? this negates the need
This commit is contained in:
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
Reference in New Issue
Block a user