/** * 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 = (location)loc.clone(); 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; }