Files
dsrc/sku.0/sys.server/compiled/game/script/ai/beast.java

1199 lines
44 KiB
Java
Executable File

package script.ai;
import script.*;
import script.library.*;
public class beast extends script.base_script
{
public beast()
{
}
public static final String MENU_FILE = "pet/pet_menu";
public static final int MAX_UNACKNOWLEDGED_MESSAGE_COUNT = 3;
public static final int PING_INTERVAL = 120;
public static final int PING_INTERVAL_RETRY = 30;
public static final float MAX_DISTANCE_FROM_MASTER = 128.0f;
public static final boolean BEAST_DEBUG = false;
public static final string_id PCOLOR = new string_id("sui", "set_primary_color");
public void blog(String text) throws InterruptedException
{
if (BEAST_DEBUG)
{
LOG("beast.script", text);
}
}
public int OnAttach(obj_id self) throws InterruptedException
{
setObjVar(self, "beast.pingMessageNumber", 0);
setObjVar(self, "beast.lastAcknowledgeNumber", 0);
messageTo(self, "handleSetupBeast", null, 1, false);
messageTo(self, "beastPing", null, 5, false);
return SCRIPT_CONTINUE;
}
public int OnAddedToWorld(obj_id self) throws InterruptedException
{
messageTo(self, "handleSetupBeast", null, 1, false);
return SCRIPT_CONTINUE;
}
public int OnGetAttributes(obj_id self, obj_id player, String[] names, String[] attribs) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
int idx = utils.getValidAttributeIndex(names);
obj_id master = getMaster(self);
obj_id beastBCD = beast_lib.getBeastBCD(self);
if (!beast_lib.isValidPlayer(master))
{
return SCRIPT_CONTINUE;
}
names[idx] = "owner";
attribs[idx] = getName(master);
idx++;
if (exists(beastBCD) && hasObjVar(beastBCD, beast_lib.OBJVAR_BEAST_ENGINEER))
{
String creatorName = getStringObjVar(beastBCD, beast_lib.OBJVAR_BEAST_ENGINEER);
names[idx] = "bm_creator";
attribs[idx] = creatorName;
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
names[idx] = "health";
attribs[idx] = " " + (int)getMaxAttrib(self, HEALTH);
idx++;
int level = getLevel(self);
if (level < 90)
{
dictionary beastStatsNextLevel = utils.dataTableGetRow(beast_lib.BEASTS_STATS, level - 1);
int experienceLastLevel = 0;
int experienceNextLevel = 0;
if (level > 1)
{
dictionary beastStatsLastLevel = utils.dataTableGetRow(beast_lib.BEASTS_STATS, level - 2);
if (beastStatsLastLevel == null || beastStatsLastLevel.size() <= 0)
{
return SCRIPT_CONTINUE;
}
experienceLastLevel = beastStatsLastLevel.getInt("XP");
}
if (beastStatsNextLevel == null || beastStatsNextLevel.size() <= 0)
{
blog("initializeBeastStats() missing entry in the " + beast_lib.BEASTS_STATS + " table for level: " + level + ".");
return SCRIPT_CONTINUE;
}
experienceNextLevel = beastStatsNextLevel.getInt("XP");
int beastExperience = beast_lib.getBeastExperience(self);
int experienceProgress = beastExperience - experienceLastLevel;
int experienceNeeded = experienceNextLevel - experienceLastLevel;
int experiencePercentage = 0;
if (experienceProgress > 0)
{
experiencePercentage = (int)(((float)experienceProgress / experienceNeeded) * 100);
}
names[idx] = "level_progress";
attribs[idx] = String.valueOf(experiencePercentage) + "%";
idx++;
}
if (beast_lib.getBeastCanLevel(self))
{
names[idx] = "exp_on";
attribs[idx] = "true";
idx++;
}
else
{
names[idx] = "exp_off";
attribs[idx] = "true";
idx++;
}
names[idx] = beast_lib.BEAST_MOOD_TITLE;
String currentHappiness = utils.packStringId(beast_lib.convertHappinessString(beastBCD));
if (currentHappiness != null)
{
attribs[idx] = String.valueOf(currentHappiness);
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
names[idx] = beast_lib.BEAST_LOYALTY_TITLE;
String currentLoyalty = utils.packStringId(beast_lib.convertLoyaltyString(beastBCD));
if (currentLoyalty != null)
{
attribs[idx] = String.valueOf(currentLoyalty);
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
int loyaltyPercentage = beast_lib.getBeastLoyaltyToNextLevelPercentage(self);
if (loyaltyPercentage >= 0)
{
names[idx] = beast_lib.BEAST_LOYALTY_PERCENTAGE_TITLE;
attribs[idx] = String.valueOf(loyaltyPercentage) + "%";
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
String[] abilityList = beast_lib.getBeastmasterPetBarData(player, self);
int slotsAvalable = getSkillStatisticModifier(player, "expertise_bm_add_pet_bar");
if (!abilityList[3].equals("") && slotsAvalable >= 0 && !abilityList[3].equals("empty") && !abilityList[3].equals("disabled"))
{
names[idx] = "bm_ability_1";
attribs[idx] = String.valueOf(utils.packStringId(new string_id("cmd_n", abilityList[3])));
idx++;
}
if (!abilityList[4].equals("") && slotsAvalable >= 1 && !abilityList[4].equals("empty") && !abilityList[4].equals("disabled"))
{
names[idx] = "bm_ability_2";
attribs[idx] = String.valueOf(utils.packStringId(new string_id("cmd_n", abilityList[4])));
idx++;
}
if (!abilityList[5].equals("") && slotsAvalable >= 2 && !abilityList[5].equals("empty") && !abilityList[5].equals("disabled"))
{
names[idx] = "bm_ability_3";
attribs[idx] = String.valueOf(utils.packStringId(new string_id("cmd_n", abilityList[5])));
idx++;
}
if (!abilityList[6].equals("") && slotsAvalable >= 3 && !abilityList[6].equals("empty") && !abilityList[6].equals("disabled"))
{
names[idx] = "bm_ability_4";
attribs[idx] = String.valueOf(utils.packStringId(new string_id("cmd_n", abilityList[6])));
idx++;
}
names[idx] = "armorhpmax";
attribs[idx] = String.valueOf((utils.getIntScriptVar(self, "beast.display.armor") + getEnhancedSkillStatisticModifier(self, "private_armor_bonus")));
idx++;
obj_id beastWeapon = getCurrentWeapon(self);
if (isIdValid(beastWeapon))
{
int minDamage = getWeaponMinDamage(beastWeapon);
int maxDamage = getWeaponMaxDamage(beastWeapon);
int expertiseDamageBonus = getEnhancedSkillStatisticModifierUncapped(self, "expertise_damage_all");
minDamage = (int)(minDamage * (1.0f + (expertiseDamageBonus / 100.0f)));
maxDamage = (int)(maxDamage * (1.0f + (expertiseDamageBonus / 100.0f)));
float weaponSpeed = getWeaponAttackSpeed(beastWeapon);
names[idx] = "damage";
attribs[idx] = minDamage + " - " + maxDamage;
idx++;
names[idx] = "attackspeed";
attribs[idx] = String.valueOf(weaponSpeed);
idx++;
float beastDPS = utils.roundFloatByDecimal((minDamage + maxDamage) / weaponSpeed / 2);
names[idx] = "basedps";
attribs[idx] = String.valueOf(beastDPS);
idx++;
}
else
{
obj_id defaultWeapon = getDefaultWeapon(self);
if (isIdValid(defaultWeapon))
{
int minDamage = getWeaponMinDamage(defaultWeapon);
int maxDamage = getWeaponMaxDamage(defaultWeapon);
float weaponSpeed = getWeaponAttackSpeed(defaultWeapon);
int expertiseDamageBonus = getEnhancedSkillStatisticModifierUncapped(self, "expertise_damage_all");
minDamage = (int)(minDamage * (1.0f + (expertiseDamageBonus / 100.0f)));
maxDamage = (int)(maxDamage * (1.0f + (expertiseDamageBonus / 100.0f)));
names[idx] = "damage";
attribs[idx] = minDamage + " - " + maxDamage;
idx++;
names[idx] = "attackspeed";
attribs[idx] = String.valueOf(weaponSpeed);
idx++;
float beastDPS = utils.roundFloatByDecimal((minDamage + maxDamage) / weaponSpeed / 2);
names[idx] = "basedps";
attribs[idx] = String.valueOf(beastDPS);
idx++;
}
}
if (beast_lib.DISPLAY_NAMES.length == beast_lib.ARRAY_BEAST_INCUBATION_STATS.length && beast_lib.DISPLAY_NAMES.length == beast_lib.DISPLAY_CONVERSION_RATES.length)
{
for (int i = 0; i < beast_lib.DISPLAY_NAMES.length; ++i)
{
String name = beast_lib.DISPLAY_NAMES[i];
if (!name.contains("_skill"))
{
if (!name.equals("block_value_bonus"))
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = String.valueOf(utils.roundFloatByDecimal((utils.getFloatScriptVar(self, beast_lib.ARRAY_BEAST_INCUBATION_STATS[i]) * beast_lib.DISPLAY_CONVERSION_RATES[i]))) + "%";
idx++;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = String.valueOf(utils.roundFloatByDecimal(utils.getFloatScriptVar(self, beast_lib.ARRAY_BEAST_INCUBATION_STATS[i])));
idx++;
}
continue;
}
else
{
names[idx] = beast_lib.DISPLAY_NAMES[i];
attribs[idx] = String.valueOf(utils.roundFloatByDecimal(utils.getFloatScriptVar(self, beast_lib.ARRAY_BEAST_INCUBATION_STATS[i])));
idx++;
continue;
}
}
}
float glanceReduct = beast_lib.getBeastModGlancingReduction(self);
if (glanceReduct > 0)
{
names[idx] = "bm_glance_reduct";
attribs[idx] = String.valueOf(glanceReduct) + "%";
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
float damageReduct = beast_lib.getBeastModDamageReduction(self);
if (damageReduct > 0)
{
names[idx] = "bm_damage_reduct";
attribs[idx] = String.valueOf(damageReduct) + "%";
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
float punishReduct = beast_lib.getBeastModPunishingReduction(self);
if (punishReduct > 0)
{
names[idx] = "bm_punish_reduct";
attribs[idx] = String.valueOf(punishReduct) + "%";
idx++;
if (idx >= names.length)
{
return SCRIPT_CONTINUE;
}
}
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))
{
if (isIdValid(beast_lib.getBeastOnPlayer(master)))
{
blog("Beast not cleaned up on " + master + " and something attempted to detach its beast script.");
return SCRIPT_OVERRIDE;
}
}
return SCRIPT_CONTINUE;
}
public int OnDestroy(obj_id self) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master))
{
if (isIdValid(beast_lib.getBeastOnPlayer(master)))
{
blog("Beast not cleaned up on " + master + " and something attempted to destroy it.");
return SCRIPT_OVERRIDE;
}
}
return SCRIPT_CONTINUE;
}
public int handleSetupBeast(obj_id self, dictionary params) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (!isIdValid(master) || !exists(master))
{
blog("handleSetupBeast() master is not valid. Destroying beast.");
destroyObject(self);
return SCRIPT_CONTINUE;
}
if (isPlayer(master))
{
setObjVar(self, "ai.pet", true);
}
beast_lib.beastFollowTarget(self, master);
if (!ai_lib.isInCombat(self) && stealth.canBeastStealth(self))
{
stealth.makeBeastInvisible(master, "appearance/pt_smoke_puff.prt");
}
return SCRIPT_CONTINUE;
}
public int beastPing(obj_id self, dictionary params) throws InterruptedException
{
int lastMessage = getIntObjVar(self, "beast.pingMessageNumber");
int nextMessage = lastMessage + 1;
setObjVar(self, "beast.pingMessageNumber", nextMessage);
int acknowledgedMessage = getIntObjVar(self, "beast.lastAcknowledgeNumber");
int unacknowledgedGap = lastMessage - acknowledgedMessage;
obj_id master = getMaster(self);
if (!isIdValid(master) || !exists(master))
{
setMaster(self, null);
blog("beastPing() master is not valid. Destroying beast.");
if (destroyObject(self))
{
return SCRIPT_CONTINUE;
}
else
{
blog("beastPing() failed to destroy the beast with no master online");
}
}
obj_id bcd = beast_lib.getBeastBCD(self);
if (!beast_lib.isValidBCD(bcd))
{
setMaster(self, null);
blog("beastPing() bcd is not valid. Destroying beast.");
if (destroyObject(self))
{
return SCRIPT_CONTINUE;
}
else
{
blog("beastPing() failed to destroy the beast with no BCD online");
}
}
if (unacknowledgedGap > MAX_UNACKNOWLEDGED_MESSAGE_COUNT)
{
beast_lib.storeBeast(bcd);
return SCRIPT_CONTINUE;
}
if (getDistance(self, master) > MAX_DISTANCE_FROM_MASTER)
{
blog("self: " + self + " too far from master: " + master + "(" + getDistance(self, master) + " and is being stored.");
beast_lib.storeBeast(bcd);
return SCRIPT_CONTINUE;
}
int nextCallbackInterval = (unacknowledgedGap <= 0) ? PING_INTERVAL : PING_INTERVAL_RETRY;
dictionary messageData = new dictionary();
messageData.put("beastId", self);
messageData.put("messageId", nextMessage);
messageTo(bcd, "beastPing", messageData, 1, false);
messageTo(self, "beastPing", null, nextCallbackInterval, false);
return SCRIPT_CONTINUE;
}
public int bcdPingResponse(obj_id self, dictionary params) throws InterruptedException
{
int ack = params.getInt("messageId");
int previousAck = getIntObjVar(self, "beast.pingMessageNumber");
if (ack > previousAck)
{
setObjVar(self, "beast.lastAcknowledgeNumber", ack);
}
return SCRIPT_CONTINUE;
}
public int resumeDefaultCalmBehavior(obj_id self, dictionary params) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (!isIdValid(master))
{
blog("resumeDefaultCalmBehavior() master is invalid and is being destroyed.");
destroyObject(self);
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (isIdValid(master))
{
location masterLoc = getLocation(master);
if(isValidLocation(masterLoc))
setHomeLocation(self, masterLoc);
}
return SCRIPT_CONTINUE;
}
public int checkMovementSpeed(obj_id self, dictionary params) throws InterruptedException
{
obj_id target = params.getObjId("target");
beast_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
public int OnFollowWaiting(obj_id self, obj_id target) throws InterruptedException
{
beast_lib.validateFollowTarget(self, target);
return SCRIPT_CONTINUE;
}
public int OnFollowMoving(obj_id self, obj_id target) throws InterruptedException
{
beast_lib.validateFollowTarget(self, target);
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;
}
LOG("beast", "OnBehaviorChange newBehavior: " + newBehavior + " oldBehavior: " + oldBehavior);
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_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;
}
public int OnIncapacitated(obj_id self, obj_id attacker) throws InterruptedException
{
beast_lib.killBeast(self, attacker);
return SCRIPT_CONTINUE;
}
public int handleBeastIncappedDecay(obj_id self, dictionary params) throws InterruptedException
{
int incapTimer = utils.getIntScriptVar(self, "incapTimer");
int messageTimer = params.getInt("incapTimer");
if (incapTimer != messageTimer)
{
return SCRIPT_CONTINUE;
}
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (!isIdValid(master))
{
return SCRIPT_CONTINUE;
}
if (isIncapacitated(self))
{
blog("handleBeastIncappedDecay() destroying self from incapacitation.");
destroyObject(self);
}
return SCRIPT_CONTINUE;
}
public int OnRecapacitated(obj_id self) throws InterruptedException
{
beast_lib.beastFollowTarget(self, getMaster(self));
return SCRIPT_CONTINUE;
}
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info mi) throws InterruptedException
{
if (!isIdValid(player))
{
return SCRIPT_CONTINUE;
}
if (isDead(self) || ai_lib.aiIsDead(player))
{
return SCRIPT_CONTINUE;
}
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (player != getMaster(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
int opt_menu = 0;
if (beast_lib.isBeastMaster(player))
{
if (!beast_lib.getBeastCanLevel(self))
{
mi.addRootMenu(menu_info_types.SERVER_MENU1, new string_id(MENU_FILE, "exp_on"));
}
else
{
mi.addRootMenu(menu_info_types.SERVER_MENU1, new string_id(MENU_FILE, "exp_off"));
}
}
obj_id bcd = beast_lib.getBeastBCD(self);
if (!ai_lib.isInCombat(player) && !ai_lib.isAiDead(self) && !ai_lib.aiIsDead(player))
{
mi.addRootMenu(menu_info_types.SERVER_MENU2, new string_id("beast", "name_beast"));
}
if (!ai_lib.isInCombat(player))
{
mi.addRootMenu(menu_info_types.PET_STORE, new string_id(MENU_FILE, "menu_store"));
}
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (hasObjVar(bcd, beast_lib.OBJVAR_OLD_PET_IDENTIFIER) && !hasObjVar(bcd, beast_lib.OBJVAR_OLD_PET_REHUED))
{
mi.addRootMenu(menu_info_types.SERVER_MENU3, PCOLOR);
}
return SCRIPT_CONTINUE;
}
public int OnObjectMenuSelect(obj_id self, obj_id player, int item) throws InterruptedException
{
if (!isIdValid(player))
{
return SCRIPT_CONTINUE;
}
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;
}
obj_id bcd = beast_lib.getBeastBCD(self);
if (!isIdValid(bcd) || !exists(bcd))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isAiDead(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(player) || ai_lib.isAiDead(player))
{
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.SERVER_MENU1)
{
boolean canLevel = !beast_lib.getBeastCanLevel(self);
beast_lib.setBeastCanLevel(self, canLevel);
beast_lib.setBCDBeastCanLevel(bcd, canLevel);
sendDirtyObjectMenuNotification(self);
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.SERVER_MENU2)
{
if (!ai_lib.isInCombat(player) && !ai_lib.isAiDead(self) && !ai_lib.aiIsDead(player))
{
sui.inputbox(self, player, "@beast:name_d", sui.OK_CANCEL, "@beast:name_t", sui.INPUT_NORMAL, null, "handleSetBeastName", null);
}
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.PET_STORE)
{
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(bcd);
return SCRIPT_CONTINUE;
}
if (item == menu_info_types.PET_COMMAND)
{
pet_lib.openLearnCommandSui(self, player);
}
if (item == menu_info_types.SERVER_MENU3)
{
if (hasObjVar(bcd, beast_lib.OBJVAR_OLD_PET_IDENTIFIER) && !hasObjVar(bcd, beast_lib.OBJVAR_OLD_PET_REHUED))
{
sui.colorize(self, player, self, hue.INDEX_1, "handlePrimaryColorize");
}
}
return SCRIPT_CONTINUE;
}
public int handlePrimaryColorize(obj_id self, dictionary params) throws InterruptedException
{
obj_id beast = self;
if (!isValidId(beast))
{
return SCRIPT_CONTINUE;
}
obj_id bcd = beast_lib.getBeastBCD(beast);
if (!isValidId(bcd))
{
return SCRIPT_CONTINUE;
}
int idx = sui.getColorPickerIndex(params);
int bp = sui.getIntButtonPressed(params);
if (bp == sui.BP_CANCEL)
{
return SCRIPT_CONTINUE;
}
if (idx > -1)
{
setObjVar(bcd, beast_lib.OBJVAR_BEAST_HUE, idx);
hue.setColor(beast, "/private/index_color_1", idx);
setObjVar(bcd, beast_lib.OBJVAR_OLD_PET_REHUED, 1);
}
return SCRIPT_CONTINUE;
}
public int handleSetBeastName(obj_id self, dictionary params) throws InterruptedException
{
obj_id player = sui.getPlayerId(params);
String beastName = sui.getInputBoxText(params);
int btn = sui.getIntButtonPressed(params);
if (btn == sui.BP_CANCEL)
{
return SCRIPT_CONTINUE;
}
if (beastName.equals("") || isNameReserved(beastName))
{
sendSystemMessage(player, new string_id("player_structure", "obscene"));
sui.inputbox(self, player, "@beast:name_d", sui.OK_CANCEL, "@beast:name_t", sui.INPUT_NORMAL, null, "handleSetBeastName", null);
return SCRIPT_CONTINUE;
}
beastName = beastName.trim();
if (beastName.length() < 3)
{
sendSystemMessage(player, new string_id("beast", "name_too_short"));
sui.inputbox(self, player, "@beast:name_d", sui.OK_CANCEL, "@beast:name_t", sui.INPUT_NORMAL, null, "handleSetBeastName", null);
return SCRIPT_CONTINUE;
}
if (beastName.length() > 40)
{
sendSystemMessage(player, new string_id("beast", "name_too_long"));
sui.inputbox(self, player, "@beast:name_d", sui.OK_CANCEL, "@beast:name_t", sui.INPUT_NORMAL, null, "handleSetBeastName", null);
return SCRIPT_CONTINUE;
}
sendDirtyObjectMenuNotification(self);
beast_lib.setBCDBeastName(beast_lib.getBeastBCD(self), beastName);
beast_lib.setBeastName(self, beastName);
return SCRIPT_CONTINUE;
}
public int handleGroupInvite(obj_id self, dictionary params) throws InterruptedException
{
return SCRIPT_CONTINUE;
}
public int postCombatPathHome(obj_id self, dictionary params) throws InterruptedException
{
LOGC(aiLoggingEnabled(self), "debug_ai", "pet::postCombatPathHome() self(" + self + ":" + getName(self) + ") master(" + getMaster(self) + ":" + getName(getMaster(self)) + ")");
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self))
{
return SCRIPT_CONTINUE;
}
if (utils.hasScriptVar(self, "ai.pet.staying"))
{
return SCRIPT_CONTINUE;
}
obj_id guardTarget = utils.getObjIdScriptVar(self, "ai.pet.guarding");
if (isIdValid(guardTarget))
{
pet_lib.petFollow(self, guardTarget);
}
else if (hasObjVar(self, "ai.inFormation"))
{
ai_lib.resumeFormationFollowing(self);
}
else
{
obj_id master = getMaster(self);
if (isIdValid(master) && master.isLoaded())
{
pet_lib.petFollow(self, master);
}
else
{
stop(self);
}
}
return SCRIPT_OVERRIDE;
}
public int handleAbandonment(obj_id self, dictionary params) throws InterruptedException
{
int ignoredForDays = getIntObjVar(self, "ai.pet.ignoredForDays");
ignoredForDays++;
if (ignoredForDays > 3)
{
pet_lib.releasePet(self);
return SCRIPT_CONTINUE;
}
else
{
setObjVar(self, "ai.pet.ignoredForDays", ignoredForDays);
}
messageTo(self, "handleAbandonment", null, 86400, false);
return SCRIPT_CONTINUE;
}
public int resumePetTrick(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = params.getObjId("master");
int trickNum = params.getInt("trickNum");
pet_lib.doStupidPetTrick(self, master, trickNum);
return SCRIPT_CONTINUE;
}
public int OnGiveItem(obj_id self, obj_id item, obj_id player) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (!isIdValid(master))
{
return SCRIPT_CONTINUE;
}
int pet_food = getIntObjVar(item, "race_restriction");
if (pet_lib.isCreaturePet(self) && (pet_food == -2) && (player == master))
{
food.petEatFood(self, master, item, player);
return SCRIPT_CONTINUE;
}
obj_id petControlDevice = callable.getCallableCD(self);
obj_id petInv = utils.getInventoryContainer(petControlDevice);
if (!isIdValid(petInv))
{
return SCRIPT_CONTINUE;
}
if (player != master)
{
return SCRIPT_CONTINUE;
}
if (isMob(item))
{
return SCRIPT_CONTINUE;
}
else if (!ai_lib.isNpc(self) || !ai_lib.isAndroid(self))
{
return SCRIPT_CONTINUE;
}
putIn(item, petInv);
return SCRIPT_CONTINUE;
}
public int handleMoveToMaster(obj_id self, dictionary params) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master))
{
location targetLocation = new location(getLocation(master));
targetLocation.x += rand(-4.0f, +4.0f);
targetLocation.z += rand(-4.0f, +4.0f);
targetLocation.y = getHeightAtLocation(targetLocation.x, targetLocation.z);
setLocation(self, getLocation(master));
pathTo(self, targetLocation);
}
return SCRIPT_CONTINUE;
}
public int handlePackRequest(obj_id self, dictionary params) throws InterruptedException
{
blog("handlePackRequest() destroying beast.");
if (!destroyObject(self))
{
debugServerConsoleMsg(null, "+++ beast.messageHandler handlePackRequest +++ WARNINGWARNING - FAILED TO DESTROY SELF");
}
return SCRIPT_CONTINUE;
}
public int handleAddToStomach(obj_id self, dictionary params) throws InterruptedException
{
int stomach = params.getInt("stomach");
int vol = params.getInt("vol");
player_stomach.addToStomach(self, stomach, vol);
return SCRIPT_CONTINUE;
}
public int handleSetColors(obj_id self, dictionary params) throws InterruptedException
{
if (params == null || params.isEmpty())
{
return SCRIPT_CONTINUE;
}
setColors(self, params);
return SCRIPT_CONTINUE;
}
public boolean setColors(obj_id self, dictionary params) throws InterruptedException
{
if (params == null || params.isEmpty())
{
return false;
}
boolean litmus = true;
java.util.Enumeration keys = params.keys();
while (keys.hasMoreElements())
{
String var = (String)keys.nextElement();
int idx = params.getInt(var);
litmus &= hue.setColor(self, var, idx);
}
return litmus;
}
public int OnEnteredCombat(obj_id self) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
obj_id master = getMaster(self);
if (isIdValid(master) && master.isLoaded())
{
aiSetHomeLocation(self, getLocation(master));
}
else
{
aiSetHomeLocation(self, getLocation(self));
}
return SCRIPT_CONTINUE;
}
public int OnDefenderCombatAction(obj_id self, obj_id attacker, obj_id weapon, int combatResult) throws InterruptedException
{
if (!beast_lib.getBeastDefensive(self))
{
return SCRIPT_OVERRIDE;
}
if (utils.hasScriptVar(self, "petIgnoreAttacks"))
{
int timeStarted = utils.getIntScriptVar(self, "petIgnoreAttacks");
blog("OnDefenderCombatAction() beast hasScriptVar petIgnoreAttacks timeStarted: " + timeStarted + " getGameTime: " + getGameTime());
if (getGameTime() < (timeStarted + 20))
{
return SCRIPT_OVERRIDE;
}
utils.removeScriptVar(self, "petIgnoreAttacks");
}
return SCRIPT_CONTINUE;
}
public int OnSawAttack(obj_id self, obj_id defender, obj_id[] attackers) throws InterruptedException
{
if (beast_lib.isBeast(self) && beast_lib.getBeastDefensive(self))
{
for (final obj_id attacker : attackers) {
if (isIdValid(attacker) && !ai_lib.isInCombat(self) && defender == getMaster(self)) {
addHate(self, attacker, 0.0f);
}
}
}
return SCRIPT_CONTINUE;
}
public int OnExitedCombat(obj_id self) throws InterruptedException
{
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
utils.setScriptVar(self, "beast.combatEnded", getGameTime());
if (!utils.hasScriptVar(self, "ai.pet.staying"))
{
obj_id master = getMaster(self);
if (isIdValid(master) && master.isLoaded())
{
beast_lib.beastFollowTarget(self, master);
if (beast_lib.getBeastDefensive(self))
{
messageTo(self, "defensiveModePing", null, 1.0f, false);
}
if (!beast_lib.getBeastDefensive(self) && !utils.hasScriptVar(self, "petIgnoreAttacks"))
{
utils.setScriptVar(self, "petIgnoreAttacks", getGameTime());
}
}
else
{
aiSetHomeLocation(self, getLocation(self));
}
}
else
{
obj_id master = getMaster(self);
if (isIdValid(master) && master.isLoaded())
{
beast_lib.doStayCommand(self, master);
}
else
{
ai_lib.aiStopFollowing(self);
location myLocation = getLocation(self);
setHomeLocation(self, myLocation);
setMovementWalk(self);
ai_lib.setDefaultCalmBehavior(self, ai_lib.BEHAVIOR_STOP);
}
}
return SCRIPT_CONTINUE;
}
public int OnSawEmote(obj_id self, obj_id performer, String emote) throws InterruptedException
{
obj_id master = getMaster(self);
if (performer != master)
{
return SCRIPT_CONTINUE;
}
if (!isMob(self))
{
return SCRIPT_CONTINUE;
}
if (!isPlayer(master))
{
return SCRIPT_CONTINUE;
}
if (ai_lib.isInCombat(self) || ai_lib.isInCombat(master) || ai_lib.aiIsDead(self))
{
return SCRIPT_CONTINUE;
}
if (getLookAtTarget(master) != self)
{
if (getIntendedTarget(master) != self)
{
return SCRIPT_CONTINUE;
}
}
if (emote.startsWith("pet") || emote.equals("reassure") || emote.equals("nuzzle") || emote.equals("hug"))
{
if (rand(1, 2) == 1)
{
stop(self);
if (ai_lib.canSit(self))
{
if (rand(1, 2) == 1)
{
ai_lib.aiSetPosture(self, POSTURE_SITTING);
}
else
{
ai_lib.aiSetPosture(self, POSTURE_LYING_DOWN);
}
}
else if (ai_lib.canLieDown(self))
{
ai_lib.aiSetPosture(self, POSTURE_LYING_DOWN);
}
}
else
{
ai_lib.doAction(self, "happy");
}
}
else if (emote.equals("bonk") || emote.equals("whap") || emote.equals("scold") || emote.equals("bad") || emote.equals("slap"))
{
ai_lib.doAction(self, "ashamed");
}
else if (emote.equals("pointat") || emote.equals("tap"))
{
ai_lib.doAction(self, ai_lib.ACTION_ALERT);
}
else if (emote.equals("beckon") || emote.equals("summon"))
{
if (rand(1, 2) == 1)
{
ai_lib.doAction(self, "confused");
}
else
{
beast_lib.doFollowCommand(self, master);
}
}
return SCRIPT_CONTINUE;
}
public int OnDeath(obj_id self, obj_id killer, obj_id corpseId) throws InterruptedException
{
obj_id master = getMaster(self);
CustomerServiceLog("Beasts", "*Beast DEATH: (" + self + ": " + getName(self) + ") has died. Their master was, (" + master + " sid:" + getPlayerObject(master));
return SCRIPT_CONTINUE;
}
public int receiveCreditForKill(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master))
{
String creatureName = params.getString("creatureName");
params.put("col_faction", dataTableGetString("datatables/mob/creatures.iff", creatureName, "col_faction"));
params.put("col_faction", dataTableGetInt("datatables/mob/creatures.iff", creatureName, "difficultyClass"));
messageTo(master, "receiveCreditForKill", params, 0.0f, false);
}
return SCRIPT_CONTINUE;
}
public int handleHealOverTimeTick(obj_id self, dictionary params) throws InterruptedException
{
float duration = params.getFloat("duration");
float tick = params.getFloat("tick");
int heal = params.getInt("heal");
int hot_id = params.getInt("id");
int isCombat = params.getInt("combat");
obj_id medic = params.getObjId("medic");
if (isDead(self))
{
if (buff.hasBuff(self, "healOverTime"))
{
buff.removeBuff(self, "healOverTime");
}
return SCRIPT_CONTINUE;
}
if (!utils.hasScriptVar(self, healing.VAR_PLAYER_HOT_ID))
{
if (buff.hasBuff(self, "healOverTime"))
{
buff.removeBuff(self, "healOverTime");
}
return SCRIPT_CONTINUE;
}
int player_id = utils.getIntScriptVar(self, healing.VAR_PLAYER_HOT_ID);
if (hot_id != player_id)
{
return SCRIPT_CONTINUE;
}
if (!isIncapacitated(self))
{
int delta = healing.healDamage(medic, self, HEALTH, heal);
if (isCombat == 1 && isIdValid(medic))
{
prose_package pp = new prose_package();
pp = prose.setStringId(pp, new string_id("healing", "heal_fly"));
pp = prose.setDI(pp, delta);
pp = prose.setTO(pp, "HEALTH");
showFlyTextPrivateProseWithFlags(self, self, pp, 2.0f, colors.SEAGREEN, FLY_TEXT_FLAG_IS_HEAL);
if (medic != self)
{
showFlyTextPrivateProseWithFlags(self, medic, pp, 2.0f, colors.SEAGREEN, FLY_TEXT_FLAG_IS_HEAL);
}
pp = prose.setStringId(pp, healing.SID_PERFORM_HEAL_DAMAGE_SUCCESS);
pp = prose.setTT(pp, medic);
pp = prose.setTO(pp, self);
pp = prose.setDI(pp, delta);
healing.sendMedicalSpam(medic, self, pp, true, true, true, COMBAT_RESULT_MEDICAL);
delta = (int)(delta * healing.HEAL_OVER_TIME_AGGRO_REDUCER);
healing._addMedicalHate(medic, self, delta);
}
}
duration -= tick;
if (duration <= 0.0f)
{
if (buff.hasBuff(self, "healOverTime"))
{
buff.removeBuff(self, "healOverTime");
}
return SCRIPT_CONTINUE;
}
dictionary d = new dictionary();
d.put("duration", duration);
d.put("tick", tick);
d.put("heal", heal);
d.put("id", hot_id);
d.put("combat", isCombat);
d.put("medic", medic);
if (tick >= 0)
{
messageTo(self, healing.MSG_HEAL_OVER_TIME, d, tick, false);
}
return SCRIPT_CONTINUE;
}
public int defensiveModePing(obj_id self, dictionary params) throws InterruptedException
{
obj_id master = getMaster(self);
if (isIdValid(master) && ai_lib.isInCombat(master))
{
obj_id[] masterAttackers = getHateList(master);
for (obj_id masterAttacker : masterAttackers) {
if (getHateTarget(masterAttacker) == master) {
utils.removeScriptVar(self, "petIgnoreAttacks");
startCombat(self, masterAttacker);
addHate(self, masterAttacker, 0.0f);
utils.setScriptVar(self, "ai.combat.target", masterAttacker);
break;
}
}
}
return SCRIPT_CONTINUE;
}
public int doBeastFlourish(obj_id self, dictionary params) throws InterruptedException
{
obj_id beast = (self);
int beastTrickNum = rand(1, 2);
doAnimationAction(beast, "trick_" + beastTrickNum);
return SCRIPT_CONTINUE;
}
}