mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
1064 lines
28 KiB
Plaintext
1064 lines
28 KiB
Plaintext
/**
|
|
* Title: camping.scriptlib
|
|
* Description: camping skill library
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
|
|
include library.utils;
|
|
include library.factions;
|
|
include library.battlefield;
|
|
include library.locations;
|
|
include library.pclib;
|
|
include library.xp;
|
|
include library.player_structure;
|
|
include library.structure;
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
//GENERAL DEFINES
|
|
const float CAMP_SIZE [] = { 6.f, 8.f, 10.f, 13.f, 15.f, 20.f };
|
|
const float MAX_SIZE = 14.f;
|
|
|
|
const int NUM_MARKER = 6;
|
|
|
|
const float HEARTBEAT_CREATION = 1.0f; //seconds
|
|
const float HEARTBEAT_MAINTAIN = 30.0f; //seconds
|
|
const float HEARTBEAT_RESTORE = 120.0f; //seconds
|
|
|
|
//CAMPING SKILL MOD DEFINES
|
|
const string MOD_CAMP = "camp";
|
|
const string MOD_CAMP_ADVANCED = "camp_advanced";
|
|
|
|
//MASTER OBJECT OBJVARS DEFINES
|
|
const string VAR_CAMP_BASE = "camp";
|
|
|
|
//status tracking vars
|
|
const string VAR_OWNER = VAR_CAMP_BASE + ".owner";
|
|
const string VAR_OWNER_NEAR = VAR_CAMP_BASE + ".owner_near";
|
|
|
|
const string VAR_STATUS = VAR_CAMP_BASE + ".status";
|
|
|
|
const string VAR_SIZE = VAR_CAMP_BASE + ".size";
|
|
const string VAR_LIFETIME = VAR_CAMP_BASE + ".lifetime";
|
|
const string VAR_CREATION_TIME = VAR_CAMP_BASE + ".creation_time";
|
|
const string VAR_DESTRUCT_TIME = VAR_CAMP_BASE + ".destruction_time";
|
|
|
|
const string VAR_BEEN_INITIALIZED = VAR_CAMP_BASE + ".beenInitialized";
|
|
|
|
//misc vars
|
|
const string VAR_CAMP_XP = VAR_CAMP_BASE + ".xp";
|
|
const string VAR_CAMP_REPEL = VAR_CAMP_BASE + ".repel";
|
|
const string VAR_CAMP_POWER = VAR_CAMP_BASE + ".power";
|
|
|
|
//trigger volume vars
|
|
const string VAR_TRIGGER_VOLUME = VAR_CAMP_BASE + ".triggerVolume";
|
|
|
|
//child tracking vars
|
|
const string VAR_CAMP_ITEM_BASE = VAR_CAMP_BASE + ".items";
|
|
|
|
const string VAR_ITEM_IDX = VAR_CAMP_BASE + ".item_idx";
|
|
const string VAR_ITEM_MAX = VAR_CAMP_BASE + ".item_max";
|
|
|
|
const string VAR_MARKERS = VAR_CAMP_ITEM_BASE + ".markers";
|
|
const string VAR_GENERAL_ITEMS = VAR_CAMP_ITEM_BASE + ".general";
|
|
const string VAR_ADVANCED_ITEMS = VAR_CAMP_ITEM_BASE + ".advanced";
|
|
|
|
//CREATOR OBJVAR DEFINES
|
|
const string VAR_PLAYER_CAMP = VAR_CAMP_BASE + ".id";
|
|
|
|
//SCRIPTVAR DEFINES
|
|
const string VAR_CURRENT_CAMP = VAR_CAMP_BASE + ".current";
|
|
|
|
//CAMP STATUS DEFINES
|
|
const int STATUS_UNKNOWN = -1;
|
|
const int STATUS_NEW = 0;
|
|
const int STATUS_CREATION = 1;
|
|
const int STATUS_MAINTAIN = 2;
|
|
const int STATUS_ABANDONED = 3;
|
|
|
|
//SCRIPT DEFINES
|
|
const string SCRIPT_MASTER_OBJECT = "systems.camping.camp_master";
|
|
|
|
//DATATABLE COLUMN DEFINES
|
|
//general item columns
|
|
const string COL_MASTER = "MASTER";
|
|
const string COL_MARKER = "MARKER";
|
|
const string COL_OTHER = "OTHER";
|
|
|
|
//advanced item columns
|
|
const string COL_TEMPLATE = "TEMPLATE";
|
|
const string COL_MIN_MOD = "MIN_MOD";
|
|
|
|
//MESSAGEHANDLER DEFINES
|
|
const string HANDLER_SET_STATUS = "handleSetStatus";
|
|
|
|
const string HANDLER_CAMP_CREATE = "handleCampCreationHeartbeat";
|
|
const string HANDLER_CAMP_MAINTAIN = "handleCampMaintenanceHeartbeat";
|
|
const string HANDLER_CAMP_RESTORE = "handleCampRestoreHeartbeat";
|
|
|
|
const string HANDLER_CAMP_COMPLETE = "handleCampComplete";
|
|
|
|
//DICTIONARY DEFINES
|
|
const string DICT_NEW_STATUS = "newStatus";
|
|
|
|
//SYSTEM MESSAGE DEFINES
|
|
const string_id SID_ABANDONED_CAMP = new string_id("camp", "abandoned_camp");
|
|
const string_id SID_STARTING_CAMP = new string_id("camp", "starting_camp");
|
|
const string_id SID_CAMP_COMPLETE = new string_id("camp", "camp_complete");
|
|
const string_id SID_ASSUMING_OWNERSHIP = new string_id("camp", "assuming_ownership");
|
|
|
|
const string_id SID_ERROR_CAMP_DISBAND = new string_id("camp", "error_camp_disband");
|
|
|
|
const string_id SID_ERROR_DEFAULT = new string_id("camp", "error_default");
|
|
const string_id SID_ERROR_INSIDE = new string_id("camp", "error_inside");
|
|
const string_id SID_ERROR_CAMP_EXISTS = new string_id("camp", "error_camp_exists");
|
|
const string_id SID_ERROR_CAMP_TOO_CLOSE = new string_id("camp", "error_camp_too_close");
|
|
const string_id SID_ERROR_BUILDING_TOO_CLOSE = new string_id("camp", "error_building_too_close");
|
|
const string_id SID_ERROR_LAIR_TOO_CLOSE = new string_id("camp", "error_lair_too_close");
|
|
const string_id SID_ERROR_MUNI_TRUE = new string_id("camp", "error_muni_true");
|
|
const string_id SID_ERROR_NOBUILD = new string_id("camp", "error_nobuild");
|
|
const string_id SID_ERROR_BATTLEFIELD = new string_id("camp", "error_battlefield");
|
|
const string_id SID_ERROR_IN_WATER = new string_id("camp", "error_in_water");
|
|
const string_id SID_ERROR_TOO_CLOSE_TO_WATER = new string_id("camp", "error_too_close_to_water");
|
|
|
|
const string_id SID_ERROR_CAMP_TOO_BIG = new string_id("camp", "error_too_big");
|
|
const string_id SID_CAMP_MASTER_NAME = new string_id("camp", "camp_master");
|
|
|
|
const string_id SID_GENERAL_ITEM_ADDED = new string_id("camp", "general_item_added");
|
|
const string_id SID_ADVANCED_ITEMS_ADDED = new string_id("camp", "advanced_items_added");
|
|
|
|
const string_id SID_CAMP_ENTER = new string_id("camp", "camp_enter");
|
|
const string_id SID_CAMP_EXIT = new string_id("camp", "camp_exit");
|
|
|
|
const string_id PROSE_CAMP_ENTER = new string_id("camp", "prose_camp_enter");
|
|
const string_id PROSE_CAMP_EXIT = new string_id("camp", "prose_camp_exit");
|
|
const string_id SID_RECRUITER_MODULE_ABORTED = new string_id("camp", "recruiter_aborted");
|
|
|
|
|
|
// New camp theaters.
|
|
const string CAMP_THEATERS [] = { "object/building/poi/scout_camp_s0.iff",
|
|
"object/building/poi/scout_camp_s1.iff",
|
|
"object/building/poi/scout_camp_s2.iff",
|
|
"object/building/poi/scout_camp_s3.iff",
|
|
"object/building/poi/scout_camp_s4.iff",
|
|
"object/building/poi/scout_camp_s5.iff" };
|
|
|
|
|
|
const string CAMP_DATATABLE = "datatables/item/camp.iff";
|
|
|
|
|
|
|
|
/***** FUNCTIONS ********************************************************/
|
|
|
|
/*****************************************************************
|
|
* @brief creates the camp
|
|
*
|
|
* @param obj_id creator
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
obj_id createCamp( obj_id creator )
|
|
{
|
|
return createCamp( creator, 1 );
|
|
}
|
|
|
|
obj_id createCamp( obj_id creator, int campPower )
|
|
{
|
|
if ( !isIdValid(creator) )
|
|
return null;
|
|
|
|
location here = utils.findLocInFrontOfTarget(creator, 1.0f);
|
|
if ( here == null )
|
|
{
|
|
sendSystemMessage(creator, new string_id("camp", "bad_location"));
|
|
return null;
|
|
}
|
|
|
|
if ( campPower == 0 )
|
|
campPower = 1; // Not sure how a camp got zero power.
|
|
|
|
if ( canPlaceCampHere( creator, here, campPower ) )
|
|
{
|
|
obj_id master = createCampTheater( here, campPower );
|
|
if ( !isIdValid(master) )
|
|
{
|
|
sendSystemMessage(creator, new string_id("camp", "bad_creation"));
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
setCampOwner( master, creator );
|
|
|
|
setCampMasterName(master);
|
|
|
|
if ( campPower > 4 && factions.isDeclared(creator) )
|
|
{
|
|
string creatorFac = factions.getFaction(creator);
|
|
if ( creatorFac != null )
|
|
{
|
|
factions.setFaction(master, creatorFac);
|
|
attachScript(master, "planet_map.map_loc_attach");
|
|
}
|
|
}
|
|
|
|
int mod_camp = getSkillStatMod( creator, MOD_CAMP );
|
|
int repel = campPower;
|
|
if ( campPower == 1 )
|
|
repel = 0;
|
|
setObjVar( master, VAR_CAMP_REPEL, repel );
|
|
setObjVar( master, VAR_CAMP_POWER, campPower );
|
|
attachScript( master, SCRIPT_MASTER_OBJECT );
|
|
setStatus( master, STATUS_NEW );
|
|
setObjVar( master, VAR_ITEM_IDX, 0 );
|
|
int maxItem = (int)(mod_camp / 20) + 2;
|
|
setObjVar( master, VAR_ITEM_MAX, maxItem );
|
|
sendCampCreationHeartbeat( master );
|
|
|
|
int createTime = getGameTime();
|
|
setObjVar( master, "camp.createTime", createTime );
|
|
|
|
return master;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("camping", "Cannot place camp here...");
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief creates the camp master object
|
|
*
|
|
* @param location here
|
|
* @param int campPower
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
obj_id createCampTheater( location here, int campPower )
|
|
{
|
|
if ( here == null )
|
|
return null;
|
|
return createObject( CAMP_THEATERS[campPower-1], here );
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief creates the camp
|
|
*
|
|
* @param obj_id creator
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
boolean canPlaceCampHere(obj_id creator, location here, int campPower)
|
|
{
|
|
if ( !isIdValid(creator) || (here == null) )
|
|
return false;
|
|
|
|
//inside?
|
|
if (isIdValid(here.cell) || here.area.startsWith("space_"))
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_INSIDE);
|
|
return false;
|
|
}
|
|
|
|
//in another camp?
|
|
obj_id currentCamp = getCurrentCamp(creator);
|
|
if ( currentCamp != null )
|
|
{
|
|
/*
|
|
obj_id campOwner = getCampOwner(currentCamp);
|
|
if ( (campOwner == null) || (campOwner == obj_id.NULL_ID) )
|
|
{
|
|
updateCampOwner(currentCamp, creator);
|
|
sendSystemMessage(creator, SID_ASSUMING_OWNERSHIP);
|
|
}
|
|
else
|
|
{
|
|
*/
|
|
sendSystemMessage(creator, SID_ERROR_CAMP_EXISTS);
|
|
// }
|
|
|
|
return false;
|
|
}
|
|
|
|
// Check for proximity of camps, and buildings.
|
|
if ( isTooCloseToAnotherCamp(here,creator) )
|
|
{
|
|
sendSystemMessage(creator, new string_id("camp", "camp_too_close"));
|
|
return false;
|
|
}
|
|
|
|
if (here.area.equals("mustafar"))
|
|
{
|
|
if (here.x > 1120 || here.z < -1024)
|
|
return false;
|
|
}
|
|
|
|
|
|
if (instance.isInInstanceArea(creator))
|
|
return false;
|
|
|
|
//check regions
|
|
region bf = battlefield.getBattlefield(here);
|
|
if ( bf != null )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_BATTLEFIELD);
|
|
return false;
|
|
}
|
|
|
|
if ( locations.isInMissionCity( here ) )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_MUNI_TRUE);
|
|
return false;
|
|
}
|
|
|
|
if ( isBelowWater( here ) )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_IN_WATER);
|
|
return false;
|
|
}
|
|
|
|
float size = CAMP_SIZE[campPower] + 1.0f;
|
|
if ( isWaterInRect (here.x - size, here.z - size, here.x + size, here.z + size) )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_TOO_CLOSE_TO_WATER);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief destroys the camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return boolean; false on error
|
|
*****************************************************************/
|
|
boolean nukeCamp(obj_id master)
|
|
{
|
|
if ( !isIdValid(master) || !exists( master ) )
|
|
return false;
|
|
|
|
removeTriggerVolume("camp_" + master);
|
|
|
|
obj_id[] players = getPlayerCreaturesInRange(getLocation(master), getCampSize(master));
|
|
if ( (players == null) || (players.length == 0) )
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < players.length; i++ )
|
|
{
|
|
clearCurrentCamp(players[i]);
|
|
}
|
|
}
|
|
|
|
int xpGranted = getIntObjVar(master, VAR_CAMP_XP);
|
|
obj_id owner = getObjIdObjVar(master, VAR_OWNER);
|
|
if ( (owner != null) && (owner != obj_id.NULL_ID) )
|
|
{
|
|
pclib.msgRemoveObjVar(owner, VAR_CAMP_BASE);
|
|
if ( (owner.isLoaded()) && (isInWorld(owner)) )
|
|
{
|
|
//xp.grant( owner, xp.SCOUT, xpGranted );
|
|
|
|
sendSystemMessage(owner, SID_ERROR_CAMP_DISBAND);
|
|
}
|
|
}
|
|
|
|
if ( !destroyObject(master) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief gets current camp scriptvar
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
obj_id getCurrentCamp(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return null;
|
|
|
|
deltadictionary dd = target.getScriptVars();
|
|
obj_id camp = dd.getObjId(VAR_CURRENT_CAMP);
|
|
|
|
// Make sure the ref is valid.
|
|
if ( !isIdValid( camp ) || !exists( camp ) || (getStatus( camp ) == STATUS_ABANDONED) )
|
|
{
|
|
// Invalid camp. clear the ref.
|
|
clearCurrentCamp( target );
|
|
return null;
|
|
}
|
|
|
|
return camp;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sets current camp scriptvar
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean setCurrentCamp(obj_id target, obj_id master)
|
|
{
|
|
if ( !isIdValid(target) || !isIdValid(master) )
|
|
return false;
|
|
|
|
deltadictionary dd = target.getScriptVars();
|
|
dd.put(VAR_CURRENT_CAMP, master);
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief clears current camp scriptvar
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean clearCurrentCamp(obj_id target)
|
|
{
|
|
if ( !isIdValid(target) )
|
|
return false;
|
|
|
|
deltadictionary dd = target.getScriptVars();
|
|
dd.remove(VAR_CURRENT_CAMP);
|
|
return true;
|
|
}
|
|
|
|
float getCampSize( obj_id master )
|
|
{
|
|
int campPower = getIntObjVar( master, VAR_CAMP_POWER ) - 1;
|
|
if ( campPower < 0 )
|
|
campPower = 0;
|
|
return CAMP_SIZE[campPower];
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief determines if there is potential camp overlap
|
|
*
|
|
* @param location here
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean isTooCloseToAnotherCamp(location here,obj_id creator)
|
|
{
|
|
if ( here == null || !isIdValid(creator) )
|
|
return true;
|
|
|
|
float range = 2 * MAX_SIZE + 1;
|
|
obj_id[] objs = getNonCreaturesInRange(here, range);
|
|
if ( (objs == null) || (objs.length == 0) )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
for ( int i = 0; i < objs.length; i++ )
|
|
{
|
|
obj_id item = objs[i];
|
|
// Is it a camp?
|
|
if ( hasObjVar(item, VAR_OWNER) )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_CAMP_TOO_CLOSE);
|
|
return true;
|
|
}
|
|
// Is it a building?
|
|
if ( player_structure.isBuilding( item ) )
|
|
{
|
|
sendSystemMessage(creator, SID_ERROR_BUILDING_TOO_CLOSE);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief returns the current owner of the specified camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
obj_id getCampOwner(obj_id master)
|
|
{
|
|
if ( !isIdValid(master) )
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return getObjIdObjVar(master, VAR_OWNER);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sets the current owner of the specified camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
boolean setCampOwner(obj_id master, obj_id newOwner)
|
|
{
|
|
if ( !isIdValid(master) || !isIdValid(newOwner) )
|
|
return false;
|
|
|
|
setObjVar(master, VAR_OWNER, newOwner);
|
|
setObjVar(newOwner, VAR_PLAYER_CAMP, master);
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief clears the current owner of the specified camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return obj_id; null on error
|
|
*****************************************************************/
|
|
boolean clearCampOwner(obj_id master)
|
|
{
|
|
if ( !isIdValid(master) )
|
|
return false;
|
|
|
|
obj_id owner = getCampOwner(master);
|
|
if ( isIdValid(owner) )
|
|
pclib.msgRemoveObjVar(owner, VAR_PLAYER_CAMP);
|
|
|
|
setObjVar(master, VAR_OWNER, obj_id.NULL_ID);
|
|
return true;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief updates the camp master object when camp gets a new owner
|
|
*
|
|
* @param obj_id master
|
|
* @param obj_id newOwner
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean updateCampOwner(obj_id master, obj_id newOwner)
|
|
{
|
|
setCampOwner(master, newOwner);
|
|
|
|
return setStatus(master, STATUS_MAINTAIN);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief updates the camp master object when camp gets a new owner
|
|
*
|
|
* @param obj_id master
|
|
* @param obj_id newOwner
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean campAbandoned( obj_id master )
|
|
{
|
|
// Grant XP.
|
|
obj_id owner = getCampOwner( master );
|
|
if ( isIdValid( owner ) )
|
|
{
|
|
//int xpAmt = getIntObjVar( master, camping.VAR_CAMP_XP );
|
|
//if ( xpAmt > 0 )
|
|
// xp.grant( owner, xp.SCOUT, xpAmt );
|
|
setObjVar( master, camping.VAR_CAMP_XP, 0 );
|
|
}
|
|
|
|
|
|
setName (master, SID_ABANDONED_CAMP);
|
|
|
|
obj_id[] children = getObjIdArrayObjVar (master, "theater.children");
|
|
if (children == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
int numKids = children.length;
|
|
|
|
for (int x = 0; x < numKids; x ++)
|
|
{
|
|
obj_id thisChild = children[x];
|
|
if (hasScript (thisChild, "systems.camping.camp_controlpanel"))
|
|
{
|
|
setName (thisChild, SID_ABANDONED_CAMP);
|
|
}
|
|
}
|
|
clearCampOwner(master);
|
|
|
|
messageTo(master, "handleNuke", null, 300f, false);
|
|
|
|
return setStatus(master, STATUS_ABANDONED);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief gets the current camp status
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return int
|
|
*****************************************************************/
|
|
int getStatus(obj_id master)
|
|
{
|
|
if ( !isIdValid(master) )
|
|
return STATUS_UNKNOWN;
|
|
|
|
return getIntObjVar(master, VAR_STATUS);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sets the current camp status
|
|
*
|
|
* @param obj_id master
|
|
* @param int newStatus
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean setStatus(obj_id master, int newStatus)
|
|
{
|
|
if ( !isIdValid(master) )
|
|
return false;
|
|
|
|
dictionary d = new dictionary();
|
|
d.put(DICT_NEW_STATUS, newStatus);
|
|
messageTo(master, HANDLER_SET_STATUS, d, 0, false);
|
|
|
|
return setObjVar(master, VAR_STATUS, newStatus);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief checks if the owner is within the camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return boolean
|
|
*****************************************************************/
|
|
boolean isOwnerInVicinity( obj_id master )
|
|
{
|
|
return getBooleanObjVar( master, VAR_OWNER_NEAR );
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sends the camp creation heartbeat
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return void
|
|
*****************************************************************/
|
|
void sendCampCreationHeartbeat(obj_id master)
|
|
{
|
|
messageTo(master, HANDLER_CAMP_CREATE, null, HEARTBEAT_CREATION, false);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sends the camp creation heartbeat
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return void
|
|
*****************************************************************/
|
|
void sendCampCreationComplete(obj_id master)
|
|
{
|
|
messageTo(master, HANDLER_CAMP_COMPLETE, null, HEARTBEAT_CREATION, false);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sends the camp maintenance heartbeat
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return void
|
|
*****************************************************************/
|
|
void sendCampMaintenanceHeartbeat(obj_id master)
|
|
{
|
|
messageTo(master, HANDLER_CAMP_MAINTAIN, null, HEARTBEAT_MAINTAIN, false);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief sends the camp creation heartbeat
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return void
|
|
*****************************************************************/
|
|
void sendCampRestoreHeartbeat(obj_id master)
|
|
{
|
|
messageTo(master, HANDLER_CAMP_RESTORE, null, HEARTBEAT_RESTORE, false);
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief makes a camping skill roll
|
|
*
|
|
* @param obj_id owner
|
|
*
|
|
* @return int (skill roll delta)
|
|
*****************************************************************/
|
|
int campingSkillCheck(obj_id owner)
|
|
{
|
|
int roll = rand(0, 100);
|
|
//debugSpeakMsg(owner, "campingSkillCheck: roll = " + roll);
|
|
int chanceSuccess = getSkillStatMod(owner, MOD_CAMP); //get skill level here
|
|
int delta = chanceSuccess - roll;
|
|
//debugSpeakMsg(owner, "campingSkillCheck: delta = " + delta);
|
|
return delta;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief attempts to set the camp master objects name
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return boolean; false on error
|
|
*****************************************************************/
|
|
void setCampMasterName(obj_id master)
|
|
{
|
|
if ( isIdValid(master) )
|
|
{
|
|
setName( master, "" );
|
|
setName(master, SID_CAMP_MASTER_NAME);
|
|
}
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief returns the value of the camp repel val; 0 for not in camp
|
|
*
|
|
* @param obj_id target
|
|
*
|
|
* @return int; -1 on error
|
|
*****************************************************************/
|
|
int getCampRepelValue(obj_id target)
|
|
{
|
|
if ( isIdValid(target) )
|
|
return -1;
|
|
|
|
obj_id master = getCurrentCamp(target);
|
|
if ( !isIdValid(master) )
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
int val = getIntObjVar(master, VAR_CAMP_REPEL);
|
|
return val;
|
|
}
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief returns true if the npc should be repelled by the player.
|
|
*
|
|
* @param obj_id npc
|
|
* @param obj_id player
|
|
*
|
|
* @return bool results
|
|
*****************************************************************/
|
|
boolean repelledByCamp( obj_id npc, obj_id player )
|
|
{
|
|
// Validate vars.
|
|
if ( !isIdValid(npc) )
|
|
return false;
|
|
if ( !isIdValid(player) )
|
|
return false;
|
|
|
|
// If the player isn't in a camp, we don't repel.
|
|
obj_id camp = getCurrentCamp( player );
|
|
if ( !isIdValid(camp) )
|
|
return false;
|
|
|
|
// Repel is the camp power.
|
|
int repel = getIntObjVar( camp, VAR_CAMP_REPEL );
|
|
int maxlevel = (repel-2)*15 + 20;
|
|
if ( ai_lib.getLevel( npc ) <= maxlevel )
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************
|
|
* @brief gets heal modifier for this camp
|
|
*
|
|
* @param obj_id master
|
|
*
|
|
* @return float heal modifier
|
|
*****************************************************************/
|
|
float getCampHealModifier( obj_id master )
|
|
{
|
|
int campPower = getIntObjVar( master, VAR_CAMP_POWER );
|
|
|
|
switch ( campPower )
|
|
{
|
|
case 1:
|
|
return 0.65f;
|
|
case 2:
|
|
return 0.65f;
|
|
case 3:
|
|
return 0.75f;
|
|
case 4:
|
|
return 0.85f;
|
|
case 5:
|
|
return 0.95f;
|
|
case 6:
|
|
return 1.0f;
|
|
default:
|
|
return 0.65f;
|
|
}
|
|
}
|
|
|
|
boolean isRecruiterModule(string module_template)
|
|
{
|
|
if ( (module_template == "object/building/poi/player_camp_imperial_recruiter.iff")
|
|
|| (module_template == "object/building/poi/player_camp_rebel_recruiter.iff") )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
boolean validateRecruiter(obj_id player, string module_template, int recruitersPlaced)
|
|
{
|
|
if (!isRecruiterModule(module_template))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
string playerFaction = factions.getFaction(player);
|
|
if ( playerFaction == null || playerFaction == "")
|
|
{
|
|
if (recruitersPlaced == 0)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( playerFaction.equals(factions.FACTION_IMPERIAL) )
|
|
{
|
|
if (module_template == "object/building/poi/player_camp_imperial_recruiter.iff")
|
|
{
|
|
if (recruitersPlaced == 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( playerFaction.equals(factions.FACTION_REBEL) )
|
|
{
|
|
if (module_template == "object/building/poi/player_camp_rebel_recruiter.iff")
|
|
{
|
|
if (recruitersPlaced == 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/*****************************************************************
|
|
***
|
|
*** ADVANCED CAMP FUNCTIONALITY
|
|
***
|
|
*****************************************************************/
|
|
|
|
void initializeAdvancedCamp(obj_id deed, obj_id camp, obj_id player, location loc)
|
|
{
|
|
setObjVar(camp, VAR_OWNER, player);
|
|
attachScript(camp, "item.camp.camp_advanced");
|
|
|
|
string name = getFirstName(player);
|
|
name += "'s Camp";
|
|
|
|
setName(camp, name);
|
|
|
|
int numNodes = getAdvancedCampNumberOfNodes(camp);
|
|
if(numNodes > 6)
|
|
numNodes = 6;
|
|
|
|
obj_id[] nodeObjects = new obj_id[numNodes];
|
|
int arrayIdx = 0;
|
|
|
|
obj_var_list ovl = getObjVarList(deed, "modules");
|
|
|
|
float lifetime = 0f;
|
|
lifetime += ovl.getFloatObjVar("lifetime");
|
|
|
|
int recruitersPlaced = 0;
|
|
if(ovl != null)
|
|
{
|
|
string[] modules = ovl.getAllObjVarNames();
|
|
|
|
if(modules != null && modules.length > 0)
|
|
{
|
|
int nodeCount = 1;
|
|
int i = 0;
|
|
|
|
while(nodeCount <= numNodes && i < modules.length)
|
|
{
|
|
if(modules[i] != null && !modules[i].equals(""))
|
|
{
|
|
if(ovl.getFloatObjVar(modules[i]) != 0.0f)
|
|
{
|
|
location tempLoc = loc;
|
|
location nodeLoc = getAdvancedCampNodeLocation(camp, tempLoc, nodeCount);
|
|
int nodeYaw = getAdvancedCampNodeYaw(camp, nodeCount);
|
|
|
|
string module_template = "";
|
|
|
|
if(modules[i].equals("shuttle_beacon"))
|
|
module_template = "object/building/poi/player_camp_shuttle_beacon.iff";
|
|
else if(modules[i].equals("cloning_tube"))
|
|
module_template = "object/building/poi/player_camp_clone_tube.iff";
|
|
else if(modules[i].equals("entertainer"))
|
|
module_template = "object/building/poi/player_camp_entertainment_area.iff";
|
|
else if(modules[i].equals("junk_dealer"))
|
|
module_template = "object/building/poi/player_camp_junk_dealer.iff";
|
|
else if(modules[i].equals("clothing_station"))
|
|
module_template = "object/building/poi/player_camp_crafting_clothing.iff";
|
|
else if(modules[i].equals("food_station"))
|
|
module_template = "object/building/poi/player_camp_crafting_food.iff";
|
|
else if(modules[i].equals("ship_station"))
|
|
module_template = "object/building/poi/player_camp_crafting_space.iff";
|
|
else if(modules[i].equals("structure_station"))
|
|
module_template = "object/building/poi/player_camp_crafting_structure.iff";
|
|
else if(modules[i].equals("weapon_station"))
|
|
module_template = "object/building/poi/player_camp_crafting_weapon.iff";
|
|
else if(modules[i].equals("imperial"))
|
|
module_template = "object/building/poi/player_camp_imperial_recruiter.iff";
|
|
else if(modules[i].equals("rebel"))
|
|
module_template = "object/building/poi/player_camp_rebel_recruiter.iff";
|
|
else if(modules[i].equals("extra_life"))
|
|
{
|
|
module_template = "object/static/structure/corellia/corl_power_transformer_s01.iff";
|
|
lifetime += ovl.getFloatObjVar("extra_life");
|
|
|
|
}
|
|
|
|
if(!module_template.equals(""))
|
|
{
|
|
if (validateRecruiter(player, module_template, recruitersPlaced))
|
|
{
|
|
obj_id module_id = create.object(module_template, nodeLoc);
|
|
if (isRecruiterModule(module_template))
|
|
{
|
|
recruitersPlaced = recruitersPlaced +1;
|
|
}
|
|
if(isIdValid(module_id))
|
|
{
|
|
setYaw(module_id, nodeYaw);
|
|
setName(module_id, name);
|
|
copyObjVar(deed, module_id, "modules." + modules[i]);
|
|
|
|
nodeObjects[arrayIdx] = module_id;
|
|
arrayIdx++;
|
|
|
|
nodeCount++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sendSystemMessage(player, SID_RECRUITER_MODULE_ABORTED);
|
|
} }
|
|
}
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
copyObjVar(deed, camp, "modules");
|
|
}
|
|
}
|
|
setObjVar(camp, "modules.ids", nodeObjects);
|
|
setObjVar(camp, VAR_LIFETIME, lifetime);
|
|
setObjVar(camp, VAR_CREATION_TIME, getCalendarTime());
|
|
|
|
messageTo(camp, "handleControlTerminalLocation", null, 10f, false);
|
|
messageTo(camp, "handleCampDecay", null, lifetime, false);
|
|
}
|
|
|
|
float getAdvancedCampRadius(obj_id camp)
|
|
{
|
|
string filename = utils.getTemplateFilenameNoPath(camp);
|
|
return dataTableGetFloat(CAMP_DATATABLE, filename, "radius");
|
|
}
|
|
|
|
int getAdvancedCampNumberOfNodes(obj_id camp)
|
|
{
|
|
string filename = utils.getTemplateFilenameNoPath(camp);
|
|
return dataTableGetInt(CAMP_DATATABLE, filename, "nodes");
|
|
}
|
|
|
|
int getAdvancedCampNodeYaw(obj_id camp, int node)
|
|
{
|
|
string filename = utils.getTemplateFilenameNoPath(camp);
|
|
string yawCol = "yaw" + node;
|
|
|
|
return dataTableGetInt(CAMP_DATATABLE, filename, yawCol);
|
|
}
|
|
|
|
location getAdvancedCampNodeLocation(obj_id camp, location loc, int node)
|
|
{
|
|
string filename = utils.getTemplateFilenameNoPath(camp);
|
|
|
|
string xCol = "x" + node;
|
|
string zCol = "z" + node;
|
|
|
|
float x = dataTableGetFloat(CAMP_DATATABLE, filename, xCol);
|
|
float z = dataTableGetFloat(CAMP_DATATABLE, filename, zCol);
|
|
|
|
loc.x += x;
|
|
loc.z += z;
|
|
|
|
return loc;
|
|
}
|
|
|
|
obj_id getCurrentAdvancedCamp(obj_id player)
|
|
{
|
|
obj_id[] objects = getNonCreaturesInRange(player, 25.0f);
|
|
|
|
if(objects == null || objects.length == 0)
|
|
return null;
|
|
|
|
for(int i = 0; i < objects.length; i++)
|
|
{
|
|
if(hasScript(objects[i], "item.camp.camp_advanced"))
|
|
{
|
|
if(isInTriggerVolume(objects[i], "campsite", player))
|
|
return objects[i];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
boolean isInEntertainmentCamp(obj_id player)
|
|
{
|
|
return isInEntertainmentCamp(player, obj_id.NULL_ID);
|
|
}
|
|
|
|
boolean isInEntertainmentCamp(obj_id player, obj_id camp)
|
|
{
|
|
if(!isIdValid(camp))
|
|
camp = getCurrentAdvancedCamp(player);
|
|
|
|
if(!isIdValid(camp))
|
|
return false;
|
|
|
|
if(hasObjVar(camp, "modules.entertainer"))
|
|
return true;
|
|
|
|
return false;
|
|
}
|