Files
dsrc/sku.0/sys.server/compiled/game/script/library/create.java
T
AconiteX 8a35cd9085 Refractor approach to special creature DNA loot
The point of this change is to get rid of all of the unnecessary DNA loot roll chance scripts located at script.item.dna.* and instead replace it with a proper implementation. There are 2 new columns in creatures.tab (dnaChancePct and dnaItemName) which are parsed during createCreature() and loot events to properly roll for loot chance of the DNA and to add it to a creature's inventory container.
2021-07-13 02:29:08 -04:00

1236 lines
52 KiB
Java
Executable File

package script.library;
import script.*;
import script.ai.ai;
import java.util.Vector;
public class create extends script.base_script
{
public create()
{
}
public static final String CREATURE_TABLE = "datatables/mob/creatures.iff";
public static final String STAT_BALANCE_TABLE = "datatables/mob/stat_balance.iff";
public static final String VEHICLE_TABLE = "datatables/vehicle/vehicle_template.iff";
public static final String TEMPLATE_PREFIX = "object/mobile/";
public static final String CREATURE_NAME_FILE = "mob/creature_names";
public static final String NPC_CUSTOMIZATION_PREFIX = "datatables/npc_customization/";
public static final String DRESSED_NPC_TABLE = "datatables/npc_customization/dressed_species.iff";
public static final String DRESSED_NPC_TABLE_ROOT = "datatables/npc_customization/dressed_species_";
public static final String BIOLINK_SCRIPT = "item.armor.biolink_item_non_faction";
public static final float MELEE_SPEED_MOD = 1.25f;
public static final float MELEE_HP_MOD = 1.15f;
public static final String INITIALIZE_CREATURE_DO_NOT_SCALE_OBJVAR = "create_doNotRescale";
public static final String[] MINATTRIBNAMES =
{
"minHealth",
"minConstitution",
"minAction",
"minStamina",
"minMind",
"minWillpower"
};
public static final String[] MAXATTRIBNAMES =
{
"maxHealth",
"maxConstitution",
"maxAction",
"maxStamina",
"maxMind",
"maxWillpower"
};
private static final boolean AI_SCRIPTS_DISABLED = utils.checkConfigFlag("GameServer", "disableAI");
public static obj_id staticObject(String objectName, location spawnLocation) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.staticObject called with NULL objectName!");
return null;
}
obj_id creature = create.object(objectName, spawnLocation, false);
if (creature != null)
{
setCreatureStatic(creature, true);
setWantSawAttackTriggers(creature, false);
setInvulnerable(creature, true);
}
return creature;
}
public static obj_id object(String objectName, location spawnLocation) throws InterruptedException
{
return object(objectName, spawnLocation, -1);
}
public static obj_id object(String objectName, location spawnLocation, int level) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.object called with NULL objectName!");
return null;
}
return create.object(objectName, spawnLocation, level, true);
}
public static obj_id object(String objectName, location spawnLocation, boolean withAi) throws InterruptedException
{
return object(objectName, spawnLocation, -1, withAi);
}
public static obj_id object(String objectName, location spawnLocation, int level, boolean withAi) throws InterruptedException
{
return create.object(objectName, spawnLocation, level, withAi, false);
}
public static obj_id object(String objectName, location spawnLocation, boolean withAi, boolean isPet) throws InterruptedException
{
return object(objectName, spawnLocation, -1, withAi, isPet);
}
public static obj_id object(String objectName, location spawnLocation, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.object called with NULL objectName!");
return null;
}
if (objectName.endsWith(".iff"))
{
LOG("create", getName(getSelf()) + " creating: " + objectName + " at " + spawnLocation);
obj_id creature = createObject(objectName, spawnLocation);
if (isIdValid(creature))
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
return creature;
}
else
{
obj_id creature = createCreature(objectName, spawnLocation, level, withAi, isPet);
if (isIdValid(creature))
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
return creature;
}
}
public static obj_id object(String objectName, obj_id objContainer, boolean withAi, boolean isPet) throws InterruptedException
{
obj_id creature = object(objectName, objContainer, -1, withAi, isPet);
if (isIdValid(creature))
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
return creature;
}
public static obj_id object(String objectName, obj_id objContainer, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.object called with NULL objectName!");
return null;
}
if (objectName.endsWith(".iff"))
{
LOG("create", getName(getSelf()) + " creating: " + objectName + " at " + objContainer);
obj_id creature = createObject(objectName, objContainer, "");
if (isIdValid(creature))
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
return creature;
}
else
{
obj_id creature = createCreature(objectName, objContainer, level, withAi, isPet);
if (isIdValid(creature))
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
return creature;
}
}
public static obj_id object(String objectName, float xOffset, float zOffset) throws InterruptedException
{
return object(objectName, xOffset, zOffset, -1);
}
public static obj_id object(String objectName, float xOffset, float zOffset, int level) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.object called with NULL objectName!");
return null;
}
location spawnLoc = new location(getLocation(getSelf()));
spawnLoc.x += xOffset;
spawnLoc.z += zOffset;
return create.object(objectName, spawnLoc, level);
}
public static obj_id themeParkObject(String objectName, float xOffset, float zOffset, String destroyHandlerName, float destroyMessageDelay) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.themeParkObject called with NULL objectName!");
return null;
}
obj_id newObject = create.themeParkObject(objectName, xOffset, zOffset);
addDestroyMessage(newObject, destroyHandlerName, destroyMessageDelay, getSelf());
return newObject;
}
public static obj_id themeParkObject(String objectName, float xOffset, float zOffset) throws InterruptedException
{
if (objectName == null)
{
LOG("create", "create.themeParkObject called with NULL objectName!");
return null;
}
location spawnLoc = new location(getLocation(getSelf()));
spawnLoc.x += xOffset;
spawnLoc.z += zOffset;
obj_id newObject = create.object(objectName, spawnLoc);
setInvulnerable(newObject, true);
ai_lib.setDefaultCalmBehavior(newObject, ai_lib.BEHAVIOR_SENTINEL);
return newObject;
}
public static obj_id createNpc(String creatureName, String templateName, location spawnLocation) throws InterruptedException
{
return createNpc(creatureName, templateName, spawnLocation, -1);
}
public static obj_id createNpc(String creatureName, String templateName, location spawnLocation, int level) throws InterruptedException
{
if (creatureName == null)
{
LOG("create", "create.createNpc called with NULL creatureName!");
return null;
}
if (templateName == null)
{
LOG("create", "create.createNpc called with NULL templateName!");
return null;
}
dictionary creatureDict = utils.dataTableGetRow(CREATURE_TABLE, creatureName);
if (creatureDict == null)
{
return null;
}
if (!templateName.endsWith(".iff"))
{
String tableName = DRESSED_NPC_TABLE_ROOT + templateName.charAt(0) + ".iff";
if (dataTableHasColumn(tableName, templateName))
{
String[] templateList = dataTableGetStringColumnNoDefaults(tableName, templateName);
if (templateList.length < 1 || templateList == null)
{
LOG("create", templateName + " column in dressed_species is empty!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)];
}
else
{
String[] templateList = dataTableGetStringColumnNoDefaults(NPC_CUSTOMIZATION_PREFIX + templateName + ".iff", rand(0, 1));
if (templateList.length < 1 || templateList == null)
{
LOG("create", templateName + " datatable does not exist!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)];
}
}
return createCreature(creatureName, templateName, spawnLocation, creatureDict, level, true);
}
public static obj_id createNpc(String creatureName, String templateName, float xOffset, float zOffset) throws InterruptedException
{
return createNpc(creatureName, templateName, xOffset, zOffset, -1);
}
public static obj_id createNpc(String creatureName, String templateName, float xOffset, float zOffset, int level) throws InterruptedException
{
if (creatureName == null)
{
LOG("create", "create.createNpc called with NULL creatureName!");
return null;
}
if (templateName == null)
{
LOG("create", "create.createNpc called with NULL templateName!");
return null;
}
location spawnLoc = new location(getLocation(getSelf()));
spawnLoc.x += xOffset;
spawnLoc.z += zOffset;
return create.createNpc(creatureName, templateName, spawnLoc, level);
}
public static obj_id createCreature(String creatureName, location spawnLocation, boolean withAi) throws InterruptedException
{
return createCreature(creatureName, spawnLocation, -1, withAi);
}
public static obj_id createCreature(String creatureName, location spawnLocation, int level, boolean withAi) throws InterruptedException
{
return create.createCreature(creatureName, spawnLocation, level, withAi, false);
}
public static obj_id createCreature(String creatureName, location spawnLocation, boolean withAi, boolean isPet) throws InterruptedException
{
return createCreature(creatureName, spawnLocation, -1, withAi, isPet);
}
public static obj_id createCreature(String creatureName, location spawnLocation, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (creatureName == null)
{
LOG("create", "create.createCreature called with NULL creatureName!");
return null;
}
dictionary creatureDict = utils.dataTableGetRow(CREATURE_TABLE, creatureName);
if (creatureDict == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn invalid creatureType: " + creatureName);
return null;
}
String templateName = creatureDict.getString("template");
if (templateName.equals("") || templateName == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn invalid creatureType: " + creatureName + " - bad templateName?");
return null;
}
if (!templateName.endsWith(".iff"))
{
String tableName = DRESSED_NPC_TABLE_ROOT + templateName.charAt(0) + ".iff";
if (dataTableHasColumn(tableName, templateName))
{
String[] templateList = dataTableGetStringColumnNoDefaults(tableName, templateName);
if (templateList.length < 1 || templateList == null)
{
LOG("create", templateName + " column in dressed_species is empty!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)];
}
else
{
String[] templateList = dataTableGetStringColumnNoDefaults(NPC_CUSTOMIZATION_PREFIX + templateName + ".iff", rand(0, 1));
if (templateList == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn " + creatureName + " - bad templateName? " + templateName);
LOG("create", templateName + " does not exist!");
return null;
}
if (templateList.length == 0)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn " + creatureName + " - bad templateName? " + templateName);
LOG("create", templateName + " File was Empty!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)] + ".iff";
}
}
return createCreature(creatureName, templateName, spawnLocation, creatureDict, level, withAi, isPet);
}
public static obj_id createCreature(String creatureName, obj_id objContainer, boolean withAi, boolean isPet) throws InterruptedException
{
return createCreature(creatureName, objContainer, -1, withAi, isPet);
}
public static obj_id createCreature(String creatureName, obj_id objContainer, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (creatureName == null)
{
LOG("create", "create.createCreature called with NULL creatureName!");
return null;
}
dictionary creatureDict = utils.dataTableGetRow(CREATURE_TABLE, creatureName);
if (creatureDict == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn invalid creatureType: " + creatureName);
return null;
}
String templateName = creatureDict.getString("template");
if (templateName.equals("") || templateName == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn invalid creatureType: " + creatureName + " - bad templateName?");
return null;
}
if (!templateName.endsWith(".iff"))
{
String tableName = DRESSED_NPC_TABLE_ROOT + templateName.charAt(0) + ".iff";
if (dataTableHasColumn(tableName, templateName))
{
String[] templateList = dataTableGetStringColumnNoDefaults(tableName, templateName);
if (templateList.length < 1 || templateList == null)
{
LOG("create", templateName + " column in dressed_species is empty!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)];
}
else
{
String[] templateList = dataTableGetStringColumnNoDefaults(NPC_CUSTOMIZATION_PREFIX + templateName + ".iff", rand(0, 1));
if (templateList == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn " + creatureName + " - bad templateName? " + templateName);
LOG("create", templateName + " does not exist!");
return null;
}
if (templateList.length == 0)
{
debugServerConsoleMsg(null, "WARNING: Unable to spawn " + creatureName + " - bad templateName? " + templateName);
LOG("create", templateName + " File was Empty!");
return null;
}
templateName = templateList[rand(0, templateList.length - 1)] + ".iff";
}
}
return createCreature(creatureName, templateName, objContainer, creatureDict, level, withAi, isPet);
}
public static obj_id createCreature(String creatureName, String templateName, location spawnLocation, dictionary creatureDict, boolean withAi) throws InterruptedException
{
return createCreature(creatureName, templateName, spawnLocation, creatureDict, -1, withAi);
}
public static obj_id createCreature(String creatureName, String templateName, location spawnLocation, dictionary creatureDict, int level, boolean withAi) throws InterruptedException
{
return createCreature(creatureName, templateName, spawnLocation, creatureDict, level, withAi, false);
}
public static obj_id createCreature(String creatureName, String templateName, location spawnLocation, dictionary creatureDict, boolean withAi, boolean isPet) throws InterruptedException
{
return createCreature(creatureName, templateName, spawnLocation, creatureDict, -1, withAi, isPet);
}
public static obj_id createCreature(String creatureName, String templateName, location spawnLocation, dictionary creatureDict, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (templateName.equals("") || templateName == null)
{
LOG("create", creatureName + " could not be made because templateName is null");
return null;
}
if (creatureName.equals("") || creatureName == null)
{
LOG("create", "creatureName is null - can't spawn whatever this was supposed to be");
return null;
}
templateName = TEMPLATE_PREFIX + templateName;
LOG("create", getName(getSelf()) + " creating: " + creatureName + " at " + spawnLocation);
obj_id creature = createObject(templateName, spawnLocation);
if (!isIdValid(creature))
{
return null;
}
else
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
if (isPet)
{
utils.setScriptVar(creature, "petBeingInitialized", true);
}
String finalCreatureName = getStringObjVar(creature, "ai.creatureBaseName");
if (finalCreatureName == null || finalCreatureName.equals(""))
{
finalCreatureName = creatureName;
}
randomlyNameCreature(creature, finalCreatureName);
initializeCreature(creature, creatureName, creatureDict, level);
attachCreatureScripts(creature, creatureDict.getString("scripts"), withAi);
return creature;
}
public static obj_id createCreature(String creatureName, String templateName, obj_id objContainer, dictionary creatureDict, boolean withAi, boolean isPet) throws InterruptedException
{
return createCreature(creatureName, templateName, objContainer, creatureDict, -1, withAi, isPet);
}
public static obj_id createCreature(String creatureName, String templateName, obj_id objContainer, dictionary creatureDict, int level, boolean withAi, boolean isPet) throws InterruptedException
{
if (templateName.equals("") || templateName == null)
{
LOG("create", creatureName + " could not be made because templateName is null");
return null;
}
if (creatureName.equals("") || creatureName == null)
{
LOG("create", "creatureName is null - can't spawn whatever this was supposed to be");
return null;
}
templateName = TEMPLATE_PREFIX + templateName;
LOG("create", getName(getSelf()) + " creating: " + creatureName + " at " + objContainer);
obj_id creature = createObject(templateName, objContainer, "");
if (!isIdValid(creature))
{
return null;
}
else
{
utils.setScriptVar(creature, "spawnedBy", getSelf());
}
if (isPet)
{
utils.setScriptVar(creature, "petBeingInitialized", true);
}
String finalCreatureName = getStringObjVar(creature, "ai.creatureBaseName");
if (finalCreatureName == null || finalCreatureName.equals(""))
{
finalCreatureName = creatureName;
}
randomlyNameCreature(creature, finalCreatureName);
initializeCreature(creature, creatureName, creatureDict, level);
attachCreatureScripts(creature, creatureDict.getString("scripts"), withAi);
return creature;
}
public static void initializeCreature(obj_id creature, String creatureName, dictionary creatureDict) throws InterruptedException
{
initializeCreature(creature, creatureName, creatureDict, -1);
}
public static void initializeCreature(obj_id creature, String creatureName, dictionary creatureDict, int level) throws InterruptedException
{
LOGC(aiLoggingEnabled(creature), "debug_ai", ("########## create::initializeCreature() BEGIN ai(" + creature + ") creatureName(" + creatureName + ") ##########"));
setCreatureName(creature, creatureName);
float minScale = creatureDict.getFloat("minScale");
float maxScale = creatureDict.getFloat("maxScale");
float baseScale = getScale(creature);
if (baseScale != 1.0f)
{
utils.setScriptVar(creature, "ai.baseScale", baseScale);
}
if (!hasObjVar(creature, "storytellerid") && !hasObjVar(creature, INITIALIZE_CREATURE_DO_NOT_SCALE_OBJVAR))
{
float newScale = baseScale * rand(minScale, maxScale);
setScale(creature, newScale);
setYaw(creature, rand(0.0f, 360.0f));
}
setObjVar(creature, "creature_type", creatureName);
setObjVar(creature, "socialGroup", creatureDict.getString("socialGroup"));
int huevar = creatureDict.getInt("hue");
if (huevar != 0)
{
int highhuevar = (huevar * 8) - 1;
int lowhuevar = highhuevar - 7;
huevar = rand(lowhuevar, highhuevar);
ranged_int_custom_var[] c = hue.getPalcolorVars(creature);
if (c != null)
{
for (ranged_int_custom_var ranged_int_custom_var : c) {
ranged_int_custom_var.setValue(huevar);
}
}
}
int baseLevel = creatureDict.getInt("BaseLevel");
int dmgLevel = baseLevel + creatureDict.getInt("Damagelevelmodifier");
int statLevel = baseLevel + creatureDict.getInt("StatLevelModifier");
int toHitLevel = baseLevel + creatureDict.getInt("ToHitLevelModifier");
int armorLevel = baseLevel + creatureDict.getInt("ArmorLevelModifier");
if (dmgLevel <= 0)
{
dmgLevel = 1;
}
if (statLevel <= 0)
{
statLevel = 1;
}
if (toHitLevel <= 0)
{
toHitLevel = 1;
}
if (armorLevel <= 0)
{
armorLevel = 1;
}
if (level > 0)
{
dmgLevel = level;
statLevel = level;
toHitLevel = level;
armorLevel = level;
}
else
{
level = calcCreatureLevel(statLevel, dmgLevel, toHitLevel, armorLevel);
}
setObjVar(creature, "intCombatDifficulty", level);
setLevel(creature, level);
int stealType = creatureDict.getInt("stealingFlags");
utils.setScriptVar(creature, stealth.STEAL_TYPE, stealType);
int difficultyClass = creatureDict.getInt("difficultyClass");
if (difficultyClass < 0)
{
difficultyClass = 0;
}
setObjVar(creature, "difficultyClass", difficultyClass);
String diffClassName = "";
if (difficultyClass == 1)
{
diffClassName = "Elite_";
}
if (difficultyClass == 2)
{
diffClassName = "Boss_";
}
float damagePerSecond = dataTableGetFloat(STAT_BALANCE_TABLE, dmgLevel - 1, diffClassName + "damagePerSecond");
int toHitChance = dataTableGetInt(STAT_BALANCE_TABLE, toHitLevel - 1, diffClassName + "ToHit");
int defenseValue = dataTableGetInt(STAT_BALANCE_TABLE, toHitLevel - 1, diffClassName + "Def");
boolean hasRanged = false;
obj_id creatureWeapon = getCurrentWeapon(creature);
float primarySpeed = creatureDict.getFloat("primary_weapon_speed");
float secondarySpeed = creatureDict.getFloat("secondary_weapon_speed");
int priMinDamage = Math.round((damagePerSecond * primarySpeed) * 0.5f);
int priMaxDamage = Math.round((damagePerSecond * primarySpeed) * 1.5f);
int secMinDamage = Math.round((damagePerSecond * secondarySpeed) * 0.5f);
int secMaxDamage = Math.round((damagePerSecond * secondarySpeed) * 1.5f);
if (isIdValid(creatureWeapon))
{
setWeaponAttackSpeed(creatureWeapon, primarySpeed);
setWeaponMaxDamage(creatureWeapon, priMaxDamage);
setWeaponMinDamage(creatureWeapon, priMinDamage);
weapons.setWeaponData(creatureWeapon);
utils.setScriptVar(creatureWeapon, "isCreatureWeapon", 1);
setObjVar(creatureWeapon, "isCreatureWeapon", 1);
}
obj_id defaultWeapon = getDefaultWeapon(creature);
if (isIdValid(defaultWeapon))
{
setWeaponAttackSpeed(defaultWeapon, primarySpeed);
setWeaponMaxDamage(defaultWeapon, secMaxDamage);
setWeaponMinDamage(defaultWeapon, secMinDamage);
weapons.setWeaponData(defaultWeapon);
utils.setScriptVar(defaultWeapon, "isCreatureWeapon", 1);
setObjVar(defaultWeapon, "isCreatureWeapon", 1);
}
{
if (aiHasPrimaryWeapon(creature))
{
final obj_id primaryWeapon = aiGetPrimaryWeapon(creature);
dictionary primDat = weapons.getWeaponDat(primaryWeapon);
if (primDat != null)
{
weapons.setWeaponAttributes(primaryWeapon, primDat, 1.0f);
}
setWeaponAttackSpeed(primaryWeapon, primarySpeed);
setWeaponMaxDamage(primaryWeapon, priMaxDamage);
setWeaponMinDamage(primaryWeapon, priMinDamage);
weapons.setWeaponData(primaryWeapon);
hasRanged = hasRanged || combat.isRangedWeapon(primaryWeapon);
if (hasScript(primaryWeapon, BIOLINK_SCRIPT))
{
cleanOffBioLink(primaryWeapon);
}
utils.setScriptVar(primaryWeapon, "isCreatureWeapon", 1);
setObjVar(primaryWeapon, "isCreatureWeapon", 1);
}
}
{
if (aiHasSecondaryWeapon(creature))
{
final obj_id secondaryWeapon = aiGetSecondaryWeapon(creature);
dictionary secDat = weapons.getWeaponDat(secondaryWeapon);
if (secDat != null)
{
weapons.setWeaponAttributes(secondaryWeapon, secDat, 1.0f);
}
setWeaponAttackSpeed(secondaryWeapon, secondarySpeed);
setWeaponMaxDamage(secondaryWeapon, secMaxDamage);
setWeaponMinDamage(secondaryWeapon, secMinDamage);
weapons.setWeaponData(secondaryWeapon);
hasRanged = hasRanged || combat.isRangedWeapon(secondaryWeapon);
if (hasScript(secondaryWeapon, BIOLINK_SCRIPT))
{
cleanOffBioLink(secondaryWeapon);
}
utils.setScriptVar(secondaryWeapon, "isCreatureWeapon", 1);
setObjVar(secondaryWeapon, "isCreatureWeapon", 1);
}
}
float speedMod = 1;
float hpMod = 1;
if (hasRanged)
{
speedMod = MELEE_SPEED_MOD;
hpMod = MELEE_HP_MOD;
}
int avgAttribHealth = dataTableGetInt(STAT_BALANCE_TABLE, statLevel - 1, diffClassName + "HP");
int minAttribHealth = minAttribHealth = (int)(avgAttribHealth * 0.9f);
int maxAttribHealth = maxAttribHealth = (int)(avgAttribHealth * 1.1f);
float newAttribValueHealth = rand(minAttribHealth, maxAttribHealth);
newAttribValueHealth *= hpMod;
setMaxAttrib(creature, HEALTH, (int)newAttribValueHealth);
setAttrib(creature, HEALTH, (int)newAttribValueHealth);
int avgAttribAction = dataTableGetInt(STAT_BALANCE_TABLE, statLevel - 1, diffClassName + "Action");
int minAttribAction = minAttribAction = (int)(avgAttribAction * 0.9f);
int maxAttribAction = maxAttribAction = (int)(avgAttribAction * 1.1f);
int newAttribValueAction = rand(minAttribAction, maxAttribAction);
setMaxAttrib(creature, ACTION, newAttribValueAction);
setAttrib(creature, ACTION, newAttribValueAction);
setMaxAttrib(creature, MIND, 1000);
setAttrib(creature, MIND, 1000);
int healthRegen = dataTableGetInt(STAT_BALANCE_TABLE, statLevel - 1, "HealthRegen");
int actionRegen = dataTableGetInt(STAT_BALANCE_TABLE, statLevel - 1, "ActionRegen");
int mindRegen = dataTableGetInt(STAT_BALANCE_TABLE, statLevel - 1, "MindRegen");
setRegenRate(creature, CONSTITUTION, healthRegen);
setRegenRate(creature, STAMINA, healthRegen);
setRegenRate(creature, WILLPOWER, healthRegen);
float normalRegen = dataTableGetFloat(STAT_BALANCE_TABLE, statLevel - 1, diffClassName + "Regen");
float combatRegen = dataTableGetFloat(STAT_BALANCE_TABLE, statLevel - 1, diffClassName + "CombatRegen");
int xpValue = xp.getLevelBasedXP(level);
setObjVar(creature, "combat.intCombatXP", xpValue);
{
float runSpeed = ai_lib.AI_MAX_MOVEMENT_SPEED * aiGetMovementSpeedPercent(creature);
runSpeed *= speedMod;
float walkSpeed = 2.0f;
setBaseRunSpeed(creature, runSpeed);
setBaseWalkSpeed(creature, walkSpeed);
{
if (getBaseWalkSpeed(creature) > runSpeed)
{
setBaseWalkSpeed(creature, runSpeed);
}
}
LOGC(aiLoggingEnabled(creature), "debug_ai", ("create::initializeCreature() ai(" + creature + ") runSpeed(" + runSpeed + ")"));
}
applySkillStatisticModifiers(creature, toHitChance, defenseValue);
applyCreatureImmunities(creature, creatureDict);
setCreatureObjVars(creature, creatureDict.getString("objvars"));
int pvpOnly = creatureDict.getInt("isSpecialForces");
String faction = creatureDict.getString("pvpFaction");
if ((faction != null) && (!faction.equals("")))
{
factions.setFaction(creature, faction, pvpOnly);
}
int invulnerable = creatureDict.getInt("invulnerable");
if (invulnerable != 0)
{
setInvulnerable(creature, true);
}
String diction = creatureDict.getString("diction");
if (!diction.equals("none"))
{
setObjVar(creature, "ai.diction", diction);
}
int niche = creatureDict.getInt("niche");
if (getTopMostContainer(creature) != creature)
{
ai_lib.setDefaultCalmBehavior(creature, ai_lib.BEHAVIOR_SENTINEL);
}
randomlyNameCreature(creature, creatureName);
setAttributeAttained(creature, attrib.ALL);
switch (niche)
{
case NICHE_HERBIVORE:
setAttributeAttained(creature, attrib.HERBIVORE);
setAttributeInterested(creature, attrib.CARNIVORE);
break;
case NICHE_CARNIVORE:
case NICHE_PREDATOR:
setAttributeAttained(creature, attrib.CARNIVORE);
setAttributeInterested(creature, attrib.HERBIVORE);
setAttributeInterested(creature, attrib.NPC);
break;
case NICHE_NPC:
setAttributeAttained(creature, attrib.NPC);
setAttributeInterested(creature, attrib.CARNIVORE);
setUpFactionalEnemyAttribs(creature, faction);
break;
case NICHE_ANDROID:
setAttributeAttained(creature, attrib.NPC);
setAttributeInterested(creature, attrib.CARNIVORE);
setUpFactionalEnemyAttribs(creature, faction);
break;
}
String strLootTable = creatureDict.getString("lootTable");
int intRolls = creatureDict.getInt("intLootRolls");
int intPercentage = creatureDict.getInt("intRollPercent");
if (!strLootTable.equals(""))
{
LOG("npe", "table is " + strLootTable);
int intItems = 0;
for (int intI = 0; intI < intRolls; intI++)
{
int intRand = rand(1, 99);
LOG("npe", "roll is " + intRand + " and +% is " + intPercentage);
if (intRand < intPercentage)
{
intItems++;
}
}
LOG("npe", "items is " + intItems);
setObjVar(creature, "loot.lootTable", strLootTable);
setObjVar(creature, "loot.numItems", intItems);
}
final float dnaLootPercentageChance = creatureDict.getFloat("dnaChancePct");
final String dnaLootItemName = creatureDict.getString("dnaItemName");
if(dnaLootPercentageChance > 0 && dnaLootItemName != null && static_item.isStaticItem(dnaLootItemName))
{
setObjVar(creature, loot.OBJVAR_DNA_LOOT_CHANCE, dnaLootPercentageChance);
setObjVar(creature, loot.OBJVAR_DNA_LOOT_ITEM_NAME, dnaLootItemName);
}
if (!initializeArmor(creature, creatureDict, dataTableGetInt(STAT_BALANCE_TABLE, armorLevel - 1, diffClassName + "Armor")))
{
LOG("create", "Unable to initialize armor on " + creatureName + "(" + creature + ")");
}
int stringCheck = creatureName.indexOf("recruiter");
if (stringCheck > -1)
{
String pvpFaction = creatureDict.getString("pvpFaction");
setFactionRecruiter(creature, pvpFaction);
}
if (hasObjVar(creature, "detect_hidden"))
{
int detectInt = getIntObjVar(creature, "detect_hidden");
if (detectInt > 0)
{
applySkillStatisticModifier(creature, "detect_hidden", detectInt);
}
}
LOGC(aiLoggingEnabled(creature), "debug_ai", ("########## create::initializeCreature() END ai(" + creature + ") creatureName(" + creatureName + ") ##########"));
}
public static int calcCreatureLevel(String creatureName) throws InterruptedException
{
dictionary creatureDict = utils.dataTableGetRow(CREATURE_TABLE, creatureName);
if (creatureDict == null)
{
debugServerConsoleMsg(null, "WARNING: Unable to find invalid creatureType: " + creatureName);
return -1;
}
return calcCreatureLevel(creatureDict);
}
public static int calcCreatureLevel(dictionary creatureDict) throws InterruptedException
{
int baseLevel = creatureDict.getInt("BaseLevel");
int dmgLevel = baseLevel + creatureDict.getInt("Damagelevelmodifier");
int statLevel = baseLevel + creatureDict.getInt("StatLevelModifier");
int toHitLevel = baseLevel + creatureDict.getInt("ToHitLevelModifier");
int armorLevel = baseLevel + creatureDict.getInt("ArmorLevelModifier");
if (statLevel <= 0)
{
statLevel = 1;
}
if (dmgLevel <= 0)
{
dmgLevel = 1;
}
if (toHitLevel <= 0)
{
toHitLevel = 1;
}
if (armorLevel <= 0)
{
armorLevel = 1;
}
return calcCreatureLevel(statLevel, dmgLevel, toHitLevel, armorLevel);
}
public static int calcCreatureLevel(int statLevel, int dmgLevel, int toHitLevel, int armorLevel) throws InterruptedException
{
int level = 0;
{
level = (int)(((statLevel * 6) + (dmgLevel * 6) + (toHitLevel * 2) + (armorLevel * 4)) / 18.0f);
}
return level;
}
public static void attachCreatureScripts(obj_id creature, String scriptList, boolean withAi) throws InterruptedException
{
if (AI_SCRIPTS_DISABLED)
{
return;
}
if (withAi)
{
attachScript(creature, "ai.ai");
attachCombatScripts(creature);
attachScript(creature, "systems.skills.stealth.player_stealth");
}
if (scriptList == null || scriptList.equals(""))
{
return;
}
String[] scriptArray = split(scriptList, ',');
for (String s : scriptArray) {
attachScript(creature, s);
}
}
public static boolean initializeArmor(obj_id creature, dictionary creatureDict) throws InterruptedException
{
int armorLevel = creatureDict.getInt("BaseLevel") + creatureDict.getInt("ArmorLevelModifier");
int difficultyClass = creatureDict.getInt("difficultyClass");
if (difficultyClass < 0)
{
difficultyClass = 0;
}
String diffClassName = "";
if (difficultyClass == 1)
{
diffClassName = "Elite_";
}
if (difficultyClass == 2)
{
diffClassName = "Boss_";
}
int armorRating = dataTableGetInt(STAT_BALANCE_TABLE, armorLevel - 1, diffClassName + "Armor");
return initializeArmor(creature, creatureDict, armorRating);
}
public static boolean initializeArmor(obj_id creature, dictionary creatureDict, int armorRating) throws InterruptedException
{
int[] armorData = new int[10];
armorData[0] = 0;
armorData[1] = armorRating;
armorData[2] = creatureDict.getInt("armorKinetic");
armorData[3] = creatureDict.getInt("armorEnergy");
armorData[4] = creatureDict.getInt("armorBlast");
armorData[5] = creatureDict.getInt("armorHeat");
armorData[6] = creatureDict.getInt("armorCold");
armorData[7] = creatureDict.getInt("armorElectric");
armorData[8] = creatureDict.getInt("armorAcid");
armorData[9] = creatureDict.getInt("armorStun");
return initializeArmor(creature, armorData);
}
public static boolean initializeArmor(obj_id creature, int[] armorData) throws InterruptedException
{
int armorRating = armorData[0];
int armorEffectiveness = armorData[1];
int armorKinetic = armorData[2];
int armorEnergy = armorData[3];
int armorBlast = armorData[4];
int armorHeat = armorData[5];
int armorCold = armorData[6];
int armorElectric = armorData[7];
int armorAcid = armorData[8];
int armorStun = armorData[9];
boolean success = true;
int vulnerability = DAMAGE_RESTRAINT;
armor.removeAllArmorData(creature);
String armorCategoryObjVar = armor.OBJVAR_ARMOR_BASE + "." + armor.OBJVAR_ARMOR_CATEGORY;
setObjVar(creature, armorCategoryObjVar, AC_battle);
String armorLevelObjVar = armor.OBJVAR_ARMOR_BASE + "." + armor.OBJVAR_ARMOR_LEVEL;
setObjVar(creature, armorLevelObjVar, AL_standard);
String genProtectionObjVar = armor.OBJVAR_ARMOR_BASE + "." + armor.OBJVAR_GENERAL_PROTECTION;
setObjVar(creature, genProtectionObjVar, (float)armorEffectiveness);
utils.setScriptVar(creature, armor.SCRIPTVAR_CACHED_GENERAL_PROTECTION, armorEffectiveness);
return success;
}
public static void setCreatureObjVars(obj_id creature, String objVarList) throws InterruptedException
{
utils.setObjVarsList(creature, objVarList);
}
public static String getLairDifficulty(int intMinDifficulty, int intMaxDifficulty, int intPlayerDifficulty) throws InterruptedException
{
final String[] LAIR_DIFFICULTIES =
{
"veryEasy",
"easy",
"medium",
"hard",
"veryHard"
};
int intDifference = intMaxDifficulty - intMinDifficulty;
intPlayerDifficulty = intPlayerDifficulty - intMinDifficulty;
if (intDifference == 0)
{
intDifference = 1;
}
float fltPercent = (intPlayerDifficulty / intDifference);
fltPercent = fltPercent * 100;
int intIndex = (int)(fltPercent / 20);
intIndex = intIndex - 1;
if (intIndex < 0)
{
intIndex = 0;
}
if (intIndex >= LAIR_DIFFICULTIES.length)
{
intIndex = LAIR_DIFFICULTIES.length - 1;
}
return LAIR_DIFFICULTIES[intIndex];
}
public static void grantAllAbilities(obj_id npc) throws InterruptedException
{
return;
}
public static void attachCombatScripts(obj_id npc) throws InterruptedException
{
if (!hasScript(npc, "ai.creature_combat"))
{
attachScript(npc, "ai.creature_combat");
}
if (!hasScript(npc, "systems.combat.combat_actions"))
{
attachScript(npc, "systems.combat.combat_actions");
}
}
public static void applySkillStatisticModifiers(obj_id creature, int toHitChance, int defenseValue) throws InterruptedException
{
applySkillStatisticModifier(creature, "rifle_accuracy", toHitChance);
applySkillStatisticModifier(creature, "toHitChance", toHitChance);
applySkillStatisticModifier(creature, "carbine_accuracy", toHitChance);
applySkillStatisticModifier(creature, "pistol_accuracy", toHitChance);
applySkillStatisticModifier(creature, "heavyweapon_accuracy", toHitChance);
applySkillStatisticModifier(creature, "onehandmelee_accuracy", toHitChance);
applySkillStatisticModifier(creature, "twohandmelee_accuracy", toHitChance);
applySkillStatisticModifier(creature, "unarmed_accuracy", toHitChance);
applySkillStatisticModifier(creature, "polearm_accuracy", toHitChance);
applySkillStatisticModifier(creature, "thrown_accuracy", toHitChance);
applySkillStatisticModifier(creature, "onehandlightsaber_accuracy", toHitChance);
applySkillStatisticModifier(creature, "twohandlightsaber_accuracy", toHitChance);
applySkillStatisticModifier(creature, "polearmlightsaber_accuracy", toHitChance);
applySkillStatisticModifier(creature, "force_accuracy", toHitChance);
applySkillStatisticModifier(creature, "ranged_defense", defenseValue);
applySkillStatisticModifier(creature, "melee_defense", defenseValue);
}
public static void applyCreatureImmunities(obj_id creature, dictionary creatureDict) throws InterruptedException
{
int rootImmune = creatureDict.getInt("rootImmune");
if (rootImmune > 0)
{
applySkillStatisticModifier(creature, "movement_resist_root", rootImmune);
}
int snareImmune = creatureDict.getInt("snareImmune");
if (snareImmune > 0)
{
applySkillStatisticModifier(creature, "movement_resist_snare", snareImmune);
}
int stunImmune = creatureDict.getInt("stunImmune");
if (stunImmune > 0)
{
applySkillStatisticModifier(creature, "movement_resist_stun", stunImmune);
}
int mezImmune = creatureDict.getInt("mezImmune");
if (mezImmune > 0)
{
applySkillStatisticModifier(creature, "movement_resist_mez", mezImmune);
}
int armorBreakImmune = creatureDict.getInt("canNotPunish");
if (armorBreakImmune > 0)
{
utils.setScriptVar(creature, "combat.immune.no_punish", 1);
}
int tauntImmune = creatureDict.getInt("tauntImmune");
if (tauntImmune > 0)
{
utils.setScriptVar(creature, "combat.immune.taunt", 1);
}
int ignorePlayer = creatureDict.getInt("ignorePlayer");
if (ignorePlayer > 0)
{
utils.setScriptVar(creature, "combat.immune.taunt", 1);
factions.setIgnorePlayer(creature);
}
}
public static void addDestroyMessage(obj_id creature, String handlerName, float delay, obj_id recipient) throws InterruptedException
{
if (!isIdValid(creature))
{
return;
}
if (!hasScript(creature, "object.destroy_message"))
{
attachScript(creature, "object.destroy_message");
}
Vector destroyMessageNames = new Vector();
destroyMessageNames.setSize(0);
Vector destroyMessageDelays = new Vector();
destroyMessageDelays.setSize(0);
Vector destroyMessageRecipients = new Vector();
destroyMessageRecipients.setSize(0);
if (hasObjVar(creature, "destroyMessageList"))
{
destroyMessageNames = getResizeableStringArrayObjVar(creature, "destroyMessageList.handlerNames");
destroyMessageDelays = getResizeableFloatArrayObjVar(creature, "destroyMessageList.delays");
destroyMessageRecipients = getResizeableObjIdArrayObjVar(creature, "destroyMessageList.recipients");
}
destroyMessageNames = utils.addElement(destroyMessageNames, handlerName);
destroyMessageDelays = utils.addElement(destroyMessageDelays, delay);
destroyMessageRecipients = utils.addElement(destroyMessageRecipients, recipient);
if (((destroyMessageNames != null) && (destroyMessageNames.size() > 0)) && ((destroyMessageDelays != null) && (destroyMessageDelays.size() > 0)) && ((destroyMessageRecipients != null) && (destroyMessageRecipients.size() > 0)))
{
setObjVar(creature, "destroyMessageList.handlerNames", destroyMessageNames);
setObjVar(creature, "destroyMessageList.delays", destroyMessageDelays);
setObjVar(creature, "destroyMessageList.recipients", destroyMessageRecipients);
}
}
public static void randomlyNameCreature(obj_id npc, String creatureName) throws InterruptedException
{
String templateName = getTemplateName(npc);
if (templateName.contains("stormtrooper"))
{
nameStormTrooper(npc);
}
if (templateName.contains("swamp_trooper"))
{
nameSwampTrooper(npc);
}
if (templateName.contains("scout_trooper"))
{
nameScoutTrooper(npc);
}
if (templateName.contains("tie_fighter"))
{
nameImperialPilot(npc);
}
if (templateName.contains("dark_trooper"))
{
nameDarkTrooper(npc);
}
String oldName = getAssignedName(npc);
string_id nameId = new string_id(CREATURE_NAME_FILE, creatureName);
String actualName = getString(nameId);
if (actualName == null || actualName.equals(""))
{
setTitle(npc, creatureName);
return;
}
setName(npc, "");
setName(npc, nameId);
}
public static void setTitle(obj_id npc, String creatureName) throws InterruptedException
{
string_id nameId = new string_id(CREATURE_NAME_FILE, creatureName);
if (nameId == null)
{
return;
}
String newName = getString(nameId);
if (newName == null || newName.equals(""))
{
return;
}
String oldName = getAssignedName(npc);
String oldNameId = getString(getNameStringId(npc));
if (oldName.equals(oldNameId))
{
setName(npc, "");
setName(npc, nameId);
}
else if (oldName == null || oldName.equals(""))
{
setName(npc, "");
setName(npc, nameId);
}
else
{
setName(npc, oldName + " (" + getString(nameId) + ")");
}
}
public static void nameStormTrooper(obj_id npc) throws InterruptedException
{
int designation = rand(1, 5);
String StName = "TK-";
switch (designation)
{
case 1:
StName = "TK-";
break;
case 2:
StName = "GK-";
break;
case 3:
StName = "RK-";
break;
case 4:
StName = "LK-";
break;
case 5:
StName = "VK-";
break;
}
setName(npc, StName + rand(1, 820));
}
public static void nameImperialPilot(obj_id npc) throws InterruptedException
{
setName(npc, "DS-" + rand(1, 820));
}
public static void nameScoutTrooper(obj_id npc) throws InterruptedException
{
int designation = rand(1, 5);
String StName = "TK-";
switch (designation)
{
case 1:
StName = "SX-";
break;
case 2:
StName = "GX-";
break;
case 3:
StName = "VX-";
break;
case 4:
StName = "CX-";
break;
case 5:
StName = "NX-";
break;
}
setName(npc, StName + rand(1, 820));
}
public static void nameDarkTrooper(obj_id npc) throws InterruptedException
{
int designation = rand(1, 5);
String StName = "DLX-";
switch (designation)
{
case 1:
StName = "JLB-";
break;
case 2:
StName = "RAR-";
break;
case 3:
StName = "KNP-";
break;
case 4:
StName = "BCP-";
break;
case 5:
StName = "RTZ-";
break;
}
setName(npc, StName + rand(10, 99));
}
public static void nameSwampTrooper(obj_id npc) throws InterruptedException
{
int designation = rand(1, 5);
String StName = "TK-";
switch (designation)
{
case 1:
StName = "GL-";
break;
case 2:
StName = "TL-";
break;
case 3:
StName = "RL-";
break;
case 4:
StName = "NL-";
break;
case 5:
StName = "CL-";
break;
}
setName(npc, StName + rand(1, 820));
}
public static boolean setFactionRecruiter(obj_id npc, String faction) throws InterruptedException
{
if (npc == null || npc == obj_id.NULL_ID)
{
return false;
}
if (faction == null)
{
return false;
}
setObjVar(npc, "faction_recruiter.faction", faction);
attachScript(npc, "npc.faction_recruiter.faction_recruiter");
return true;
}
public static void setUpFactionalEnemyAttribs(obj_id npc, String pvpFaction) throws InterruptedException
{
if (pvpFaction == null)
{
return;
}
if (pvpFaction.equals(""))
{
return;
}
setAttributeAttained(npc, attrib.NPC);
setAttributeInterested(npc, attrib.NPC);
}
public static void cleanOffBioLink(obj_id weapon) throws InterruptedException
{
detachScript(weapon, BIOLINK_SCRIPT);
removeObjVar(weapon, "biolink");
return;
}
}