Files
dsrc/sku.0/sys.server/compiled/game/script/library/create.scriptlib
T
2013-09-10 23:17:15 -07:00

1633 lines
50 KiB
Plaintext

include library.utils;
include library.hue;
include library.ai_lib;
include ai.ai_combat;
include library.factions;
include library.dressup;
include library.attrib;
include library.weapons;
include library.stealth;
const string CREATURE_TABLE = "datatables/mob/creatures.iff";
const string STAT_BALANCE_TABLE = "datatables/mob/stat_balance.iff";
const string VEHICLE_TABLE = "datatables/vehicle/vehicle_template.iff";
const string TEMPLATE_PREFIX = "object/mobile/";
const string CREATURE_NAME_FILE = "mob/creature_names";
const string NPC_CUSTOMIZATION_PREFIX = "datatables/npc_customization/";
const string DRESSED_NPC_TABLE = "datatables/npc_customization/dressed_species.iff";
const string DRESSED_NPC_TABLE_ROOT = "datatables/npc_customization/dressed_species_";
const string BIOLINK_SCRIPT = "item.armor.biolink_item_non_faction";
const float MELEE_SPEED_MOD = 1.25f; // melee mobs gets X% movement speed bonus
const float MELEE_HP_MOD = 1.15f; // melee mobs get X% hitpoint bonus
const string INITIALIZE_CREATURE_DO_NOT_SCALE_OBJVAR = "create_doNotRescale";
//const string NPC_DATATABLE = "datatables/npc_customization/npc.iff";
const string[] MINATTRIBNAMES = {
"minHealth",
"minConstitution",
"minAction",
"minStamina",
"minMind",
"minWillpower"
};
const string[] MAXATTRIBNAMES = {
"maxHealth",
"maxConstitution",
"maxAction",
"maxStamina",
"maxMind",
"maxWillpower"
};
/**
* Creates a creature without attaching AI or combat scripts to the creature
* and sets the creature Static:
*
* @params creatureName the name of the creature to create
* @params spawnLocation the location at which to create the creature
*
* @returns the obj_id of the creature created
*/
obj_id staticObject( string objectName, location spawnLocation )
{
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;
}
/* -----------------12/5/2002 2:49PM-----------------
* creates an object from template, creature datatable or npc datatable
*
* @param objectName the templatename, creature or NPC type to create
* @param spawnLocation the location to create the object
*
* @returns the obj_id of the created object
* --------------------------------------------------*/
obj_id object( string objectName, location spawnLocation )
{
return object( objectName, spawnLocation, -1 );
}
obj_id object( string objectName, location spawnLocation, int level )
{
if ( objectName == null )
{
LOG("create", "create.object called with NULL objectName!" );
return null;
}
return create.object( objectName, spawnLocation, level, true);
}
obj_id object( string objectName, location spawnLocation, boolean withAi )
{
return object( objectName, spawnLocation, -1, withAi );
}
obj_id object( string objectName, location spawnLocation, int level, boolean withAi )
{
return create.object( objectName, spawnLocation, level, withAi, false );
}
obj_id object( string objectName, location spawnLocation, boolean withAi, boolean isPet )
{
return object( objectName, spawnLocation, -1, withAi, isPet );
}
obj_id object( string objectName, location spawnLocation, int level, boolean withAi, boolean isPet )
{
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;
}
}
obj_id object( string objectName, obj_id objContainer, boolean withAi, boolean isPet )
{
obj_id creature = object( objectName, objContainer, -1, withAi, isPet );
if ( isIdValid(creature) )
utils.setScriptVar( creature, "spawnedBy", getSelf() );
return creature;
}
obj_id object( string objectName, obj_id objContainer, int level, boolean withAi, boolean isPet )
{
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;
}
}
/**
* Creates an object at an x/z-offset of the parent object's location
* The parent object is the object to which this script is attached
*
* @params objectName the name of the thing to make
* @params xOffset the float x-offset at which to create the object
* @params zOffset the float z-offset at which to create the object
*
* @returns the obj_id of the new object
*/
obj_id object( string objectName, float xOffset, float zOffset )
{
return object( objectName, xOffset, zOffset, -1 );
}
obj_id object( string objectName, float xOffset, float zOffset, int level )
{
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 );
}
/**
* Creates an object, persists it, makes it invulnerable and adds a destroy messageHandler to it
*
* @params objectName the template, NPC or creatureName to create
* @params xOffset
* @params zOffset the location offset from Self to create the object at
* @params destoyHandlerName the messageHandler to send a message to Self when this object is destroyed
* @params destroyMessageDelay the delay for the destroy message to use
*
* @returns the obj_id of the new object
*/
obj_id themeParkObject( string objectName, float xOffset, float zOffset, string destroyHandlerName, float destroyMessageDelay )
{
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;
}
obj_id themeParkObject( string objectName, float xOffset, float zOffset )
{
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;
}
/* -----------------12/11/2002 3:31PM----------------
* Used to create an NPC of a specified species or from a specific species-list
*
* @params creatureName the name of the creature to spawn
* @params templateName the name of the creature template to use, or the species datatable name to use
* @params spawnLocation the location at which to create the thing
*
* @returns the obj_id of the created creature
* --------------------------------------------------*/
obj_id createNpc( string creatureName, string templateName, location spawnLocation )
{
return createNpc( creatureName, templateName, spawnLocation, -1 );
}
obj_id createNpc( string creatureName, string templateName, location spawnLocation, int level )
{
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" ))
{
//if this is an entry in the dress-species table, then use that:
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
{
//else use the old species_selection table
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 );
}
/**
* Creates an NPC of a specific type at x/z-offsets from the parent object
* The parent object is the object to which this script is attached
*
* @params creatureName the name of the npc to create
* @params templateName the species template or species-template list datatable to create
* @params xOffset the x-offset to create the creature at
* @params zOffset the z-offset to create the creature at
*
* @returns the obj_id of the creature created
*/
obj_id createNpc( string creatureName, string templateName, float xOffset, float zOffset )
{
return createNpc( creatureName, templateName, xOffset, zOffset, -1 );
}
obj_id createNpc( string creatureName, string templateName, float xOffset, float zOffset, int level )
{
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 );
}
/**
* Used to create a creature from the creature datatable at the given location
*
* @params creatureName the name/type of creature to spawn
* @params spawnLocation the location at which to spawn it
*
* @returns the obj_id of the creature
*/
obj_id createCreature( string creatureName, location spawnLocation, boolean withAi )
{
return createCreature( creatureName, spawnLocation, -1, withAi );
}
obj_id createCreature( string creatureName, location spawnLocation, int level, boolean withAi )
{
return create.createCreature( creatureName, spawnLocation, level, withAi, false );
}
obj_id createCreature( string creatureName, location spawnLocation, boolean withAi, boolean isPet )
{
return createCreature( creatureName, spawnLocation, -1, withAi, isPet );
}
obj_id createCreature( string creatureName, location spawnLocation, int level, boolean withAi, boolean isPet )
{
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 == "" || 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 );
}
obj_id createCreature( string creatureName, obj_id objContainer, boolean withAi, boolean isPet )
{
return createCreature( creatureName, objContainer, -1, withAi, isPet );
}
obj_id createCreature( string creatureName, obj_id objContainer, int level, boolean withAi, boolean isPet )
{
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 == "" || 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 );
}
/**
* Called by createNpc and createCreature to create a creature and set attribs from the datatable
*
* @params creatureName the name of the creature to create
* @params templateName the name of the template to use
* @params spawnLocation the location at which to create the creature
* @params creatureDict a dictionary containing the creature's datatable info
*
* @returns the obj_id of the creature created
*/
obj_id createCreature( string creatureName, string templateName, location spawnLocation, dictionary creatureDict, boolean withAi )
{
return createCreature( creatureName, templateName, spawnLocation, creatureDict, -1, withAi );
}
obj_id createCreature( string creatureName, string templateName, location spawnLocation, dictionary creatureDict, int level, boolean withAi )
{
return createCreature( creatureName, templateName, spawnLocation, creatureDict, level, withAi, false );
}
obj_id createCreature( string creatureName, string templateName, location spawnLocation, dictionary creatureDict, boolean withAi, boolean isPet )
{
return createCreature( creatureName, templateName, spawnLocation, creatureDict, -1, withAi, isPet );
}
obj_id createCreature( string creatureName, string templateName, location spawnLocation, dictionary creatureDict, int level, boolean withAi, boolean isPet )
{
if ( templateName == "" || templateName == null )
{
LOG( "create", creatureName + " could not be made because templateName is null" );
return null;
}
if ( creatureName == "" || 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 == "" )
{
finalCreatureName = creatureName;
}
randomlyNameCreature( creature, finalCreatureName );
initializeCreature ( creature, creatureName, creatureDict, level );
attachCreatureScripts( creature, creatureDict.getString( "scripts" ), withAi );
return creature;
}
obj_id createCreature( string creatureName, string templateName, obj_id objContainer, dictionary creatureDict, boolean withAi, boolean isPet )
{
return createCreature( creatureName, templateName, objContainer, creatureDict, -1, withAi, isPet );
}
obj_id createCreature( string creatureName, string templateName, obj_id objContainer, dictionary creatureDict, int level, boolean withAi, boolean isPet )
{
if ( templateName == "" || templateName == null )
{
LOG( "create", creatureName + " could not be made because templateName is null" );
return null;
}
if ( creatureName == "" || 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 == "" )
{
finalCreatureName = creatureName;
}
randomlyNameCreature( creature, finalCreatureName );
initializeCreature ( creature, creatureName, creatureDict, level );
attachCreatureScripts( creature, creatureDict.getString( "scripts" ), withAi );
return creature;
}
// returns modified xp value for creature xp
/*
int getCreatureXP(dictionary creatureDict)
{
const float PACK_MODIFIER = .05f;
const float AGGRO_MODIFIER = .10f;
const float KILLER_MODIIFER = .05f;
const float STALKER_MODIFIER = .025f;
int intRawXP = creatureDict.getInt( "XP" );
int intKiller = creatureDict.getInt("killer");
int intStalker = creatureDict.getInt("stalker");
int intPack = creatureDict.getInt("pack");
int intAggro = creatureDict.getInt("aggro");
float fltModifier = 1;
fltModifier = fltModifier + (intKiller * KILLER_MODIIFER);
fltModifier = fltModifier + (intStalker * STALKER_MODIFIER);
fltModifier = fltModifier + (intPack * PACK_MODIFIER);
fltModifier = fltModifier + (intAggro * AGGRO_MODIFIER);
intRawXP = (int)(intRawXP * fltModifier);
return intRawXP;
}*/
/**
* Called by createCreature to set a creature's attribs from the datatable
*
* @params creature the obj_id of the creature to initialize
* @params creatureName the name of the creature to create
* @params creatureDict a dictionary containing the creature's datatable info
*
* @returns nothing
*/
void initializeCreature( obj_id creature, string creatureName, dictionary creatureDict )
{
initializeCreature( creature, creatureName, creatureDict, -1);
}
void initializeCreature( obj_id creature, string creatureName, dictionary creatureDict, int level )
{
LOGC(aiLoggingEnabled(creature), "debug_ai", ("########## create::initializeCreature() BEGIN ai(" + creature + ") creatureName(" + creatureName + ") ##########"));
//record creatureName for AI script to reference
setCreatureName(creature, creatureName);
//set scale:
float minScale = creatureDict.getFloat( "minScale" );
float maxScale = creatureDict.getFloat( "maxScale" );
float baseScale = getScale( creature );
if ( baseScale != 1.0f )
utils.setScriptVar( creature, "ai.baseScale", baseScale );
// don't rescale storyteller npcs.
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"));
//hue creature:
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 ( int i = 0; i < c.length; i++)
c[i].setValue(huevar);
}
}
// Get level settings
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");
// Cap levels
if (dmgLevel <= 0) dmgLevel = 1;
if (statLevel <= 0) statLevel = 1;
if (toHitLevel <= 0) toHitLevel = 1;
if (armorLevel <= 0) armorLevel = 1;
// Check for level override
if (level > 0)
{
dmgLevel = level;
statLevel = level;
toHitLevel = level;
armorLevel = level;
}
else // Compute final level on level settings
{
// This weighted average must match up with BE clone level calcs
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);
// This scriptvar is pre-existing and is already in use in a number of places to check for a weapon that is being used by an ai.
// The objvar is being added so that if a player somehow gets hold of an ai weapon, we'll be able to know that.
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);
// This scriptvar is pre-existing and is already in use in a number of places to check for a weapon that is being used by an ai.
// The objvar is being added so that if a player somehow gets hold of an ai weapon, we'll be able to know that.
utils.setScriptVar(defaultWeapon, "isCreatureWeapon", 1);
setObjVar(defaultWeapon, "isCreatureWeapon", 1);
}
// Setup the primary weapon (there is no real need I can see for this weapon setup to not be in server code)
{
if(aiHasPrimaryWeapon(creature))
{
const obj_id primaryWeapon = aiGetPrimaryWeapon(creature);
dictionary primDat = weapons.getWeaponDat(primaryWeapon);
if(primDat != null)
{
// set values from data table
weapons.setWeaponAttributes(primaryWeapon, primDat, 1f);
}
// override data table values
setWeaponAttackSpeed(primaryWeapon, primarySpeed);
setWeaponMaxDamage(primaryWeapon, priMaxDamage);
setWeaponMinDamage(primaryWeapon, priMinDamage);
weapons.setWeaponData(primaryWeapon);
hasRanged = hasRanged || combat.isRangedWeapon(primaryWeapon);
if(hasScript(primaryWeapon, BIOLINK_SCRIPT))
cleanOffBioLink(primaryWeapon);
// This scriptvar is pre-existing and is already in use in a number of places to check for a weapon that is being used by an ai.
// The objvar is being added so that if a player somehow gets hold of an ai weapon, we'll be able to know that.
utils.setScriptVar(primaryWeapon, "isCreatureWeapon", 1);
setObjVar(primaryWeapon, "isCreatureWeapon", 1);
}
}
// Setup the secondary weapon (there is no real need I can see for this weapon setup to not be in server code)
{
if(aiHasSecondaryWeapon(creature))
{
const obj_id secondaryWeapon = aiGetSecondaryWeapon(creature);
dictionary secDat = weapons.getWeaponDat(secondaryWeapon);
if(secDat != null)
{
weapons.setWeaponAttributes(secondaryWeapon, secDat, 1f);
}
// override data table values
setWeaponAttackSpeed(secondaryWeapon, secondarySpeed);
setWeaponMaxDamage(secondaryWeapon, secMaxDamage);
setWeaponMinDamage(secondaryWeapon, secMinDamage);
weapons.setWeaponData(secondaryWeapon);
hasRanged = hasRanged || combat.isRangedWeapon(secondaryWeapon);
if(hasScript(secondaryWeapon, BIOLINK_SCRIPT))
cleanOffBioLink(secondaryWeapon);
// This scriptvar is pre-existing and is already in use in a number of places to check for a weapon that is being used by an ai.
// The objvar is being added so that if a player somehow gets hold of an ai weapon, we'll be able to know that.
utils.setScriptVar(secondaryWeapon, "isCreatureWeapon", 1);
setObjVar(secondaryWeapon, "isCreatureWeapon", 1);
}
}
// non-ranged opponents get more HP and faster speed
float speedMod = 1;
float hpMod = 1;
if(hasRanged)
{
speedMod = MELEE_SPEED_MOD;
hpMod = MELEE_HP_MOD;
}
//setAttribs
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 );
//setRegenRates
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); // CHANGES MADE 10/31/2005 to work with SJakab's new regen methods.
//setMaxAttrib(creature, CONSTITUTION, healthRegen );
setRegenRate(creature, STAMINA, healthRegen);
//setMaxAttrib(creature, STAMINA, actionRegen );
setRegenRate(creature, WILLPOWER, healthRegen);
//setMaxAttrib(creature, WILLPOWER, mindRegen );
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;
setBaseRunSpeed(creature, runSpeed);
// Never let an ai walk at a speed faster than it can run
{
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 != "" ))
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" );
//Set creatures spawned indoors to default sentinel
if (getTopMostContainer(creature) != creature)
ai_lib.setDefaultCalmBehavior(creature, ai_lib.BEHAVIOR_SENTINEL);
/*
if ( niche == NICHE_NPC || niche == NICHE_ANDROID)
{
string weaponList = creatureDict.getString( "weaponList" );
if (weaponList.equals(null) || weaponList.equals( "" ) )
dressup.equipNpcWeapon( creature, "pirate_medium" );
else if (!weaponList.equals("none") )
dressup.equipNpcWeapon( creature, weaponList );
}
*/
randomlyNameCreature( creature, creatureName );
//setup Attributes and Interests for trigger volume breaches
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;
}
// SETUP OUR LOOT STUFF
string strLootTable = creatureDict.getString("lootTable");
int intRolls = creatureDict.getInt("intLootRolls");
int intPercentage = creatureDict.getInt("intRollPercent");
if(strLootTable!="")
{
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);
}
// add natural armor
if (!initializeArmor(creature, creatureDict, dataTableGetInt(STAT_BALANCE_TABLE, armorLevel - 1, diffClassName + "Armor")))
LOG( "create", "Unable to initialize armor on " + creatureName + "(" + creature + ")");
// Deprecated Armor Abstact Method
//string armor_abstract = "abstract/armor_statistics/armor/creature/statistics_armor_" + creatureName + ".iff";
//LOG("LOG_CHANNEL", "abstract ->" + armor_abstract);
//if (!addArmorLayer(creature, armor_abstract))
// LOG( "create", "Invalid armor abstract " + armor_abstract + " added to " + creature);
//this is a very hacky way of doing this
//Check for adding faction scripts
int stringCheck = creatureName.indexOf("recruiter");
if (stringCheck > -1)
{
string pvpFaction = creatureDict.getString( "pvpFaction" );
setFactionRecruiter(creature, pvpFaction);
}
//Creatures that can detect hidden
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 + ") ##########"));
}
int calcCreatureLevel(string creatureName)
{
dictionary creatureDict = utils.dataTableGetRow( CREATURE_TABLE, creatureName );
if ( creatureDict == null )
{
debugServerConsoleMsg( null, "WARNING: Unable to find invalid creatureType: " + creatureName );
return -1;
}
return calcCreatureLevel(creatureDict);
}
int calcCreatureLevel(dictionary creatureDict)
{
// Get level settings
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");
// Cap levels
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);
}
int calcCreatureLevel(int statLevel, int dmgLevel, int toHitLevel, int armorLevel)
{
int level = 0;
// Compute final level on level settings
{
// This weighted average must match up with BE clone level calcs
level = (int)(((statLevel*6) + (dmgLevel*6) + (toHitLevel*2) + (armorLevel*4))/18f);
}
return level;
}
/**
* Scripts are stored in the format:
* scriptname,scriptname,scriptname
*/
void attachCreatureScripts( obj_id creature, string scriptList, boolean withAi )
{
if ( getConfigSetting("GameServer", "disableAI")!=null )
return;
//Everyone gets the AI script:
if ( withAi )
{
//always attach ai.ai first, and cerature combat scripts second:
attachScript( creature, "ai.ai" );
attachCombatScripts( creature );
attachScript(creature, "systems.skills.stealth.player_stealth");
//grantAllAbilities( creature );
}
if ( scriptList == null || scriptList == "" )
return;
string[] scriptArray = split(scriptList, ',' );
for ( int i = 0; i < scriptArray.length; i++ )
{
attachScript( creature, scriptArray[i] );
}
}
boolean initializeArmor(obj_id creature, dictionary creatureDict)
{
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);
}
boolean initializeArmor(obj_id creature, dictionary creatureDict, int armorRating)
{
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);
}
boolean initializeArmor(obj_id creature, int[] armorData)
{
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;
// Clear out any existing armor data
armor.removeAllArmorData(creature);
// Set base armor info
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;
}
/**
* Creature Objvars are stored in the format:
* int:name=value,string:name=value,float:name=value
*/
void setCreatureObjVars( obj_id creature, string objVarList )
{
//moved this to utils for other script use as well
utils.setObjVarsList(creature, objVarList);
}
/**
* Called to get the STRING difficulty of a lair based on the min and max difficulty
*
* @param intMinDifficulty the minimum difficulty of the lair
* @param intMaxDifficulty the max difficulty of the lair
* @param intPlayerDifficulty the player's difficulty level
*
* @returns the string value of the lair difficulty, "veryEasy", "easy", "medium", "hard" "veryHard"
*/
string getLairDifficulty(int intMinDifficulty, int intMaxDifficulty, int intPlayerDifficulty)
{
// we need to check where the spawned difficulty falls in terms of the actual ranges.
// based on that, we'll return a string
// there are 5 sizes
// veryEasy, easy, medium, hard, veryHard
// every 20 % gives us these
const string[] LAIR_DIFFICULTIES = {"veryEasy", "easy", "medium", "hard", "veryHard"};
// normalize the numbers
int intDifference = intMaxDifficulty - intMinDifficulty;
intPlayerDifficulty = intPlayerDifficulty - intMinDifficulty;
// now we're normalzied to a 0 scale
if(intDifference==0)
{
intDifference = 1;
}
float fltPercent = (float)(intPlayerDifficulty / intDifference);
fltPercent = fltPercent * 100;
int intIndex = (int)(fltPercent / 20);
// normalize to 0 through 4)
intIndex = intIndex - 1;
if(intIndex<0)
{
intIndex = 0;
}
if (intIndex >= LAIR_DIFFICULTIES.length)
{
intIndex = LAIR_DIFFICULTIES.length - 1;
}
return LAIR_DIFFICULTIES[intIndex];
}
/**
* Grants npcs all the abilities they need to perform combat skills:
*
* @params npc the npc
*
* @returns nothing
*/
void grantAllAbilities( obj_id npc )
{
return;
/** removing this call because NPCs don't need to be granted abilities:
grantCommand(npc, "combatAttitudeEvasive");
grantCommand(npc, "combatAttitudeNeutral");
grantCommand(npc, "combatAttitudeAggressive");
int niche = ai_lib.aiGetNiche( npc );
if ( niche != NICHE_NPC )
return;
grantCommand(npc, "aim");
grantCommand(npc, "rifleAim");
grantCommand(npc, "pistolAim");
grantCommand(npc, "carbineAim");
grantCommand(npc, "unarmedAim");
grantCommand(npc, "fullAutoSingle");
grantCommand(npc, "fullAutoArea");
grantCommand(npc, "headShot");
grantCommand(npc, "bodyShot");
grantCommand(npc, "legShot");
grantCommand(npc, "disarmingShot");
grantCommand(npc, "suppressionFire");
grantCommand(npc, "startle");
grantCommand(npc, "strafe");
grantCommand(npc, "flurry");
grantCommand(npc, "diveShot");
grantCommand(npc, "rollShot");
grantCommand(npc, "kipUpShot");
grantCommand(npc, "rescue");
grantCommand(npc, "wildShot");
grantCommand(npc, "surpriseShot");
grantCommand(npc, "charge");
grantCommand(npc, "berserk");
grantCommand(npc, "intimidate");
grantCommand(npc, "warcry");
grantCommand(npc, "takeCover");
grantCommand(npc, "tumbleToProne");
grantCommand(npc, "tumbleToKneeling");
grantCommand(npc, "tumbleToStanding");
//grantCommand(npc, "sneak");
grantCommand(npc, "alert");
//grantCommand(npc, "block");
grantCommand(npc, "feignIncapacitation");
*/
}
/**
* Attaches the appropriate combat script for an npc, based on the npc's skeleton
*
* @params npc the npc to attach the scripts to
*
* @returns nothing
*/
void attachCombatScripts( obj_id npc )
{
if ( !hasScript( npc, "ai.creature_combat") )
attachScript( npc, "ai.creature_combat" );
if (!hasScript(npc, "systems.combat.combat_actions"))
attachScript(npc, "systems.combat.combat_actions");
obj_id primaryWeapon = aiGetPrimaryWeapon(npc);
obj_id secondaryWeapon = aiGetSecondaryWeapon(npc);
boolean hasJediWeapon = false;
if (isIdValid(primaryWeapon))
{
if (jedi.isLightsaber(primaryWeapon))
hasJediWeapon = true;
}
if (isIdValid(secondaryWeapon))
{
if (jedi.isLightsaber(secondaryWeapon))
hasJediWeapon = true;
}
}
/**
* Applies the toHitPercent to all the creature's skill statistics:
*
* @params creature the obj_id of the creature
* @params toHitChance the float indicating the creatures chance to hit
*
* @returns nothing
*/
void applySkillStatisticModifiers( obj_id creature, int toHitChance, int defenseValue )
{
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);
}
void applyCreatureImmunities(obj_id creature, dictionary creatureDict)
{
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);
}
}
/**
* Adds a destroy message to a creature or object which is sent to
* the recipient when the creature is destroyed
*
* The message is sent by the object.destroy_message script, and is a
* persisted message if the recipient is a persisted object
*
* @params creature the creature that should send the message
* @params handlerName the messageHandlerName which should be sent
* @params delay the float delay for delivery of the message
* @params recipient the obj_id of the object to be messaged.
*
* @returns nothing
*/
void addDestroyMessage( obj_id creature, string handlerName, float delay, obj_id recipient )
{
if ( !isIdValid(creature) )
return;
if ( !hasScript( creature, "object.destroy_message" ))
attachScript( creature, "object.destroy_message" );
resizeable string[] destroyMessageNames = new string[0];
resizeable float[] destroyMessageDelays = new float[0];
resizeable obj_id[] destroyMessageRecipients = new obj_id[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.length > 0)) && ((destroyMessageDelays != null) && (destroyMessageDelays.length > 0)) &&
((destroyMessageRecipients != null) && (destroyMessageRecipients.length > 0))) { // Zero length array check
setObjVar(creature, "destroyMessageList.handlerNames", destroyMessageNames );
setObjVar(creature, "destroyMessageList.delays", destroyMessageDelays );
setObjVar(creature, "destroyMessageList.recipients", destroyMessageRecipients );
}
}
void randomlyNameCreature( obj_id npc, string creatureName )
{
string templateName = getTemplateName( npc );
if ( templateName.indexOf("stormtrooper") != -1 )
{
nameStormTrooper( npc );
// return;
}
if ( templateName.indexOf("swamp_trooper") != -1 )
{
nameSwampTrooper( npc );
// return;
}
if ( templateName.indexOf("scout_trooper") != -1 )
{
nameScoutTrooper( npc );
// return;
}
if ( templateName.indexOf("tie_fighter") != -1 )
{
nameImperialPilot( npc );
// return;
}
if ( templateName.indexOf("dark_trooper") != -1 )
{
nameDarkTrooper( npc );
// return;
}
string oldName = getAssignedName( npc );
string_id nameId = new string_id( CREATURE_NAME_FILE, creatureName );
string actualName = getString(nameId);
if (actualName == null || actualName == "")
{
setTitle( npc, creatureName );
return;
}
setName( npc, "" );
setName( npc, nameId );
}
void setTitle( obj_id npc, string creatureName )
{
string_id nameId = new string_id( CREATURE_NAME_FILE, creatureName );
if ( nameId == null )
return;
string newName = getString( nameId );
if ( newName == null || newName == "" )
return;
string oldName = getAssignedName( npc );
string oldNameId = getString( getNameStringId( npc ));
if ( oldName == oldNameId )
{
setName( npc, "" );
setName( npc, nameId );
}
else if ( oldName == null || oldName == "" )
{
setName( npc, "" );
setName( npc, nameId );
}
else
{
setName( npc, oldName + " (" + getString(nameId) + ")" );
}
}
void nameStormTrooper( obj_id npc )
{
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));
}
void nameImperialPilot( obj_id npc )
{
setName (npc, "DS-"+ rand(1,820));
}
void nameScoutTrooper( obj_id npc )
{
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));
}
void nameDarkTrooper( obj_id npc )
{
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));
}
void nameSwampTrooper( obj_id npc )
{
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));
}
boolean setFactionRecruiter(obj_id npc, string faction)
{
// Turns any npc into a faction recruiter of the specified faction.
// Faction must appear exactly as it does in the faction datatable.
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;
}
void setUpFactionalEnemyAttribs( obj_id npc, string pvpFaction )
{
if ( pvpFaction == null )
return;
if ( pvpFaction == "" )
return;
//NPCs with factional enemies need to be able to 'see' each other:
setAttributeAttained( npc, attrib.NPC );
setAttributeInterested( npc, attrib.NPC );
}
void cleanOffBioLink(obj_id weapon)
{
detachScript(weapon, BIOLINK_SCRIPT);
removeObjVar(weapon, "biolink");
return;
}