/** * Copyright (c) ©2000,2001 Sony Online Entertainment Inc. * All Rights Reserved * * Title: scenario.scriptlib * Description: scriptlib for handling complex POI (scenario) functions * @author $Author: rpalacio $ * @version $Revision: #1 $ */ /***** INCLUDES ********************************************************/ include library.factions; include library.poi; include library.utils; include library.chat; include library.group; include library.combat; include library.ai_lib; include ai.ai_combat; /***** CONSTANTS *******************************************************/ //ACTOR CONSTS const string MEDIATOR = "mediator"; const string ANTAGONIST = "antagonist"; //SCENARIO OBJVARS const string VAR_SCENARIO_BASE = "scenario"; //OBJVARS on MASTER const string VAR_SCENARIO_IDX = VAR_SCENARIO_BASE + ".idx"; const string VAR_SCENARIO_NAME = VAR_SCENARIO_BASE + ".name"; const string VAR_SCENARIO_CONVO = VAR_SCENARIO_BASE + ".convo"; const string VAR_SCENARIO_PLAYERS = VAR_SCENARIO_BASE + ".players"; const string VAR_TEAM = VAR_SCENARIO_BASE + ".team"; const string VAR_SCENARIO_MEDIATOR_TYPE = VAR_SCENARIO_BASE + ".mediator_type"; const string VAR_SCENARIO_ANTAGONIST_TYPE = VAR_SCENARIO_BASE + ".antagonist_type"; const string VAR_MEDIATOR_COUNT = VAR_SCENARIO_BASE + ".mediator_count"; const string VAR_ANTAGONIST_COUNT = VAR_SCENARIO_BASE + ".antagonist_count"; const string VAR_MEDIATOR_LOC = VAR_SCENARIO_BASE + ".mediator_loc"; const string VAR_ANTAGONIST_LOC = VAR_SCENARIO_BASE + ".antagonist_loc"; const string VAR_SCENARIO_DEAD = VAR_SCENARIO_BASE + ".dead"; const string VAR_SCENARIO_DEAD_ANTAGONIST = VAR_SCENARIO_BASE + ".antagonist_dead"; const string VAR_SCENARIO_DEAD_MEDIATOR = VAR_SCENARIO_BASE + ".mediator_dead"; const string VAR_SCENARIO_COMPLETE = VAR_SCENARIO_BASE + ".complete"; //OBJVARS on ACTORS const string VAR_TARGET_LOCATION = VAR_SCENARIO_BASE + ".targetLoc"; const string VAR_TARGET_LOCATION_NAME = VAR_SCENARIO_BASE + ".targetLocName"; const string VAR_MY_NAME = VAR_SCENARIO_BASE + ".myName"; const string VAR_RANK = VAR_SCENARIO_BASE + ".rank"; const string VAR_HAS_ARRIVED = VAR_SCENARIO_BASE + ".hasArrived"; const string VAR_PRIMARY_KILLERS = VAR_SCENARIO_BASE + ".primaryKillers"; //OBJVARS on PLAYER const string VAR_PROGRESS = "progress"; //MESSAGEHANDLER DEFINES const string HANDLER_INIT_SCENARIO = "initScenario"; const string HANDLER_RUN_SCENARIO = "runScenario"; const string HANDLER_CLEANUP_SCENARIO = "cleanupScenario"; const string HANDLER_DESTROY_SELF = "destroySelf"; const string HANDLER_TIMER = "handleTimer"; const string HANDLER_PREP_TIMER = "handlePrepTimer"; const string HANDLER_ATTACK_TIMER = "handleAttackTimer"; const string HANDLER_FOLLOW_TIMER = "handleFollowTimer"; const string HANDLER_CHARGE = "handleCharge"; const string HANDLER_ENEMY_ATTACK = "handleEnemyAttack"; const string HANDLER_INCAPACITATION = "handleIncapacitation"; const string HANDLER_MY_DEATH = "handleMyDeath"; const string HANDLER_ACTOR_DEATH = "handleActorDeath"; const string HANDLER_VICTORY = "handleVictory"; const string HANDLER_ADD_TARGET_LOCATION = "handleAddTargetLocation"; const string HANDLER_ONLINE_STATUS_UPDATE = "handleOnlineStatusUpdate"; //PROGRESS DEFINES const int NOT_STARTED = 0; //DATATABLE COLUMN DEFINES const string COL_NAME = "SCENARIO_NAME"; const string COL_MEDIATOR = "MEDIATOR_TEMPLATE"; const string COL_MEDIATOR_MINION = "MEDIATOR_MINION_TEMPLATE"; const string COL_MEDIATOR_STRUCTURE = "MEDIATOR_STRUCTURE_TEMPLATE"; const string COL_ANTAGONIST = "ANTAGONIST_TEMPLATE"; const string COL_ANTAGONIST_MINION = "ANTAGONIST_MINION_TEMPLATE"; const string COL_ANTAGONIST_STRUCTURE = "ANTAGONIST_STRUCTURE_TEMPLATE"; const string COL_CONTENDED = "CONTENDED"; const string COL_CONVO = "CONVO_FILE"; const string COL_TOOL = "TOOL"; const string COL_TABLE = "DATATABLE"; const string COL_RING_MIN = "RING_MIN"; const string COL_RING_MAX = "RING_MAX"; const string COL_THEATER = "THEATER"; //KEYWORD DEFINES const string KEY_RANDOM = "random"; const string KEY_NONE = "none"; const string KEY_UNKNOWN = "unknown"; //DICTIONARY DEFINES const string DICT_IDX = "idx"; const string DICT_LOC_NAME = "locName"; const string DICT_LOCATION = "location"; const string DICT_RADIUS = "radius"; const string DICT_NAME = "name"; const string DICT_OBJID = "objid"; const string DICT_STATUS = "status"; //SCENARIO RANK DEFINES const int SR_MEDIATOR = 0; const int SR_ANTAGONIST = 1; const int SR_MEDIATOR_MINION = 2; const int SR_ANTAGONIST_MINION = 3; //SCNEARIO ONLINE STATUS DEFINES const int OFFLINE = 0; const int ONLINE = 1; //DEFAULT DEFINES const string DEFAULT_CONVO = "poi/default"; //CONCLUSION FLAGS const string VAR_UNLOAD_NUKE = "nukeOnUnload"; /***** FUNCTIONS *******************************************************/ /***** SCENARIO SETUP FUNCTIONS ****************************************/ /************************************************************************ * @brief initializes a scenario * * @param obj_id master * @param string tbl * * @return boolean; false on error ***********************************************************************/ boolean initScenario(obj_id master, string tbl) { if ( !isIdValid(master) || tbl == null || tbl.equals("") ) return false; dictionary params = getRandomScenario(tbl); if ( (params == null) || (params.isEmpty()) ) return false; int idx = params.getInt(DICT_IDX); string scenario_name = params.getString(COL_NAME); string convo = params.getString(COL_CONVO); if (hasObjVar(master, VAR_SCENARIO_BASE)) removeObjVar(master, VAR_SCENARIO_BASE); setObjVar(master, VAR_SCENARIO_IDX, idx); setObjVar(master, VAR_SCENARIO_NAME, scenario_name); setObjVar(master, VAR_SCENARIO_CONVO, convo); return messageTo (master, HANDLER_INIT_SCENARIO, params, 2, true); } /***** SCENARIO NPC/TEAM FUNCTIONS ****************************************/ /************************************************************************ * @brief creates a scenario team * * @param obj_id master * @param string team_name * @param string team_faction * * @return boolean; false on error ***********************************************************************/ boolean createTeam(obj_id master, string team_name, string team_faction) { if ( !isIdValid(master) ) return false; if ( (team_name == null) || (team_name.equals("")) ) return false; if ( (team_faction == null) || (team_faction.equals("")) ) return false; string team_path = VAR_TEAM + "." + team_name; setObjVar(master, team_path + ".faction", team_faction); setObjVar(master, team_path + ".dead_count", 0); /* resizeable obj_id[] team_members = new obj_id[0]; resizeable int[] member_alive = new int[0]; setObjVar(master, team_path + ".members", team_members); setObjVar(master, team_path + ".member_alive", member_alive); */ setObjVarList(master, team_path + ".kill_credits"); return true; } /************************************************************************ * @brief sets a scenario team's faction * * @param obj_id master * @param string team_name * @param string team_faction * * @return boolean; false on error ***********************************************************************/ boolean setTeamFaction(obj_id master, string team_name, string team_faction) { if ( !isIdValid(master) ) return false; if ( (team_name == null) || (team_name.equals("")) ) return false; if ( (team_faction == null) || (team_faction.equals("")) ) return false; string team_path = VAR_TEAM + "." + team_name; string member_path = team_path + ".members"; resizeable obj_id[] team_members = getResizeableObjIdArrayObjVar(master, member_path); if ( team_members != null && team_members.length > 0 ) { for (int i = 0; i < team_members.length; i++) { obj_id target = team_members[i]; if ( isIdValid(target) ) { factions.setFaction(target, team_faction); } } } return setObjVar(master, team_path + ".faction", team_faction); } /************************************************************************ * @brief gets a scenario team's faction * * @param obj_id master * @param string team_name * * @return string; null on error ***********************************************************************/ string getTeamFaction(obj_id master, string team_name) { if ( !isIdValid(master) ) return null; if ( (team_name == null) || (team_name.equals("")) ) return null; string team_path = VAR_TEAM + "." + team_name; string fac_path = team_path + ".faction"; return getStringObjVar(master, VAR_TEAM+"."+team_name+".faction"); } /************************************************************************ * @brief handles actor incapacitation * * @param obj_id master * @param string team_name * @param string type * @param location here * * @return obj_id; null on error ***********************************************************************/ obj_id createTeamNpc(obj_id master, string team_name, string type, string ident, location here) { if ( !isIdValid(master) || here == null || type == null || type.equals("") ) return null; if ( team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; //obj_var_list members = getObjVarList(master, VAR_TEAM + "." + team_name + ".members"); resizeable obj_id[] team_members = getResizeableObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); resizeable int[] member_alive = getResizeableIntArrayObjVar(master, VAR_TEAM + "." + team_name + ".member_alive"); if ( (ident == null) || (ident.equals("")) ) { if ( team_members == null ) { ident = team_name + "_0"; } else { ident = team_name + team_members.length; } } obj_id npc = poi.createNpc(master, ident, type, here); if ( !isIdValid(npc) ) return null; setObjVar(npc, VAR_TEAM, team_name); string team_faction = getTeamFaction(master, team_name); if ( (team_faction != null) && (!team_faction.equals("")) ) { string oldFaction = factions.getFaction( npc ); if ( (oldFaction == null) || ((oldFaction != "Imperial") && (oldFaction != "Rebel")) ) factions.setFaction( npc, team_faction ); } team_members = utils.addElement(team_members, npc); member_alive = utils.addElement(member_alive, 1); if ( team_members != null && team_members.length > 0 && member_alive != null && member_alive.length > 0 ) { setObjVar(master, VAR_TEAM + "." + team_name + ".members", team_members); setObjVar(master, VAR_TEAM + "." + team_name + ".member_alive", member_alive); } faceTo(npc, master); return npc; } /************************************************************************ * @brief gets a scenario actor's team * * @param obj_id actor * * @return string; null on error ***********************************************************************/ string getTeamName(obj_id actor) { if ( !isIdValid(actor) ) return null; if ( exists(actor) && actor.isLoaded() ) { return getStringObjVar(actor, VAR_TEAM); } else { obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) { return null; } obj_var_list teamsList = getObjVarList(master, VAR_TEAM); if ( teamsList != null ) { int teamCount = teamsList.getNumItems(); for ( int i = 0; i < teamCount; i++ ) { obj_var ov = teamsList.getObjVar(i); obj_var_list team = (obj_var_list)(ov); if ( team != null ) { if ( team.hasObjVar("members." + actor) ) { return team.getName(); } } } } } return null; } /************************************************************************ * @brief gets a scenario actor's team * * @param obj_id actor * * @return string; null on error ***********************************************************************/ boolean isActorAlive(obj_id actor) { if ( !isIdValid(actor) ) return false; obj_id master = poi.getBaseObject(getSelf()); if ( !isIdValid(master) ) return false; string team_name = getTeamName(actor); resizeable obj_id[] team_members = getResizeableObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); int idx = findTeamMember(team_members, actor); if (idx != -1) { resizeable int[] member_alive = getResizeableIntArrayObjVar(master, VAR_TEAM + "." + team_name + ".member_alive"); return (member_alive[idx] == 1); } return false; } /************************************************************************ * @brief sets actor's tracking data to dead * * @param obj_id actor * * @return boolean; false on error ***********************************************************************/ boolean setActorDead(obj_id actor, obj_id[] killers) { if ( !isIdValid(actor) ) return false; obj_id master = poi.getBaseObject(getSelf()); if ( !isIdValid(master) ) return false; string team_name = getTeamName(actor); resizeable obj_id[] team_members = getResizeableObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); if ( team_members == null || team_members.length == 0 ) return false; int idx = findTeamMember(team_members, actor); if (idx != -1) { resizeable int[] member_alive = getResizeableIntArrayObjVar(master, VAR_TEAM + "." + team_name + ".member_alive"); if(member_alive != null && member_alive.length > 0) { member_alive[idx] = 0; setObjVar(master, VAR_TEAM + "." + team_name + ".member_alive", member_alive); } else { return false; } grantKillCredit(master, team_name, killers); return true; } return false; } boolean setActorDead(obj_id actor) { return setActorDead(actor, null); } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ obj_id[] getTeamMembers(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; return getObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); } obj_id[] getTeamMembers(string team_name) { return getTeamMembers( poi.getBaseObject(getSelf()), team_name ); } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ obj_id[] getAliveTeamMembers(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; obj_id[] team_members = getObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); int[] member_alive = getIntArrayObjVar(master, VAR_TEAM + "." + team_name + ".member_alive"); resizeable obj_id[] members = new obj_id[0]; for ( int i = 0; i < team_members.length; i++ ) { if (member_alive[i] == 1) { members = utils.addElement(members, team_members[i]); } } return members; } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ obj_id[] getDeadTeamMembers(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; obj_id[] team_members = getObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); int[] member_alive = getIntArrayObjVar(master, VAR_TEAM + "." + team_name + ".member_alive"); resizeable obj_id[] members = new obj_id[0]; for ( int i = 0; i < team_members.length; i++ ) { if (member_alive[i] == 0) { members = utils.addElement(members, team_members[i]); } } return members; } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ int getAliveTeamMemberCount(obj_id master, string team_name) { obj_id[] members = getAliveTeamMembers(master, team_name); if ( (members == null) || (members.length == 0) ) return -1; return members.length; } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ int getDeadTeamMemberCount(obj_id master, string team_name) { obj_id[] members = getDeadTeamMembers(master, team_name); if ( (members == null) || (members.length == 0) ) return -1; return members.length; } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ obj_id getRandomTeamMember(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; obj_id[] members = getAliveTeamMembers(master, team_name); if ( (members == null) || (members.length == 0) ) return null; int idx = rand(0, members.length - 1); return members[idx]; } /************************************************************************ * @brief retrieves the ids of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ obj_id getRandomAliveTeamMember(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return null; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return null; obj_id[] members = getAliveTeamMembers(master, team_name); if ( (members == null) || (members.length == 0) ) return null; int idx = rand(0, members.length - 1); return members[idx]; } /************************************************************************ * @brief retrieves the number of members on a team * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ int getTeamCount(obj_id master, string team_name) { if ( !isIdValid(master) || team_name == null || team_name.equals("") ) return -1; if ( !hasObjVar(master, VAR_TEAM + "." + team_name) ) return -1; obj_id[] team_members = getObjIdArrayObjVar(master, VAR_TEAM + "." + team_name + ".members"); if ( (team_members == null) || (team_members.length == 0) ) return -1; return team_members.length; } /************************************************************************ * @brief cycles through team array to find specified member index * * @param obj_id master * * @return int; -1 on error ***********************************************************************/ int findTeamMember(resizeable obj_id[] team, obj_id member) { for (int i = 0; i < team.length; i++) { if (team[i] == member) return i; } return -1; } /************************************************************************ * @brief grants kill credit to killers for the specified team name * * @param obj_id master * * @return boolean; false on error ***********************************************************************/ boolean grantKillCredit(obj_id master, string team_name, obj_id[] killers) { if ( (master == null) || (master == obj_id.NULL_ID) ) { return false; } if ( (team_name == null) || (team_name.equals("")) ) { return false; } if ( (killers == null) || (killers.length == 0) ) { return false; } string creditPath = VAR_TEAM + "." + team_name + ".kill_credits"; for ( int i = 0; i < killers.length; i++ ) { LOG( "SCENARIO", "granting kill credit to " + getName(killers[i]) + " " + team_name ); string path = creditPath + "." + killers[i]; int cnt = 0; if ( hasObjVar(master, path) ) { cnt = getIntObjVar(master, path); } cnt++; setObjVar(master, path, cnt); } return true; } /************************************************************************ * @brief grants kill credit to killers for the specified team name * * @param obj_id master * * @return boolean; false on error ***********************************************************************/ boolean hasKillCredit(obj_id master, string team_name, obj_id killer) { if ( (master == null) || (master == obj_id.NULL_ID) ) { return false; } if ( (team_name == null) || (team_name.equals("")) ) { return false; } if ( (killer == null) || (killer == obj_id.NULL_ID) ) { return false; } string creditPath = VAR_TEAM + "." + team_name + ".kill_credits." + killer; return hasObjVar(master, creditPath); } /***** CONVERSATIONAL FUNCTIONS ****************************************/ /************************************************************************ * @brief attempts to read speech, chat type, and mood from convo file * * @return string; "" on error ***********************************************************************/ string getConvo() { obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) { return ""; } if ( hasObjVar(master, VAR_SCENARIO_CONVO) ) { return getStringObjVar(master, VAR_SCENARIO_CONVO); } return ""; } /************************************************************************ * @brief attempts to read speech, chat type, and mood from convo file * * @param string convo * @param string base_id * * @return boolean; false on error ***********************************************************************/ boolean say(obj_id npc, string convo, string base_id, boolean doAct) { if ( (npc == null) || (npc == obj_id.NULL_ID) || (convo.equals("")) || (base_id.equals("")) ) { return false; } string_id msg = new string_id(convo, base_id); string chatType = getString( new string_id(convo, base_id + "_chat") ); string mood = getString( new string_id(convo, base_id + "_mood") ); string act = getString( new string_id(convo, base_id + "_act") ); if ( (chatType == null) || chatType.equals("") ) { chatType = chat.CHAT_SAY; } if ( (mood == null) || mood.equals("") ) { mood = "none"; } chat.chat(npc, chatType, mood, msg); if ( doAct ) { if ( !act.equals("") ) { queueCommand(npc, ##"social", null, act, COMMAND_PRIORITY_DEFAULT); } } return true; } boolean say(obj_id npc, string convo, string base_id) { return say(npc, convo, base_id, true); } boolean sayNoAct(obj_id npc, string convo, string base_id) { return say(npc, convo, base_id, false); } boolean brainfart(obj_id npc) { return say(npc, DEFAULT_CONVO, "brainfart_" + rand(1,10)); } /************************************************************************ * @brief sets the completion objvar on the poiMaster object * * @param obj_id poiMaster * * @return string; "" on error ***********************************************************************/ boolean complete(obj_id poiMaster) { if ( poiMaster == null ) { return false; } setObjVar(poiMaster, VAR_SCENARIO_COMPLETE, true); poi.complete(poiMaster); return true; } boolean complete() { obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) return false; return complete( master ); } /************************************************************************ * @brief sets the completion objvar on the poiMaster object * * @param obj_id poiMaster * * @return string; "" on error ***********************************************************************/ boolean isComplete(obj_id poiMaster) { if ( poiMaster == null ) { return false; } return getBooleanObjVar(poiMaster, VAR_SCENARIO_COMPLETE); } boolean isComplete() { obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) return false; return isComplete( master ); } /***** PLAYER TRACKING RELATED FUNCTIONS ****************************************/ /***** PLAYER TRACKING FUNCTIONS ****************************************/ /************************************************************************ * @brief set a player as a scenario participant with progress * * @param obj_id player * @param int progress * * @return boolean; false on error ***********************************************************************/ boolean setPlayerProgress(obj_id player, int progress) { if ( (player == null) || (!isPlayer(player)) ) { return false; } obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) { return false; } string path = VAR_SCENARIO_PLAYERS + "." + player; return setObjVar(master, path, progress); } /************************************************************************ * @brief clear a player as a scenario participantd * * @param obj_id player * @param int progress * * @return boolean; false on error ***********************************************************************/ boolean clearPlayerProgress(obj_id player) { if ( (player == null) || (!isPlayer(player)) ) { return false; } obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) { return false; } string path = VAR_SCENARIO_PLAYERS + "." + player; removeObjVar(master, path); return true; } /************************************************************************ * @brief get a player as a scenario participant with progress * * @param obj_id poiMaster * @param obj_id player * @param int progress * * @return int; -1 on error ***********************************************************************/ int getPlayerProgress(obj_id player) { if ( (player == null) || (!isPlayer(player)) ) { return -1; } obj_id self = getSelf(); obj_id master = poi.getBaseObject(self); if ( (master == null) || (master == obj_id.NULL_ID) ) { return -1; } string path = VAR_SCENARIO_PLAYERS + "." + player; return getIntObjVar(master, path); } /***** POI DATA RETRIEVAL FUNCTIONS ********************************/ /************************************************************************ * @brief attempts to retrieve poi objects with the specified name prefix * * @param obj_id poiMaster * @param string prefix * * @return obj_id[]; null on error ***********************************************************************/ obj_id[] getActorsWithNamePrefix(obj_id poiMaster, string prefix) { if ( (poiMaster == null) || (prefix.equals("")) ) { return null; } resizeable obj_id[] actors = new obj_id[0]; if ( hasObjVar(poiMaster, "poi") ) { obj_var_list ovl = getObjVarList(poiMaster, "poi.stringList"); if(ovl != null) { int numItems = ovl.getNumItems(); if ( numItems > 0 ) { for ( int i = 0; i < numItems; i++ ) { obj_var ov = ovl.getObjVar(i); string ovName = ov.getName(); if ( ovName.startsWith(prefix) ) { obj_id tmp = getObjIdObjVar(poiMaster, "poi.stringList." + ovName); if ( (tmp == null) || (tmp == obj_id.NULL_ID) ) { } else { actors = utils.addElement(actors, tmp); } } } } } } if ( (actors == null) || (actors.length == 0) ) { return null; } else { return actors; } } /***** SCENARIO EVENT HANDLING FUNCTIONS ********************************/ /************************************************************************ * @brief cleans up scenario master data as well as requesting player cleanup * * @param obj_id poiMaster * * @return boolean; false on error ***********************************************************************/ boolean cleanup(obj_id poiMaster) { if ( poiMaster == null ) { return false; } /* obj_id[] players = getObjIdArrayObjVar(poiMaster, scenario.VAR_SCENARIO_PLAYERS); if ( (players == null) || (players.length == 0) ) { } else { for ( int i = 0; i < players.length; i++ ) { removePlayer(poiMaster, players[i]); } } */ //messageTo(poiMaster, scenario.HANDLER_DESTROY_SELF, null, 0, true); destroyObject(poiMaster); return true; } /***** DATATABLE ACCESS FUNCTIONS ****************************************/ /************************************************************************ * @brief attempts to retrieve a "random" scenario * * @param string tbl * * @return dictionary; null on error ***********************************************************************/ dictionary getRandomScenario(string tbl) { if ( tbl.equals("") ) { return null; } if ( dataTableOpen(tbl) ) { int numRows = dataTableGetNumRows(tbl); int idx = -1; if ( numRows < 1 ) { return null; } else if ( numRows == 1 ) { idx = 0; } else { idx = rand(0, numRows - 1); } dictionary ret = dataTableGetRow(tbl, idx); if ( ret != null ) { ret.put(DICT_IDX, idx); return ret; } } return null; } /***** ACTOR MESSAGING FUNCTIONS ****************************************/ /************************************************************************ * @brief requests the object add a target location * * @param string tbl * * @return boolean; false on error ***********************************************************************/ boolean requestAddTargetLocation(obj_id target, string locName, location pathLoc, float r) { if ( (target == null) || (locName.equals("")) || (pathLoc == null) || (r < 0) ) { return false; } dictionary d = new dictionary(); d.put(DICT_LOC_NAME, locName); d.put(DICT_LOCATION, pathLoc); d.put(DICT_RADIUS, r); return messageTo(target, HANDLER_ADD_TARGET_LOCATION, d, 0, isObjectPersisted(target)); } /***** DEPRECATED FUNCTIONS ****************************************/ /************************************************************************ * @brief handles actor incapacitation * * @param obj_id self * @param obj_id killer * * @return boolean; false on error ***********************************************************************/ boolean actorIncapacitated(obj_id self) { if ( !isIdValid(self) ) return false; obj_id poiMaster = poi.getBaseObject(self); if ( !isIdValid(poiMaster) ) return false; obj_id[] primaryKillers = getObjIdArrayObjVar(self, VAR_PRIMARY_KILLERS); if ( (primaryKillers == null) || (primaryKillers.length == 0) ) { //sendSystemMessagePlanetTestingOnly("poi: retrived killer array is null!"); } else { for ( int i = 0; i < primaryKillers.length; i++ ) { obj_id pk = primaryKillers[i]; if ( (pk == null) || (pk == obj_id.NULL_ID) ) { //sendSystemMessagePlanetTestingOnly("poi: pk[i] is invalid!!"); } else { if ( isPlayer(pk) ) { obj_id groupId = getGroupObject(pk); if ( isIdValid(groupId) ) { //sendSystemMessagePlanetTestingOnly("poi: granting credit to " + pk); poi.grantCredit(self, pk); } else { obj_id[] members = getGroupMemberIds(groupId); if ( members != null && members.length > 0 ) { for ( int n = 0; i < members.length; i++ ) { //sendSystemMessagePlanetTestingOnly("poi: granting credit to group member " + members[n]); poi.grantCredit(self, members[n]); } } } } else { if ( group.isGroupObject(pk) ) { obj_id[] members = getGroupMemberIds(pk); if ( (members == null) || (members.length == 0) ) { } else { for ( int n = 0; i < members.length; i++ ) { //sendSystemMessagePlanetTestingOnly("poi: granting credit to group member " + members[n]); poi.grantCredit(self, members[n]); } } } else { //sendSystemMessagePlanetTestingOnly("poi: primary killer is not PC or group object!"); } } } } } string myName = getStringObjVar(self, VAR_MY_NAME); if ( !myName.equals("") ) { dictionary d = new dictionary(); d.put(DICT_NAME, myName); d.put(DICT_OBJID, self); messageTo(poiMaster, HANDLER_ACTOR_DEATH, d, 0, true); return true; } return false; } /************************************************************************ * @brief handles same faction group attack * * @param obj_id self * @param obj_id target * * @return void ***********************************************************************/ void groupAttack(obj_id self, obj_id target) { startCombat(self, target); } /************************************************************************ * @brief faces all scenario actors of the prefix type to the target * * @param obj_id self * @param obj_id target * @param string prefix * * @return void ***********************************************************************/ void groupFace(obj_id self, obj_id target, string prefix) { obj_id poiMaster = poi.getBaseObject(self); if ( isIdValid(poiMaster) ) { obj_id[] members = getActorsWithNamePrefix(poiMaster, prefix); if ( (members == null) || (members.length == 0) ) { } else { for ( int i = 0; i < members.length; i++ ) { faceTo(members[i], target); } } } faceTo(self, target); } /************************************************************************ * @brief forms all scenario actors of the prefix type as wedge on formTarget * * @param obj_id self * @param obj_id target * @param string prefix * * @return void ***********************************************************************/ void groupFollow(obj_id leader, obj_id formTarget, string prefix) { obj_id poiMaster = poi.getBaseObject(leader); if ( isIdValid(poiMaster) ) { int formation = rand(0,1); obj_id[] members = getActorsWithNamePrefix(poiMaster, prefix); if ( (members == null) || (members.length == 0) ) { } else { int pos = 1; for ( int i = 0; i < members.length; i++ ) { if ( (members[i] == leader) && (leader != formTarget) ) { ai_lib.aiFollow(leader, formTarget); } else { //ai_lib.aiFollow(members[i], leader); ai_lib.followInFormation(members[i], leader, formation, pos); pos++; } } } } }