mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-31 00:15:54 -04:00
1318 lines
34 KiB
Plaintext
1318 lines
34 KiB
Plaintext
/**
|
|
* Title: scenario.scriptlib
|
|
* Description: scriptlib for handling complex POI (scenario) functions
|
|
*/
|
|
|
|
/***** 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++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|