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

665 lines
16 KiB
Plaintext

include library.ai_lib;
include library.pet_lib;
include library.beast_lib;
include library.utils;
include library.vehicle;
const int CALLABLE_TYPE_UNKNOWN = -1;
const int CALLABLE_TYPE_COMBAT_OTHER = 0;
const int CALLABLE_TYPE_COMBAT_PET = 1;
const int CALLABLE_TYPE_FAMILIAR = 2;
const int CALLABLE_TYPE_RIDEABLE = 3;
const int CALLABLE_TYPE_SHIP = 4;
const string OBJVAR_CALLABLE_TYPE_COMBAT_OTHER = "callable.type.combat_other";
const string OBJVAR_CALLABLE_TYPE_COMBAT_PET = "callable.type.combat_pet";
const string OBJVAR_CALLABLE_TYPE_FAMILIAR = "callable.type.familiar";
const string OBJVAR_CALLABLE_TYPE_RIDEABLE = "callable.type.rideable";
const string OBJVAR_CALLABLE_CALLED = "pet.called";
const string OBJVAR_CALLABLE_CONTROL_DEVICE = "pet.controlDevice";
const string SCRIPTVAR_RIDEABLE_PACKED_CALLABLE = "callable.recently_packed";
const int MAX_STORED_COMBAT_PETS = 20;
const int MAX_STORED_FAMILIARS = 40;
// Base Number of Rideables a player may have in their datapad. This number can be added to via an objvar.
const int BASE_MAX_STORED_RIDEABLES = 40;
// Overall Max Number of Rideables a player may have in their datapad. This is the hard cap.
const int ABSOLUTE_MAX_STORED_RIDEABLES = 150;
// The value of this objvar can increase the max number of rideables a player may have in their datapad.
const string ADDON_MAX_STORED_RIDEABLES_OBJVAR = "rideables.addonMaxStoredRideables";
void clog(string text)
{
if(text != null)
{
LOG("callable beasts", text);
}
}
int getControlDeviceType(obj_id cd)
{
if(beast_lib.isValidBCD(cd))
{
return CALLABLE_TYPE_COMBAT_PET;
}
if(hasObjVar(cd, "ai.pet.trainedMount") || hasScript(cd, "systems.vehicle_system.vehicle_control_device"))
{
return CALLABLE_TYPE_RIDEABLE;
}
if(hasScript(cd, "space.ship_control_device.ship_control_device"))
{
return CALLABLE_TYPE_SHIP;
}
int petType = -1;
if(hasObjVar(cd, "ai.pet.type"))
{
petType = getIntObjVar(cd, "ai.pet.type");
}
switch(petType)
{
case pet_lib.PET_TYPE_NON_AGGRO:
case pet_lib.PET_TYPE_AGGRO:
case pet_lib.PET_TYPE_NPC:
case pet_lib.PET_TYPE_DROID:
return CALLABLE_TYPE_COMBAT_PET;
case pet_lib.PET_TYPE_FAMILIAR:
return CALLABLE_TYPE_FAMILIAR;
}
return CALLABLE_TYPE_UNKNOWN;
}
int getCallableType(obj_id objCallable)
{
if(!isIdValid(objCallable) || !exists(objCallable))
{
return CALLABLE_TYPE_UNKNOWN;
}
if((beast_lib.isBeast(objCallable) || pet_lib.isDroidPet(objCallable) || ai_lib.aiGetNiche(objCallable) == NICHE_NPC) && pet_lib.getPetType(objCallable) != pet_lib.PET_TYPE_FAMILIAR)
{
return CALLABLE_TYPE_COMBAT_PET;
}
if( pet_lib.isFamiliarPetType(objCallable) )
{
return CALLABLE_TYPE_FAMILIAR;
}
if(hasCallableCD(objCallable))
{
obj_id petControlDevice = getCallableCD(objCallable);
if((isValidId(petControlDevice) && exists(petControlDevice) && hasObjVar(petControlDevice, "ai.pet.trainedMount")) ||
pet_lib.isVehiclePet(objCallable))
{
return CALLABLE_TYPE_RIDEABLE;
}
}
if(hasObjVar(objCallable, "ai.pet.buddy"))
{
return CALLABLE_TYPE_COMBAT_OTHER;
}
return CALLABLE_TYPE_UNKNOWN;
}
string getCallableTypeObjVar(int type)
{
switch(type)
{
case CALLABLE_TYPE_COMBAT_OTHER:
return OBJVAR_CALLABLE_TYPE_COMBAT_OTHER;
case CALLABLE_TYPE_COMBAT_PET:
return OBJVAR_CALLABLE_TYPE_COMBAT_PET;
case CALLABLE_TYPE_FAMILIAR:
return OBJVAR_CALLABLE_TYPE_FAMILIAR;
case CALLABLE_TYPE_RIDEABLE:
return OBJVAR_CALLABLE_TYPE_RIDEABLE;
default: // Unknown type
return null;
}
}
obj_id getCallable(obj_id master, int objCallableType)
{
if(!beast_lib.isValidPlayer(master))
{
return null;
}
string strObjVar = getCallableTypeObjVar(objCallableType);
if(strObjVar == null)
{
return null;
}
if(utils.hasScriptVar(master, strObjVar))
{
obj_id objCallable = utils.getObjIdScriptVar(master, strObjVar);
if(isIdValid(objCallable) && exists(objCallable))
{
return objCallable;
}
}
return null;
}
obj_id[] getCallables(obj_id master)
{
int [] callableTypes = { CALLABLE_TYPE_COMBAT_OTHER, CALLABLE_TYPE_COMBAT_PET, CALLABLE_TYPE_FAMILIAR, CALLABLE_TYPE_RIDEABLE };
resizeable obj_id[] callables = new obj_id[0];
for(int i = 0; i < callableTypes.length; i++)
{
obj_id objCallable = getCallable(master, callableTypes[i]);
if(isIdValid(objCallable) && exists(objCallable))
{
callables = utils.addElement(callables, objCallable);
}
}
return callables;
}
obj_id[] getDatapadCallablesByType(obj_id master, int callableType)
{
resizeable obj_id[] callables = new obj_id[0];
obj_id datapad = utils.getPlayerDatapad(master);
if(!isIdValid(datapad))
{
return null;
}
obj_id[] dataItems = getContents(datapad);
for(int i = 0; i < dataItems.length; i++)
{
if(getControlDeviceType(dataItems[i]) == callableType)
{
callables = utils.addElement(callables, dataItems[i]);
}
}
return callables;
}
boolean hasCallable(obj_id master, int objCallableType)
{
return hasCallable(master, objCallableType, obj_id.NULL_ID);
}
boolean hasCallable(obj_id master, int objCallableType, obj_id beast)
{
if(!beast_lib.isValidPlayer(master))
{
return true;
}
string strObjVar = getCallableTypeObjVar(objCallableType);
if(strObjVar == null)
{
return true;
}
if(utils.hasScriptVar(master, strObjVar))
{
obj_id objCallable = utils.getObjIdScriptVar(master, strObjVar);
if(isIdValid(beast))
{
if(isIdValid(objCallable) && exists(objCallable) && beast != objCallable)
{
return true;
}
}
else
{
if(isIdValid(objCallable) && exists(objCallable))
{
return true;
}
}
}
return false;
}
boolean hasAnyCallable(obj_id master)
{
if(hasCallable(master, CALLABLE_TYPE_COMBAT_OTHER) || hasCallable(master, CALLABLE_TYPE_COMBAT_PET) ||
hasCallable(master, CALLABLE_TYPE_FAMILIAR) || hasCallable(master, CALLABLE_TYPE_RIDEABLE))
{
return true;
}
return false;
}
boolean setCallable(obj_id master, obj_id objCallable, int objCallableType)
{
if(!beast_lib.isValidPlayer(master))
{
return false;
}
if(objCallableType == -1 && isIdValid(objCallable) && exists(objCallable))
{
objCallableType = getCallableType(objCallable);
}
string strObjVar = getCallableTypeObjVar(objCallableType);
if(strObjVar == null)
{
return false;
}
// If the objCallable is null, then remove the script var.
if(objCallableType != -1 && !isIdValid(objCallable))
{
utils.removeScriptVar(master, strObjVar);
return true;
}
if(hasCallable(master, objCallableType))
{
return false;
}
utils.setScriptVar(master, strObjVar, objCallable);
return true;
}
obj_id getCDCallable(obj_id cd)
{
if(!isIdValid(cd) || !exists(cd))
{
return null;
}
if(utils.hasScriptVar(cd, OBJVAR_CALLABLE_CALLED))
{
obj_id objCallable = utils.getObjIdScriptVar(cd, OBJVAR_CALLABLE_CALLED);
if(isIdValid(objCallable) && exists(objCallable))
{
return objCallable;
}
}
return null;
}
boolean hasCDCallable(obj_id cd)
{
if(!isIdValid(cd) || !exists(cd))
{
return false;
}
if(utils.hasScriptVar(cd, OBJVAR_CALLABLE_CALLED))
{
obj_id objCallable = utils.getObjIdScriptVar(cd, OBJVAR_CALLABLE_CALLED);
if(isIdValid(objCallable) && exists(objCallable))
{
return true;
}
}
return false;
}
boolean setCDCallable(obj_id cd, obj_id objCallable)
{
if(!isIdValid(cd) || !exists(cd))
{
return false;
}
if(isIdValid(objCallable) && exists(objCallable))
{
utils.setScriptVar(cd, OBJVAR_CALLABLE_CALLED, objCallable);
}
else
{
utils.removeScriptVar(cd, OBJVAR_CALLABLE_CALLED);
}
return true;
}
obj_id getCallableCD(obj_id objCallable)
{
if(!isIdValid(objCallable) || !exists(objCallable))
{
return null;
}
if(hasObjVar(objCallable, OBJVAR_CALLABLE_CONTROL_DEVICE))
{
obj_id cd = getObjIdObjVar(objCallable, OBJVAR_CALLABLE_CONTROL_DEVICE);
if(isIdValid(cd) && exists(cd))
{
return cd;
}
}
return null;
}
boolean hasCallableCD(obj_id objCallable)
{
if(!isIdValid(objCallable) || !exists(objCallable))
{
return false;
}
if(hasObjVar(objCallable, OBJVAR_CALLABLE_CONTROL_DEVICE))
{
obj_id cd = getObjIdObjVar(objCallable, OBJVAR_CALLABLE_CONTROL_DEVICE);
if(isIdValid(cd) && exists(cd))
{
return true;
}
}
return false;
}
boolean setCallableCD(obj_id objCallable, obj_id cd)
{
if(!isIdValid(cd) || !exists(cd) || !isIdValid(objCallable) || !exists(objCallable))
{
return false;
}
setObjVar(objCallable, OBJVAR_CALLABLE_CONTROL_DEVICE, cd);
return true;
}
void setCallableLinks(obj_id master, obj_id cd, obj_id objCallable)
{
setCallable(master, objCallable, getCallableType(objCallable));
setCDCallable(cd, objCallable);
setCallableCD(objCallable, cd);
setMaster(objCallable, master);
//DO NOT SET THE MASTER AS THE OWNER OF AN OBJECT OR YOU OWN ITS INVENTORY THIS INCLUDES WEAPONS AND STUFF
//we only need to set the master as the owner if we are a droid with an inventory module
if(pet_lib.isDroidPet(objCallable))
{
obj_id inventory = utils.getInventoryContainer(objCallable);
//this should prevent opening combat droids inventories
if(isIdValid(inventory))
setOwner(inventory, master);
}
}
void storeCallable(obj_id master, obj_id objCallable)
{
if(!isIdValid(objCallable) || !exists(objCallable))
{
return;
}
if(beast_lib.isBeast(objCallable))
{
beast_lib.storeBeast(beast_lib.getBeastBCD(objCallable));
}
else
{
int callableType = getCallableType(objCallable);
clog("callableType: " + callableType + " pet_lib.isVehiclePet(objCallable): " + pet_lib.isVehiclePet(objCallable));
if(pet_lib.isVehiclePet(objCallable))
{
vehicle.storeVehicle(getCallableCD(objCallable), master, false);
}
else
{
pet_lib.storePet(objCallable, master);
}
setCallable(master, null, callableType);
}
}
void storeCallables(obj_id master)
{
if(!isIdValid(master) || !exists(master) || !hasAnyCallable(master))
{
return;
}
int [] callableTypes = { CALLABLE_TYPE_COMBAT_OTHER, CALLABLE_TYPE_COMBAT_PET, CALLABLE_TYPE_FAMILIAR, CALLABLE_TYPE_RIDEABLE };
for(int i = 0; i < callableTypes.length; i++)
{
obj_id objCallable = getCallable(master, callableTypes[i]);
if(isIdValid(objCallable) && exists(objCallable))
{
storeCallable(master, objCallable);
}
}
}
void restoreCallable(obj_id master)
{
if(!isIdValid(master) || !exists(master) || hasCallable(master, CALLABLE_TYPE_COMBAT_PET) || !utils.hasScriptVar(master, SCRIPTVAR_RIDEABLE_PACKED_CALLABLE))
{
return;
}
obj_id cd = utils.getObjIdScriptVar(master, SCRIPTVAR_RIDEABLE_PACKED_CALLABLE);
if(beast_lib.isValidBCD(cd))
{
beast_lib.createBeastFromBCD(master, cd);
}
utils.removeScriptVar(master, SCRIPTVAR_RIDEABLE_PACKED_CALLABLE);
}
void killCallable(obj_id objCallable, obj_id killer)
{
if(!isIdValid(objCallable) || !exists(objCallable))
{
return;
}
if(beast_lib.isBeast(objCallable))
{
if(!isDead(objCallable))
{
beast_lib.killBeast(objCallable, killer);
}
}
else
{
if(objCallable.isLoaded() && ai_lib.aiIsDead(objCallable) && !isDead(objCallable))
{
utils.setScriptVar(objCallable, "killer", killer);
pet_lib.killPet(objCallable);
}
}
}
void killCallables(obj_id master, obj_id killer)
{
if(!isIdValid(master) || !exists(master) || !hasAnyCallable(master))
{
return;
}
int [] callableTypes = { CALLABLE_TYPE_COMBAT_OTHER, CALLABLE_TYPE_COMBAT_PET, CALLABLE_TYPE_FAMILIAR, CALLABLE_TYPE_RIDEABLE };
for(int i = 0; i < callableTypes.length; i++)
{
obj_id objCallable = getCallable(master, callableTypes[i]);
if(isIdValid(objCallable) && exists(objCallable))
{
killCallable(objCallable, killer);
}
}
}
int getNumStoredCDByType(obj_id master, int CDType)
{
if(!isIdValid(master) || !exists(master))
{
return 0;
}
obj_id datapad = utils.getPlayerDatapad(master);
if(!isIdValid(datapad))
{
return 0;
}
obj_id[] dataItems = getContents(datapad);
if(dataItems == null || dataItems.length < 1)
{
return 0;
}
int numStored = 0;
for(int i = 0; i < dataItems.length; i++)
{
if(getControlDeviceType(dataItems[i]) == CDType)
{
numStored++;
}
}
return numStored;
}
// Returns the number of rideables (vehicles and mounts) that the player may have in their datapad.
// These are "active" rideables that a player can use, so does not include any stored in a barn or garage.
int getMaxAllowedStoredRideables(obj_id player)
{
int totalMaxStoredRideables = BASE_MAX_STORED_RIDEABLES;
// Check for an addon to the max amount of stored rideables on this player over the base amount.
int addonMaxStoredRideables = getAddonMaxAllowedStoredRideables(player);
if ( addonMaxStoredRideables < 0 )
addonMaxStoredRideables = 0;
totalMaxStoredRideables += addonMaxStoredRideables;
// the total cannot be more than the absolute cap
if ( totalMaxStoredRideables > ABSOLUTE_MAX_STORED_RIDEABLES )
totalMaxStoredRideables = ABSOLUTE_MAX_STORED_RIDEABLES;
return totalMaxStoredRideables;
}
int getAddonMaxAllowedStoredRideables(obj_id player)
{
int addonAmount = 0;
if ( hasObjVar(player, ADDON_MAX_STORED_RIDEABLES_OBJVAR) )
{
addonAmount = getIntObjVar(player, ADDON_MAX_STORED_RIDEABLES_OBJVAR);
}
return addonAmount;
}
// Returns true or false based on whether the player already had the maximum number of rideables (vehicles and mounts)
boolean hasMaxStoredRideables(obj_id player)
{
int totalMaxStoredRideables = getMaxAllowedStoredRideables(player);
if( getNumStoredCDByType(player, CALLABLE_TYPE_RIDEABLE) >= totalMaxStoredRideables )
{
return true;
}
return false;
}
// Increases the addon number of rideables (vehicles and mounts) for the player over the base amount.
// Logs success or failure, plus the amount added.
// Logs the source if there is one.
boolean increaseAddonMaxStoredRideables(obj_id player, int amountIncreased)
{
return increaseAddonMaxStoredRideables(player, amountIncreased, obj_id.NULL_ID);
}
boolean increaseAddonMaxStoredRideables(obj_id player, int amountIncreased, obj_id source)
{
int currentAddonAmount = getAddonMaxAllowedStoredRideables(player);
int newAddonMaxAmount = currentAddonAmount + amountIncreased;
if ( newAddonMaxAmount < 0 )
{
string negativeAddonLog = "Increased Addon for Max Stored Rideables *FAILED*: ("+player+") "+getName(player)+": has failed to increase max stored rideables - would be negative addon amount: attempted new addon = "+newAddonMaxAmount+"(current addon ["+currentAddonAmount+"] + attempted increase to addon["+amountIncreased+"]).";
if ( isIdValid(source) )
{
negativeAddonLog += " Source of Increase: "+getEncodedName(source)+" ("+source+").";
}
CustomerServiceLog("max_stored_rideables", negativeAddonLog);
return false;
}
int currentMaxAllowedStoredRideables = getMaxAllowedStoredRideables(player);
int newMaxAllowedStoredRideables = BASE_MAX_STORED_RIDEABLES + newAddonMaxAmount;
if ( newMaxAllowedStoredRideables > ABSOLUTE_MAX_STORED_RIDEABLES )
{
string overCapLog = "Increased Addon for Max Stored Rideables *FAILED*: ("+player+") "+getName(player)+": has failed to increase max stored rideables - would be over the cap: attempted new max = "+newMaxAllowedStoredRideables+"(Base Amount ["+BASE_MAX_STORED_RIDEABLES+"] + current addon ["+currentAddonAmount+"] + attempted increase to addon["+amountIncreased+"]).";
if ( isIdValid(source) )
{
overCapLog += " Source of Increase: "+getEncodedName(source)+" ("+source+").";
}
CustomerServiceLog("max_stored_rideables", overCapLog);
return false;
}
setObjVar(player, ADDON_MAX_STORED_RIDEABLES_OBJVAR, newAddonMaxAmount);
string successLog = "Increased Addon for Max Stored Rideables *SUCCESS*: ("+player+") "+getName(player)+": successfully increased max stored rideables: new max = "+newMaxAllowedStoredRideables+" (Base Amount ["+BASE_MAX_STORED_RIDEABLES+"] + current addon ["+currentAddonAmount+"] + increase to addon["+amountIncreased+"]).";
if ( isIdValid(source) )
{
successLog += " Source of Increase: "+getEncodedName(source)+" ("+source+").";
}
CustomerServiceLog("max_stored_rideables",successLog);
return true;
}
boolean hasMaxStoredCombatPets(obj_id master)
{
if(getNumStoredCDByType(master, CALLABLE_TYPE_COMBAT_PET) >= MAX_STORED_COMBAT_PETS)
{
return true;
}
return false;
}