mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-07-29 23:15:55 -04:00
4054 lines
126 KiB
Plaintext
4054 lines
126 KiB
Plaintext
/**********************************************************************
|
|
* Copyright (c)2000-2002 Sony Online Entertainment Inc.
|
|
* All Rights Reserved
|
|
*
|
|
* Title: battlefield.scriptlib
|
|
* Description: Library for battlefields
|
|
* @author $Author:$
|
|
* @version $Revision:$
|
|
**********************************************************************/
|
|
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
include library.factions;
|
|
include library.player_structure;
|
|
include library.pet_lib;
|
|
include library.create;
|
|
include library.utils;
|
|
include java.lang.Math;
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
const string BATTLEFIELD_DATATABLE = "datatables/battlefield/battlefield.iff";
|
|
const string BATTLEFIELD_MARKER_DATATABLE = "datatables/battlefield/marker.iff";
|
|
const string BUILDABLE_STRUCTURE_DATATABLE = "datatables/battlefield/buildable_structure.iff";
|
|
const string SPAWNER_DATATABLE = "datatables/battlefield/spawner.iff";
|
|
const string BATTLEFIELD_MARKER = "object/static/structure/tatooine/antenna_tatt_style_1.iff";
|
|
|
|
// Battlefield datatable
|
|
const string DATATABLE_COL_NAME = "battlefield";
|
|
const string DATATABLE_COL_AREA = "area";
|
|
const string DATATABLE_COL_TYPE = "type";
|
|
const string DATATABLE_COL_X1 = "x1";
|
|
const string DATATABLE_COL_Y1 = "y1";
|
|
const string DATATABLE_COL_Z1 = "z1";
|
|
const string DATATABLE_COL_RADIUS = "radius";
|
|
const string DATATABLE_COL_GAME_TYPE = "gameType";
|
|
const string DATATABLE_COL_RESTART_MIN = "restartMin";
|
|
const string DATATABLE_COL_RESTART_MAX = "restartMax";
|
|
const string DATATABLE_COL_GAME_TIME = "gameTime";
|
|
const string DATATABLE_COL_IMPERIAL = "Imperial";
|
|
const string DATATABLE_COL_REBEL = "Rebel";
|
|
const string DATATABLE_COL_HUTT = "Hutt";
|
|
const string DATATABLE_COL_OBJECT = "object";
|
|
const string DATATABLE_COL_OBJECT_X = "object_x";
|
|
const string DATATABLE_COL_OBJECT_Y = "object_y";
|
|
const string DATATABLE_COL_OBJECT_Z = "object_z";
|
|
const string DATATABLE_COL_OBJECT_DELTA = "object_delta";
|
|
const string DATATABLE_COL_HEADING = "heading";
|
|
const string DATATABLE_COL_FACTION = "faction";
|
|
const string DATATABLE_COL_STRUCTURE_TYPE = "structure_type";
|
|
const string DATATABLE_COL_CRITICAL = "gameCritical";
|
|
const string DATATABLE_COL_VALUE1 = "value1";
|
|
const string DATATABLE_COL_VALUE2 = "value2";
|
|
const string DATATABLE_COL_SCRIPT = "script";
|
|
|
|
// Buildable structure
|
|
const string DATATABLE_COL_BUILDING_NAME = "name";
|
|
const string DATATABLE_COL_TEMPLATE = "template";
|
|
const string DATATABLE_COL_BUILD_COST = "cost";
|
|
|
|
// Spawner data
|
|
const string DATATABLE_COL_SPAWNER_TYPE = "type";
|
|
const string DATATABLE_COL_SPAWNER_PULSE = "pulse";
|
|
const string DATATABLE_COL_SPAWNER_MAX_SPAWN = "max_spawn";
|
|
const string DATATABLE_COL_SPAWNER_MAX_POPULATION = "max_population";
|
|
const string DATATABLE_COL_SPAWNER_TEMPLATE = "spawn_template";
|
|
const string DATATABLE_COL_SPAWNER_MIN_NUMBER = "min_number";
|
|
const string DATATABLE_COL_SPAWNER_MAX_NUMBER = "max_number";
|
|
const string DATATABLE_COL_SPAWNER_WEIGHT = "weight";
|
|
|
|
// Scripts
|
|
const string SCRIPT_BATTLEFIELD_REGION = "systems.battlefield.battlefield_region";
|
|
const string SCRIPT_PLAYER_BATTLEFIELD = "systems.battlefield.player_battlefield";
|
|
const string SCRIPT_BATTLEFIELD_OBJECT = "systems.battlefield.battlefield_object";
|
|
const string SCRIPT_DESTRUCTIBLE_BUILDING = "systems.battlefield.destructible_building";
|
|
const string SCRIPT_DESTROY_OBJECTIVE = "systems.battlefield.destroy_objective";
|
|
const string SCRIPT_BATTLEFIELD_CONSTRUCTOR = "systems.battlefield.battlefield_constructor";
|
|
const string SCRIPT_BARRACKS = "systems.battlefield.barracks";
|
|
const string SCRIPT_BATTLEFIELD_SPAWNER = "systems.battlefield.battlefield_spawner";
|
|
const string SCRIPT_FACTION_ITEM = "npc.faction_recruiter.faction_item";
|
|
|
|
// objvars ---
|
|
// Master object/region
|
|
const string VAR_BATTLEFIELD = "battlefield";
|
|
const string VAR_NAME = "battlefield.name";
|
|
const string VAR_PLANET = "battlefield.planet";
|
|
const string VAR_VERSION = "battlefield.version";
|
|
const string VAR_MASTER_OBJECT = "battlefield.master_object";
|
|
const string VAR_EXTENT = "battlefield.extent";
|
|
const string VAR_MARKERS = "battlefield.markers";
|
|
const string VAR_RESTART_TIME_MIN = "battlefield.restart_time_min";
|
|
const string VAR_RESTART_TIME_MAX = "battlefield.restart_time_max";
|
|
const string VAR_GAME_DURATION = "battlefield.game_duration";
|
|
const string VAR_NEXT_GAME = "battlefield.next_game";
|
|
const string VAR_GAME_TYPE = "battlefield.game_type";
|
|
const string VAR_FACTIONS_ALLOWED = "battlefield.factions_allowed";
|
|
const string VAR_FACTIONS_AI_ALLOWED = "battlefield.factions_ai_allowed";
|
|
const string VAR_START_LOCATIONS = "battlefield.start_locations";
|
|
const string VAR_BASE_OBJECTS = "battlefield.base_objects";
|
|
const string VAR_PLAYERS_IN_BATTLEFIELD = "battlefield.player_in_battlefield";
|
|
const string VAR_WAYPOINTS = "battlefield.waypoints";
|
|
|
|
// Game variables
|
|
const string VAR_GAME = "battlefield.game";
|
|
const string VAR_TIME_REMAINING = "battlefield.game.time_remaining";
|
|
const string VAR_PARTICIPANTS = "battlefield.game.participants";
|
|
const string VAR_FACTIONS_REMAINING = "battlefield.game.factions_remaining";
|
|
const string VAR_FACTIONS_AI_REMAINING = "battlefield.game.factions_ai_remaining";
|
|
const string VAR_BUILD_POINTS = "battlefield.game.build_points_";
|
|
const string VAR_KILLS = "battlefield.game.stats.kills_";
|
|
const string VAR_DEATHS = "battlefield.game.stats.deaths_";
|
|
|
|
// Previous game stat variables
|
|
const string VAR_STAT_ROOT = "battlefield.stats";
|
|
const string VAR_STAT_TYPE = "battlefield.stats.type";
|
|
const string VAR_STAT_TIME = "battlefield.stats.time";
|
|
const string VAR_STAT_WINNER = "battlefield.stats.winner";
|
|
const string VAR_STAT_PLAYERS = "battlefield.stats.players";
|
|
const string VAR_STAT_KILLS = "battlefield.stats.kills_";
|
|
const string VAR_STAT_DEATHS = "battlefield.stats.deaths_";
|
|
|
|
// Player
|
|
const string VAR_BATTLEFIELD_ENTERED = "battlefield.battlefield_entered";
|
|
const string VAR_BATTLEFIELD_TO_ENTER = "battlefield.battlefield_to_enter";
|
|
const string VAR_TEAM_FACTION = "battlefield.team_faction";
|
|
const string VAR_TIME_ENTERED = "battlefield.time_entered";
|
|
const string VAR_TIME_EXITED = "battlefield.time_exited";
|
|
const string VAR_CHATROOM_ALL = "battlefield.chatroom_all";
|
|
const string VAR_CHATROOM_FACTION = "battlefield.chatroom_faction";
|
|
const string VAR_EXPELLED = "battlefield.expelled";
|
|
const string VAR_SELECTING_FACTION = "battlefield.selecting_faction";
|
|
|
|
// Spawners
|
|
const string VAR_SPAWNER_TYPE = "battlefield.spawner.type";
|
|
const string VAR_SPAWNER_PULSE = "battlefield.spawner.pulse";
|
|
const string VAR_SPAWNER_MAX = "battlefield.spawner.maximum_spawn";
|
|
const string VAR_SPAWNER_CURRENT = "battlefield.spawner.current_spawn";
|
|
const string VAR_SPAWNER_CURRENT_POPULATION = "battlefield.spawner.current_population";
|
|
const string VAR_SPAWNER_MAX_POPULATION = "battlefield.spawner.max_population";
|
|
const string VAR_SPAWNED_BY = "battlefield.spawned_by";
|
|
const string VAR_SPAWNED_BATTLEFIELD = "battlefield.spawned_battlefield";
|
|
|
|
// Game critical objects
|
|
const string VAR_GAME_CRITICAL = "battlefield.game_critical";
|
|
const string VAR_VALUE1 = "battlefield.value1";
|
|
const string VAR_VALUE2 = "battlefield.value2";
|
|
const string VAR_COMBAT_DESTROYED = "battlefield.combat_destroyed";
|
|
|
|
// Construction sites/Player built
|
|
const string VAR_BUILDTIME = "battlefield.buildtime";
|
|
const string VAR_TIMESTAMP = "battlefield.timestamp";
|
|
const string VAR_HEIGHT = "battlefield.height";
|
|
const string VAR_CONSTRUCTED = "battlefield.constructed";
|
|
const string VAR_REPAIRING = "battlefield.repairing";
|
|
const string VAR_REPAIR_COST = "battlefield.repair_cost";
|
|
const string VAR_LAST_BUILD = "battlefield.last_build";
|
|
const string VAR_BUILD_RATE = "battlefield.build_rate";
|
|
const string VAR_REINFORCEMENT_TEMPLATE = "battlefield.reinforcement_template";
|
|
const string VAR_REINFORCEMENT_NAME = "battlefield.reinforcement_name";
|
|
const string VAR_REINFORCEMENT_COST = "battlefield.reinforcement_cost";
|
|
|
|
// Misc
|
|
const string VAR_DECLARED = "faction_recruiter.declared";
|
|
|
|
// system values
|
|
const float MARKER_SPACING = 4.0f;
|
|
const int GAME_TIME_PULSE = 5;
|
|
const float OUTER_PERIMETER_WIDTH = 15.0f;
|
|
const float MIN_START_LOCATION_TOLERANCE = 1.0f;
|
|
const float MAX_START_LOCATION_TOLERANCE = 5.0f;
|
|
const int CONFINEMENT_TIME = 0;
|
|
const float DEATH_TIME = 15.0f;
|
|
const int STARTING_BUILD_POINTS = 500;
|
|
const float BUILD_POINT_RECHARGE_PULSE = 30.0f;
|
|
const int BUILD_POINT_RECHARGE_AMOUNT = 10;
|
|
const float CONSTRUCTOR_RANGE = 60.0f;
|
|
const float REINFORCEMENT_RANGE = 10.0f;
|
|
const float REPAIR_RANGE = 10.0f;
|
|
const float REPAIR_PULSE = 5.0f;
|
|
const int MAXIMUM_POPULATION = 50;
|
|
const int MAXIMUM_FACTION_SIZE_DIFFERENCE = 5;
|
|
|
|
// version
|
|
const int CURRENT_VERSION = 3;
|
|
|
|
// trigger names
|
|
const string STRING_TRIG_BOUNDARY = "battlefield_boundary";
|
|
const string STRING_TRIG_OUTER_PERIMETER = "battlefield_outer_perimeter";
|
|
|
|
// misc
|
|
const string GAME_SCRIPT_PATH = "systems.battlefield.game_";
|
|
|
|
/***** TRIGGERS ********************************************************/
|
|
|
|
|
|
/***** MESSAGEHANDLERS *************************************************/
|
|
|
|
|
|
/***** MESSAGEHANDLERS *************************************************/
|
|
|
|
|
|
/***** COMMANDHANDLERS *************************************************/
|
|
|
|
|
|
/***** FUNCTIONS *************************************************/
|
|
|
|
|
|
/***********************************************************************
|
|
* @brief Creates battlefields for the specified area
|
|
*
|
|
* @param string area
|
|
*
|
|
* @return void
|
|
***********************************************************************/
|
|
void createBattlefieldRegions(string area)
|
|
{
|
|
int numItems = dataTableGetNumRows(BATTLEFIELD_DATATABLE);
|
|
int numMarkers = dataTableGetNumRows(BATTLEFIELD_MARKER_DATATABLE);
|
|
|
|
for (int i = 0; i < numItems; i++)
|
|
{
|
|
dictionary row = dataTableGetRow(BATTLEFIELD_DATATABLE, i);
|
|
string name = row.getString(DATATABLE_COL_NAME);
|
|
string bf_area = row.getString(DATATABLE_COL_AREA);
|
|
//LOG("LOG_CHANNEL", "name ->" + name + " bf_area ->" + bf_area);
|
|
if (area == bf_area)
|
|
{
|
|
// Get the region's data
|
|
string type = row.getString(DATATABLE_COL_TYPE);
|
|
float x1 = row.getFloat(DATATABLE_COL_X1);
|
|
float y1 = row.getFloat(DATATABLE_COL_Y1);
|
|
float z1 = row.getFloat(DATATABLE_COL_Z1);
|
|
float radius = row.getFloat(DATATABLE_COL_RADIUS);
|
|
string game_type = row.getString(DATATABLE_COL_GAME_TYPE);
|
|
int restart_min = row.getInt(DATATABLE_COL_RESTART_MIN);
|
|
int restart_max = row.getInt(DATATABLE_COL_RESTART_MAX);
|
|
int game_time = row.getInt(DATATABLE_COL_GAME_TIME);
|
|
int imperial = row.getInt(DATATABLE_COL_IMPERIAL);
|
|
int rebel = row.getInt(DATATABLE_COL_REBEL);
|
|
int hutt = row.getInt(DATATABLE_COL_HUTT);
|
|
|
|
LOG("LOG_CHANNEL", " type ->" + type + " " + x1 + "/" + y1 + "/" + z1 + "/" + radius);
|
|
|
|
if (type == null)
|
|
continue;
|
|
|
|
// Check to see if a battlefield is already in the area.
|
|
int regionPvpType;
|
|
if ( type == "pvp" )
|
|
regionPvpType = regions.PVP_REGION_TYPE_BATTLEFIELD_PVP;
|
|
else if (type == "pve")
|
|
regionPvpType = regions.PVP_REGION_TYPE_BATTLEFIELD_PVE;
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", " Unsupported pvp type " + type + " read, skipping");
|
|
continue;
|
|
}
|
|
|
|
// Create the locations for the region's bounds
|
|
location loc = new location(x1, y1, z1, bf_area);
|
|
|
|
string regionName = "@battlefield:" + name;
|
|
|
|
// Check to see if a battlefield is already in the area.
|
|
if (getRegionsWithPvPAtPoint(loc, regionPvpType) != null)
|
|
{
|
|
LOG("LOG_CHANNEL", " " + type.toUpperCase() + " Battlefield found, skipping...");
|
|
}
|
|
else
|
|
{
|
|
// get the geography at the battlefield
|
|
int geography = regions.GEO_PLAINS;
|
|
region testRegion = getSmallestRegionAtPoint(loc);
|
|
if ( testRegion != null )
|
|
geography = testRegion.getGeographicalType();
|
|
|
|
// Create the region
|
|
createCircleRegion(loc, radius, regionName, regionPvpType, regions.BUILD_TRUE, regions.MUNI_FALSE,
|
|
geography, 0, 0, regions.SPAWN_FALSE, regions.MISSION_NONE, true, false);
|
|
}
|
|
|
|
// Create the battlefield marker
|
|
string markerName = null;
|
|
float bestRadius = 0.0f;
|
|
for (int j = 0; j < numMarkers; ++j)
|
|
{
|
|
dictionary markerRow = dataTableGetRow(BATTLEFIELD_MARKER_DATATABLE, j);
|
|
float markerRadius = markerRow.getFloat(DATATABLE_COL_RADIUS);
|
|
if (Math.abs(markerRadius-radius) < Math.abs(bestRadius-radius))
|
|
{
|
|
bestRadius = markerRadius;
|
|
markerName = markerRow.getString(DATATABLE_COL_TEMPLATE);
|
|
}
|
|
}
|
|
if (markerName != null)
|
|
{
|
|
obj_id marker = createObject(markerName, loc);
|
|
if (isIdValid(marker))
|
|
{
|
|
setBattlefieldMarkerRegionName(marker, regionName);
|
|
if (exists(marker))
|
|
persistObject(marker);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void destroyBattlefieldRegions(string area)
|
|
{
|
|
if (area == null)
|
|
return;
|
|
|
|
int numItems = dataTableGetNumRows(BATTLEFIELD_DATATABLE);
|
|
|
|
for (int i = 0; i < numItems; i++)
|
|
{
|
|
dictionary row = dataTableGetRow(BATTLEFIELD_DATATABLE, i);
|
|
string name = row.getString(DATATABLE_COL_NAME);
|
|
string bf_area = row.getString(DATATABLE_COL_AREA);
|
|
string type = row.getString(DATATABLE_COL_TYPE);
|
|
if (type == null || type.length() < 1)
|
|
continue;
|
|
|
|
if (bf_area != null && bf_area.length() > 0)
|
|
{
|
|
if (area == bf_area)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::destroyBattlefieldRegions -- " + name);
|
|
float x1 = row.getFloat(DATATABLE_COL_X1);
|
|
float y1 = row.getFloat(DATATABLE_COL_Y1);
|
|
float z1 = row.getFloat(DATATABLE_COL_Z1);
|
|
location loc = new location(x1, y1, z1, bf_area);
|
|
|
|
int regionPvpType;
|
|
if ( type == "pvp" )
|
|
regionPvpType = regions.PVP_REGION_TYPE_BATTLEFIELD_PVP;
|
|
else if (type == "pve")
|
|
regionPvpType = regions.PVP_REGION_TYPE_BATTLEFIELD_PVE;
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", " Unsupported pvp type " + type + " read, skipping");
|
|
continue;
|
|
}
|
|
region[] regs = getRegionsWithPvPAtPoint(loc, regionPvpType);
|
|
if (regs != null && regs.length > 0)
|
|
{
|
|
for (int j = 0; j < regs.length; j++)
|
|
{
|
|
obj_id bf_object = getMasterObjectFromRegion(regs[j]);
|
|
if (isIdValid(bf_object))
|
|
destroyBattlefield(bf_object);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Updates a battlefield's object values from the datatable.
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean false on fail
|
|
***********************************************************************/
|
|
boolean updateBattlefieldData(obj_id master_object, region bf)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::updateBattlefield");
|
|
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.updateBattlefield -- the battlefield object is null.");
|
|
debugServerConsoleMsg(null, "battlefield.updateBattlefield -- the battlefield object is null.");
|
|
return false;
|
|
}
|
|
|
|
if (bf == null)
|
|
{
|
|
bf = getBattlefield(master_object);
|
|
if (bf == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.updateBattlefield -- the region is null.");
|
|
debugServerConsoleMsg(null, "battlefield.updateBattlefield -- the region is null.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
string name = getBattlefieldName(bf);
|
|
int idx = dataTableSearchColumnForString(name, DATATABLE_COL_NAME, BATTLEFIELD_DATATABLE);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getSpawnerData -- unable to find an entry for " + name);
|
|
debugServerConsoleMsg(null, "battlefield::getSpawnerData -- unable to find an entry for " + name);
|
|
return false;
|
|
}
|
|
|
|
// Get the data from the datatable
|
|
dictionary row = dataTableGetRow(BATTLEFIELD_DATATABLE, idx);
|
|
string type = row.getString(DATATABLE_COL_TYPE);
|
|
float x1 = row.getFloat(DATATABLE_COL_X1);
|
|
float y1 = row.getFloat(DATATABLE_COL_Y1);
|
|
float z1 = row.getFloat(DATATABLE_COL_Z1);
|
|
float radius = row.getFloat(DATATABLE_COL_RADIUS);
|
|
string game_type = row.getString(DATATABLE_COL_GAME_TYPE);
|
|
int restart_min = row.getInt(DATATABLE_COL_RESTART_MIN);
|
|
int restart_max = row.getInt(DATATABLE_COL_RESTART_MAX);
|
|
int game_time = row.getInt(DATATABLE_COL_GAME_TIME);
|
|
int imperial = row.getInt(DATATABLE_COL_IMPERIAL);
|
|
int rebel = row.getInt(DATATABLE_COL_REBEL);
|
|
int hutt = row.getInt(DATATABLE_COL_HUTT);
|
|
|
|
// Set the battlefield type
|
|
// if (type.toUpperCase().equals("PVP"))
|
|
// setRegionPvP(bf, regions.PVP_REGION_TYPE_BATTLEFIELD_PVP);
|
|
// else
|
|
// setRegionPvP(bf, regions.PVP_REGION_TYPE_BATTLEFIELD_PVE);
|
|
|
|
// Set the objvars
|
|
setObjVar(master_object, VAR_NAME, bf.getName());
|
|
setObjVar(master_object, VAR_PLANET, bf.getPlanetName());
|
|
setObjVar(master_object, VAR_EXTENT, radius);
|
|
setObjVar(master_object, VAR_GAME_TYPE, game_type);
|
|
setObjVar(master_object, VAR_RESTART_TIME_MIN, restart_min);
|
|
setObjVar(master_object, VAR_RESTART_TIME_MAX, restart_max);
|
|
setObjVar(master_object, VAR_GAME_DURATION, game_time);
|
|
|
|
// Set factions allowed
|
|
resizeable string[] factions_allowed = new string[0];
|
|
resizeable string[] factions_ai = new string[0];
|
|
LOG("LOG_CHANNEL", "imperial ->" + imperial + " rebel ->" + rebel);
|
|
|
|
// 1 enables a faction for players and ai.
|
|
// 2 enables a faction for just ai.
|
|
if (imperial == 1)
|
|
factions_allowed = utils.addElement(factions_allowed, factions.FACTION_IMPERIAL);
|
|
else if (imperial == 2)
|
|
factions_ai = utils.addElement(factions_ai, factions.FACTION_IMPERIAL);
|
|
|
|
if (rebel == 1)
|
|
factions_allowed = utils.addElement(factions_allowed, factions.FACTION_REBEL);
|
|
else if (rebel == 2)
|
|
factions_ai = utils.addElement(factions_ai, factions.FACTION_REBEL);
|
|
|
|
if (hutt == 1)
|
|
factions_allowed = utils.addElement(factions_allowed, factions.FACTION_HUTT);
|
|
else if (hutt == 2)
|
|
factions_ai = utils.addElement(factions_ai, factions.FACTION_HUTT);
|
|
|
|
if (factions_allowed.length > 0)
|
|
{
|
|
// Set Factions allowed and create a starting location array with as many elements
|
|
setObjVar(master_object, VAR_FACTIONS_ALLOWED, factions_allowed);
|
|
|
|
location[] start_locations = new location[factions_allowed.length];
|
|
|
|
if(start_locations.length > 0) { // Zero length array check, should be redundant
|
|
|
|
setObjVar(master_object, VAR_START_LOCATIONS, start_locations);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::updateBattlefield -- there are no allowed factions for " + master_object);
|
|
return false;
|
|
}
|
|
|
|
if (factions_ai.length > 0)
|
|
setObjVar(master_object, VAR_FACTIONS_AI_ALLOWED, factions_ai);
|
|
|
|
setObjVar(master_object, VAR_VERSION, CURRENT_VERSION);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Surrounds a battlefield with markers
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean markBattlefield(region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
// For now we only use circular battlefields.
|
|
// Make the radius of the markers slightly larger than the trigger volume so that they
|
|
// stay out of it.
|
|
float radius = getBattlefieldExtent(r) + 2.0f;
|
|
location bf_loc = getBattlefieldLocation(r);
|
|
|
|
// The amount of markers to drop is dependant on the radius.
|
|
float degree_incr = 360.0f * MARKER_SPACING / radius;
|
|
if (degree_incr > 90)
|
|
degree_incr = 90;
|
|
|
|
//LOG("LOG_CHANNEL", "degree_incr ->" + degree_incr);
|
|
float radian_incr = (float)Math.toRadians(degree_incr);
|
|
resizeable obj_id[] markers = new obj_id[0];
|
|
|
|
for (float angle = 0.0f; angle < 2 * Math.PI; angle = angle + radian_incr)
|
|
{
|
|
float x = radius * (float)Math.sin(angle) + bf_loc.x;
|
|
float z = radius * (float)Math.cos(angle) + bf_loc.z;
|
|
float y = getHeightAtLocation(x, z);
|
|
//LOG("LOG_CHANNEL", "angle ->" + angle + " " + x + "/" + y + "/" + z);
|
|
|
|
location loc = new location(x, y, z, getCurrentSceneName());
|
|
|
|
obj_id marker = createObject(BATTLEFIELD_MARKER, loc);
|
|
persistObject(marker);
|
|
markers = utils.addElement(markers, marker);
|
|
}
|
|
|
|
// Keep track of the markers on the master object so that they may be cleaned up
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
if(markers.length > 0) { // Zero length array check
|
|
|
|
setObjVar(master_object, VAR_MARKERS, markers);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the battlefield at the given locaiton
|
|
*
|
|
* @param location loc
|
|
*
|
|
* @return region; returns null if the location is not in a battlefield
|
|
***********************************************************************/
|
|
region getBattlefield(location loc)
|
|
{
|
|
// Check for PvP battlefields
|
|
region[] rPvP = getRegionsWithPvPAtPoint(loc, regions.PVP_REGION_TYPE_BATTLEFIELD_PVP);
|
|
if (rPvP != null)
|
|
{
|
|
// There should only be one battlefield at a given point
|
|
return rPvP[0];
|
|
}
|
|
else
|
|
{
|
|
// Check for PvE battlefields
|
|
region[] rPvE = getRegionsWithPvPAtPoint(loc, regions.PVP_REGION_TYPE_BATTLEFIELD_PVE);
|
|
if (rPvE != null)
|
|
{
|
|
// There should only be one battlefield at a given point
|
|
return rPvE[0];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getBattlefield
|
|
*
|
|
* @param obj_id object
|
|
*
|
|
* @return region; returns null if the object is not in a battlefield
|
|
***********************************************************************/
|
|
region getBattlefield(obj_id object)
|
|
{
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
location loc = getLocation(object);
|
|
|
|
return getBattlefield(loc);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the battle field is PvP.
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldPvP(region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
int pvpType = r.getPvPType();
|
|
if (pvpType == regions.PVP_REGION_TYPE_BATTLEFIELD_PVP)
|
|
return true;
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the battle field is PvE.
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldPvE(region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
int pvpType = r.getPvPType();
|
|
if (pvpType == regions.PVP_REGION_TYPE_BATTLEFIELD_PVE)
|
|
return true;
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a the battlefield is active
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldActive(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
int time = getGameTimeRemaining(master_object);
|
|
if (time == -1)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for isBattlefieldActive
|
|
*
|
|
* @param region r battlefield to test
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldActive(region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return isBattlefieldActive(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a player is on a given team
|
|
*
|
|
* @param obj_id player
|
|
* @param string faction
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isFactionTeamMember(obj_id player, string faction, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
obj_id[] faction_team = getFactionTeam(master_object, faction);
|
|
if (faction_team != null)
|
|
{
|
|
for (int i = 0; i < faction_team.length; i++)
|
|
{
|
|
if (player == faction_team[i])
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a player faction is allowed in
|
|
* the game.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isFactionAllowed(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (faction == null)
|
|
return false;
|
|
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
if (factions_allowed == null)
|
|
return false;
|
|
|
|
int idx = utils.getElementPositionInArray(factions_allowed, faction);
|
|
|
|
if (idx == -1)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a faction is still remaining in
|
|
* the game.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isFactionRemaining(obj_id master_object, string faction)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::isFactionRemaining -- " + master_object + " " + faction);
|
|
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!isBattlefieldActive(master_object))
|
|
return false;
|
|
|
|
if (!hasObjVar(master_object, VAR_FACTIONS_REMAINING))
|
|
return false;
|
|
else
|
|
{
|
|
string[] factions_remaining = getFactionsRemaining(master_object);
|
|
int idx = utils.getElementPositionInArray(factions_remaining, faction);
|
|
//LOG("LOG_CHANNEL", "battlefield::isFactionRemaining -- " + idx);
|
|
|
|
if (idx == -1)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a faction is a player faction.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isPlayerFaction(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
if (factions_allowed != null)
|
|
{
|
|
int idx = utils.getElementPositionInArray(factions_allowed, faction);
|
|
if (idx != -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::isPlayerFaction -- true");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::isPlayerFaction -- false");
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::isPlayerFaction -- factions_allowed is null.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a faction is an ai faction.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isAIFaction(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string[] ai_factions = getAIFactionsAllowed(master_object);
|
|
if (ai_factions != null)
|
|
{
|
|
int idx = utils.getElementPositionInArray(ai_factions, faction);
|
|
if (idx != -1)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::isAIFaction -- ai_factions is null.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a player has an existing
|
|
* select faction sui.
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean hasSelectFactionSui(obj_id player)
|
|
{
|
|
if (!isIdValid(player))
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::hasSelectFactionSui -- " + player + " (false)");
|
|
return false;
|
|
}
|
|
|
|
if (utils.hasScriptVar(player, VAR_SELECTING_FACTION))
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::hasSelectFactionSui -- " + player + " (true)");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::hasSelectFactionSui -- " + player + " (false)");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a player may join a given faction.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id param
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canJoinFaction(obj_id master_object, obj_id player, string faction)
|
|
{
|
|
|
|
LOG("LOG_CHANNEL", "battlefield.canJoinFaction -- " + master_object + "/" + player + "/" + faction);
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
|
|
int total_population = 0;
|
|
obj_id[] players = getParticipantsOnBattlefield(master_object);
|
|
if (players != null)
|
|
total_population = players.length;
|
|
|
|
// if the total population exceeds the battlefield limits, can't join any faction.
|
|
if (total_population >= MAXIMUM_POPULATION)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->There are too many combatants currently within the battlefield.");
|
|
sendSystemMessageTestingOnly(player, "There are too many combatants currently within the battlefield.");
|
|
return false;
|
|
}
|
|
|
|
// Check the count in each faction.
|
|
resizeable int[] factions_allowed_sizes = new int[0];
|
|
int number_factions = factions_allowed.length;
|
|
int faction_size = 0;
|
|
if (factions_allowed != null)
|
|
{
|
|
for (int i = 0; i < factions_allowed.length; i++)
|
|
{
|
|
obj_id[] faction_team = getFactionTeam(master_object, factions_allowed[i]);
|
|
int size;
|
|
if (faction_team != null)
|
|
size = faction_team.length;
|
|
else
|
|
size = 0;
|
|
|
|
factions_allowed_sizes = utils.addElement(factions_allowed_sizes, size);
|
|
|
|
if (factions_allowed[i].equals(faction))
|
|
faction_size = size;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.canJoinFaction -- factions_allowed is null for " + master_object);
|
|
return false;
|
|
}
|
|
|
|
// The faction to join can not have more than its faction of the maximum population
|
|
int max_faction_pop = MAXIMUM_POPULATION / number_factions;
|
|
if (faction_size >= max_faction_pop)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->There are too many combantants on the " + faction + " faction to join at this list.");
|
|
sendSystemMessageTestingOnly(player, "There are too many combantants on the " + faction + " faction to join at this list.");
|
|
return false;
|
|
}
|
|
|
|
// Compare the sizes of the factions. No faction may have more than 10
|
|
for (int i = 0; i < factions_allowed_sizes.length; i++)
|
|
{
|
|
if (!factions_allowed[i].equals(faction))
|
|
{
|
|
if (faction_size - factions_allowed_sizes[i] > MAXIMUM_FACTION_SIZE_DIFFERENCE)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->There are too many combantants on the " + faction + " faction to join at this list.");
|
|
sendSystemMessageTestingOnly(player, "There are too many combantants on the " + faction + " faction to join at this list.");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a location is near a battlefield
|
|
* constructor of the specified faction
|
|
*
|
|
* @param obj_id master_object
|
|
* @param location loc
|
|
* @param string faction
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isNearBattlefieldConstructor(obj_id master_object, location loc, string faction)
|
|
{
|
|
if (loc.y == 0.0f)
|
|
{
|
|
// We need a y coordinate for an accurate range check. Since the placement tool
|
|
// does not give y, we must set it outselves.
|
|
loc.y = getElevation(loc);
|
|
}
|
|
|
|
obj_id[] objects = getObjectsInRange(loc, CONSTRUCTOR_RANGE);
|
|
if (objects != null)
|
|
{
|
|
for (int i = 0; i < objects.length; i++)
|
|
{
|
|
//LOG("LOG_CHANNEL", "object ->" + objects[i]);
|
|
if (hasScript(objects[i], SCRIPT_BATTLEFIELD_CONSTRUCTOR))
|
|
{
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
int obj_faction_id = pvpBattlefieldGetFaction(objects[i], bf);
|
|
string obj_faction = factions.getFactionNameByHashCode(obj_faction_id);
|
|
//LOG("LOG_CHANNEL", "... faction ->" + faction + " obj_faction ->" + obj_faction);
|
|
if (faction.equals(obj_faction))
|
|
{
|
|
LOG("LOG_CHANNEL", "constructor ->" + objects[i]);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not an object was battlefield constructed
|
|
*
|
|
* @param obj_id object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldConstructed(obj_id object)
|
|
{
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (hasObjVar(object, VAR_CONSTRUCTED))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not an object was battlefield spawned
|
|
*
|
|
* @param obj_id object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isBattlefieldSpawned(obj_id object)
|
|
{
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (hasObjVar(object, VAR_SPAWNED_BY))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not two objects are of the same
|
|
* battlefield faction.
|
|
*
|
|
* @param obj_id object1
|
|
* @param obj_id object2
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean isSameBattlefieldFaction(obj_id object1, obj_id object2)
|
|
{
|
|
if (object1 == null || object1 == obj_id.NULL_ID)
|
|
return false;
|
|
if (object2 == null || object2 == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
region bf = battlefield.getBattlefield(object1);
|
|
region bf2 = battlefield.getBattlefield(object2);
|
|
if (bf == null || bf2 == null)
|
|
return false;
|
|
|
|
if (!bf.getName().equals(bf2.getName()))
|
|
return false;
|
|
|
|
obj_id master_object = battlefield.getMasterObjectFromRegion(bf);
|
|
int object1_id = pvpBattlefieldGetFaction(object1, bf);
|
|
int object2_id = pvpBattlefieldGetFaction(object2, bf);
|
|
//LOG("LOG_CHANNEL", "obj1 ->" + object1_id + " obj2 ->" + object2_id);
|
|
|
|
if (object1_id == object2_id)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the player may join a battlefield game
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player
|
|
* @param boolean verbose
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canJoinBattlefield(obj_id master_object, obj_id player, boolean verbose)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!isBattlefieldActive(master_object))
|
|
return true;
|
|
|
|
if (pvpHasAnyTempEnemyFlags(player))
|
|
{
|
|
if (verbose)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You cannot enter the battlefield as long as you have temporary enemies.");
|
|
sendSystemMessageTestingOnly(player, "You cannot enter the battlefield as long as you have temporary enemies.");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
if (hasObjVar(player, VAR_BATTLEFIELD_ENTERED))
|
|
{
|
|
if (master_object == getObjIdObjVar(player, VAR_BATTLEFIELD_ENTERED))
|
|
{
|
|
if (verbose)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You must wait for the current battle to end before reentering.");
|
|
sendSystemMessageTestingOnly(player, "You must wait for the current battle to end before reentering.");
|
|
}
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief canJoinBattlefield overload
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canJoinBattlefield(obj_id master_object, obj_id player)
|
|
{
|
|
return canJoinBattlefield(master_object, player, false);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief canJoinBattlefield overload
|
|
*
|
|
* @param region r battlefield to test
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canJoinBattlefield(region r, obj_id player)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return canJoinBattlefield(master_object, player);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the player can build a structure.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canBuildBattlefieldStructure(obj_id master_object, obj_id player)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
location loc = getLocation(player);
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
int faction_id = pvpBattlefieldGetFaction(player, bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
|
|
// Check to see if the player has the appropriate skill.
|
|
if (!utils.isProfession(player, utils.TRADER))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You must have skill as an artisan in order to use the battlefield constructor.");
|
|
sendSystemMessageTestingOnly(player, "You must have skill as an artisan in order to use the battlefield constructor.");
|
|
return false;
|
|
}
|
|
|
|
if (!isNearBattlefieldConstructor(master_object, loc, faction))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You must be near a battlefield constructor owned by your faction.");
|
|
sendSystemMessageTestingOnly(player, "You must be near a battlefield constructor owned by your faction.");
|
|
return false;
|
|
}
|
|
|
|
if (!isBattlefieldActive(master_object))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You can only build in an active battlefield.");
|
|
sendSystemMessageTestingOnly(player, "You can only build in an active battlefield.");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not a barracks is able to build
|
|
* reinforcements.
|
|
*
|
|
* @param obj_id structure
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canBuildReinforcement(obj_id structure)
|
|
{
|
|
if (structure == null || structure == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!hasScript(structure, SCRIPT_BARRACKS))
|
|
return false;
|
|
else
|
|
{
|
|
if (hasObjVar(structure, VAR_LAST_BUILD))
|
|
{
|
|
int time = getGameTime();
|
|
int build_rate = getIntObjVar(structure, VAR_BUILD_RATE);
|
|
if (time - getIntObjVar(structure, VAR_LAST_BUILD) <= build_rate)
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the player may enter the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canEnterBattlefield(obj_id master_object, obj_id player)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!isBattlefieldActive(master_object))
|
|
return true;
|
|
|
|
if (hasObjVar(player, VAR_TEAM_FACTION))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief canEnterBattlefield
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canEnterBattlefield(region r, obj_id player)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return canEnterBattlefield(master_object, player);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Determines whether or not the player may leave the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player
|
|
* @param boolean verbose whether or not to display messaging.
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean canExitBattlefield(obj_id master_object, obj_id player, boolean verbose)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (hasObjVar(player, VAR_TIME_ENTERED))
|
|
{
|
|
int time_played = getGameTime() - getIntObjVar(player, VAR_TIME_ENTERED);
|
|
//LOG("LOG_CHANNEL", "time_played ->" + time_played);
|
|
if (time_played < CONFINEMENT_TIME)
|
|
{
|
|
if (verbose)
|
|
{
|
|
int time_left = CONFINEMENT_TIME - time_played;
|
|
int[] conv_time = player_structure.convertSecondsTime(time_left);
|
|
string time_str = player_structure.assembleTimeRemaining(conv_time);
|
|
|
|
LOG("LOG_CHANNEL", player + " ->You may not leave the battlefield until you have played for another " + time_str);
|
|
sendSystemMessageTestingOnly(player, "You may not leave the battlefield until you have played for another " + time_str);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* @brief Adds an object to the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string template template of object to add
|
|
* @param location loc location to place the object
|
|
* @param float yaw yaw of the object
|
|
* @param string faction faction with which to align the object
|
|
*
|
|
* @return obj_id object created. Null on fail.
|
|
***********************************************************************/
|
|
obj_id addBattlefieldObject(obj_id master_object, string template, location loc, float yaw, string faction)
|
|
{
|
|
// Create it.
|
|
obj_id object = createObject(template, loc);
|
|
if (object == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::addBattlefieldObject -- unable to create " + template + " in " + master_object);
|
|
return null;
|
|
}
|
|
|
|
// Rotate it.
|
|
setYaw(object, yaw);
|
|
|
|
// Attach battlefield object script
|
|
attachScript(object, SCRIPT_BATTLEFIELD_OBJECT);
|
|
|
|
// Add it to the base object list.
|
|
//resizeable obj_id[] base_objects = new obj_id[0];
|
|
//if (hasObjVar(master_object, VAR_BASE_OBJECTS))
|
|
// base_objects = getResizeableObjIdArrayObjVar(master_object, VAR_BASE_OBJECTS);
|
|
|
|
//base_objects = utils.addElement(base_objects, object);
|
|
//setObjVar(master_object, VAR_BASE_OBJECTS, base_objects);
|
|
|
|
// Set its faction.
|
|
int faction_id = getFactionId(faction);
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
pvpBattlefieldSetParticipant(object, bf, faction_id);
|
|
|
|
//persistObject(object);
|
|
|
|
return object;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Removes an object from the battlefield
|
|
*
|
|
* @param obj_id object object to remove
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean removeBattlefieldObject(obj_id master_object, obj_id object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
pvpBattlefieldSetParticipant(object, bf, 0);
|
|
|
|
messageTo(object, "msgDestroyBattlefieldObject", null, 0.0f, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for removeBattlefieldObject
|
|
*
|
|
* @param obj_id object object to remove
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean removeBattlefieldObject(obj_id object)
|
|
{
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
region bf = getBattlefield(object);
|
|
obj_id master_object = getMasterObjectFromRegion(bf);
|
|
|
|
if (master_object == null)
|
|
return false;
|
|
|
|
return removeBattlefieldObject(master_object, object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief removes the object from the battlefield object list
|
|
* without deleting it. This should only be used if it can
|
|
* be assured that the object will be deleted.
|
|
*
|
|
* @param obj_id object object to remove
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean removeFromBattlefieldObjectList(obj_id master_object, obj_id object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (object == null || object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
pvpBattlefieldSetParticipant(object, bf, 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Adds a mob to the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string mob mob name to add (from creature datatable)
|
|
* @param location loc location to place the mob
|
|
* @param string faction faction with which to align the mob
|
|
*
|
|
* @return obj_id mob created. Null on fail.
|
|
***********************************************************************/
|
|
obj_id addBattlefieldMob(obj_id master_object, string name, location loc, string faction)
|
|
{
|
|
// Create it.
|
|
obj_id mob = create.createCreature(name, loc, true);
|
|
if (mob == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::addBattlefieldMob -- unable to create " + name + " in " + master_object);
|
|
return null;
|
|
}
|
|
|
|
// Attach battlefield object script
|
|
attachScript(mob, SCRIPT_BATTLEFIELD_OBJECT);
|
|
|
|
// Set its faction.
|
|
int faction_id = getFactionId(faction);
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
pvpBattlefieldSetParticipant(mob, bf, faction_id);
|
|
|
|
return mob;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Adds a battlefield waypoint to the player for a given structure
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id structure
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
obj_id addBattlefieldWaypoint(obj_id player, obj_id structure)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (structure == null || structure == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
obj_id waypoint = createWaypointInDatapad(player, structure);
|
|
if (!isIdValid(waypoint))
|
|
return null;
|
|
|
|
setWaypointVisible(waypoint, true);
|
|
setWaypointActive(waypoint, true);
|
|
|
|
setWaypointName(waypoint, getName(structure));
|
|
|
|
// Record the waypoint in the player's waypoint list.
|
|
resizeable obj_id[] waypoint_list = new obj_id[0];
|
|
if (hasObjVar(player, VAR_WAYPOINTS))
|
|
waypoint_list = getResizeableObjIdArrayObjVar(player, VAR_WAYPOINTS);
|
|
|
|
waypoint_list = utils.addElement(waypoint_list, waypoint);
|
|
|
|
if(waypoint_list.length > 0) { // Zero length array check
|
|
|
|
setObjVar(player, VAR_WAYPOINTS, waypoint_list);
|
|
}
|
|
|
|
LOG("LOG_CHANNEL", "battlefield::AddBattlefieldWaypoint -- adding waypoint(" + waypoint + ") to player " + player + " for " + structure);
|
|
|
|
return waypoint;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Removes a battlefield waypoint from a player.
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id waypoint
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean removeBattlefieldWaypoint(obj_id player, obj_id waypoint)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (waypoint == null || waypoint == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (hasObjVar(player, VAR_WAYPOINTS))
|
|
{
|
|
resizeable obj_id[] waypoint_list = getResizeableObjIdArrayObjVar(player, VAR_WAYPOINTS);
|
|
int idx = utils.getElementPositionInArray(waypoint_list, waypoint);
|
|
if (idx != -1)
|
|
{
|
|
waypoint_list = utils.removeElementAt(waypoint_list, idx);
|
|
if (waypoint_list.length < 1)
|
|
removeObjVar(player, VAR_WAYPOINTS);
|
|
else
|
|
setObjVar(player, VAR_WAYPOINTS, waypoint_list);
|
|
}
|
|
}
|
|
|
|
destroyObject(waypoint);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Destroys the battlefield and everything within it.
|
|
*
|
|
* @param obj_id master_object master battlefield object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean destroyBattlefield(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
LOG("LOG_CHANNEL", "destroying " + master_object);
|
|
// destroy the region
|
|
region r = getRegionFromMasterObject(master_object);
|
|
deleteRegion(r);
|
|
|
|
// destroy the region markers
|
|
if (hasObjVar(master_object, VAR_MARKERS))
|
|
{
|
|
obj_id[] markers = getObjIdArrayObjVar(master_object, VAR_MARKERS);
|
|
for (int i = 0; i < markers.length; i++)
|
|
destroyObject(markers[i]);
|
|
}
|
|
|
|
// destroy the items within the battlefield
|
|
destroyBaseObjects(master_object);
|
|
|
|
// destroy the master object
|
|
destroyObject(master_object);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for destroyBattlefield
|
|
*
|
|
* @param region battlefield to destroy
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean destroyBattlefield(region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return destroyBattlefield(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Destroys a battlefield's base objects
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean destroyBaseObjects(obj_id master_object)
|
|
{
|
|
//LOG("LOG_CHANNEL", "destroyBaseObjects -- " + master_object);
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
region reg = getRegionFromMasterObject(master_object);
|
|
obj_id[] base_objects = pvpBattlefieldGetParticipantsForFaction(reg, 0);
|
|
if (base_objects != null)
|
|
{
|
|
//LOG("LOG_CHANNEL", "destroyBaseObjects -- " + master_object);
|
|
for (int i = 0; i < base_objects.length; i++)
|
|
{
|
|
if (hasScript(base_objects[i], SCRIPT_BATTLEFIELD_OBJECT))
|
|
messageTo(base_objects[i], "msgDestroyBattlefieldObject", null, 30.0f, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the region of the specified master object
|
|
*
|
|
* @param obj_id master battlefield object
|
|
*
|
|
* @return region of battlefield null on failure
|
|
***********************************************************************/
|
|
region getRegionFromMasterObject(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string regionPlanet = getStringObjVar(master_object, VAR_PLANET);
|
|
string regionName = getStringObjVar(master_object, VAR_NAME);
|
|
|
|
return getRegion(regionPlanet, regionName);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the master object of the specified region
|
|
*
|
|
* @param region battlefield battlefield object
|
|
*
|
|
* @return obj_id of master object null on failure
|
|
***********************************************************************/
|
|
obj_id getMasterObjectFromRegion(region battlefield)
|
|
{
|
|
if (battlefield == null)
|
|
return null;
|
|
|
|
return getBattlefieldRegionMasterObject(battlefield);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the battlefield's name
|
|
*
|
|
* @param obj_id master battlefield object
|
|
*
|
|
* @return string null on failure
|
|
***********************************************************************/
|
|
string getBattlefieldName(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string name = getStringObjVar(master_object, VAR_NAME);
|
|
|
|
if ( name.startsWith("@") )
|
|
{
|
|
// strip the string id table from the name
|
|
name = name.substring(name.indexOf(":") + 1);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getBattlefieldName
|
|
*
|
|
* @param region r battlefield region
|
|
*
|
|
* @return string null on failure
|
|
***********************************************************************/
|
|
string getBattlefieldName(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
string name = r.getName();
|
|
if ( name.startsWith("@") )
|
|
{
|
|
// strip the string id table from the name
|
|
name = name.substring(name.indexOf(":") + 1);
|
|
}
|
|
return name;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the battlefield's localized name
|
|
*
|
|
* @param obj_id master battlefield object
|
|
*
|
|
* @return string null on failure
|
|
***********************************************************************/
|
|
string getBattlefieldLocalizedName(obj_id master_object)
|
|
{
|
|
if (!isIdValid(master_object))
|
|
return null;
|
|
|
|
string name = getBattlefieldName(master_object).toLowerCase();
|
|
string_id name_id = utils.unpackString("@battlefield:" + name);
|
|
|
|
return localize(name_id);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the radius of the battlefield
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return float -1.0f on fail
|
|
***********************************************************************/
|
|
float getBattlefieldExtent(region r)
|
|
{
|
|
if (r == null)
|
|
return -1.0f;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getFloatObjVar(master_object, VAR_EXTENT);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload of BattlefieldExtent
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return float -1.0f on fail
|
|
***********************************************************************/
|
|
float getBattlefieldExtent(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1.0f;
|
|
|
|
return getFloatObjVar(master_object, VAR_EXTENT);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the location of the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return location null on fail
|
|
*********************************************************************/
|
|
location getBattlefieldLocation(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
return getLocation(master_object);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the location of the battlefield
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return location null on fail
|
|
*********************************************************************/
|
|
location getBattlefieldLocation(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getBattlefieldLocation(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the version of the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int
|
|
*********************************************************************/
|
|
int getBattlefieldVersion(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
if (hasObjVar(master_object, VAR_VERSION))
|
|
return getIntObjVar(master_object, VAR_VERSION);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the time remaining in a battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameTimeRemaining(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
if (hasObjVar(master_object, VAR_TIME_REMAINING))
|
|
return getIntObjVar(master_object, VAR_TIME_REMAINING);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getGameTimeRemaining
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameTimeRemaining(region r)
|
|
{
|
|
if (r == null)
|
|
return -1;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getGameTimeRemaining(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's game type
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getBattlefieldGameType(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
return getStringObjVar(master_object, VAR_GAME_TYPE);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getBattlefieldGameType
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getBattlefieldGameType(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getBattlefieldGameType(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's next game time stamp
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getNextGameTime(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
if (hasObjVar(master_object, VAR_NEXT_GAME))
|
|
{
|
|
return getIntObjVar(master_object, VAR_NEXT_GAME);
|
|
}
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getNextGameTime
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getNextGameTime(region r)
|
|
{
|
|
if (r == null)
|
|
return -1;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getNextGameTime(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's game duration
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameDuration(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
return getIntObjVar(master_object, VAR_GAME_DURATION);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getBattlefieldRestartTime
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameDuration(region r)
|
|
{
|
|
if (r == null)
|
|
return -1;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getGameDuration(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the amount of time a player has spent in the
|
|
* battlefield
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return int -1 on fail or the player is not in the battlefield
|
|
*********************************************************************/
|
|
int getTimeSpentInBattlefield(obj_id player)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
region bf = getBattlefield(player);
|
|
if (bf == null)
|
|
return -1;
|
|
|
|
int time_entered = getIntObjVar(player, VAR_TIME_ENTERED);
|
|
int time_exited = getGameTime();
|
|
if (hasObjVar(player, VAR_TIME_EXITED))
|
|
time_exited = getIntObjVar(player, VAR_TIME_EXITED);
|
|
|
|
return time_exited - time_entered;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* @brief returns a list of the names of structures that may be built
|
|
* on the battlefield.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction the faction for which to find buildable
|
|
* structures
|
|
*
|
|
* @return string[] null on fail or if there are none
|
|
*********************************************************************/
|
|
string[] getBuildableStructures(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
int idx = getBattlefieldIndex(master_object, BUILDABLE_STRUCTURE_DATATABLE);
|
|
if (idx == -1)
|
|
return null;
|
|
|
|
resizeable string[] buildable_objects = new string[0];
|
|
int num_items = dataTableGetNumRows(BUILDABLE_STRUCTURE_DATATABLE);
|
|
if (num_items > idx + 1)
|
|
{
|
|
for (int i = idx + 1; i < num_items; i++)
|
|
{
|
|
dictionary row = dataTableGetRow(BUILDABLE_STRUCTURE_DATATABLE, i);
|
|
string bf_name = row.getString(DATATABLE_COL_NAME);
|
|
string structure_faction = row.getString(DATATABLE_COL_FACTION);
|
|
if (bf_name.length() > 0)
|
|
return buildable_objects;
|
|
|
|
//LOG("LOG_CHANNEL", "structure_faction ->" + structure_faction);
|
|
if (structure_faction.equals(faction) || structure_faction.equals("ALL") || faction.equals("ANY"))
|
|
{
|
|
string structure_name = row.getString(DATATABLE_COL_BUILDING_NAME);
|
|
buildable_objects = utils.addElement(buildable_objects, structure_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (buildable_objects.length > 0)
|
|
return buildable_objects;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a dictionary of the buildable structure's
|
|
* construction stats.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param int index Index of 0 refers to the first
|
|
* structure after the battlefield name.
|
|
*
|
|
* @return dictionary keys: template, name, cost, construction_time,
|
|
* faction
|
|
*********************************************************************/
|
|
dictionary getBuildableStructureStats(obj_id master_object, int index)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
// Find the position of the object in the datatable.
|
|
int bf_idx = getBattlefieldIndex(master_object, BUILDABLE_STRUCTURE_DATATABLE);
|
|
if (bf_idx == -1)
|
|
return null;
|
|
|
|
// Check to make sure the index does not go into the next battlefield's entries
|
|
string[] buildable_structures = getBuildableStructures(master_object, "ANY");
|
|
if (index > buildable_structures.length)
|
|
return null;
|
|
|
|
int structure_idx = bf_idx + index + 1;
|
|
//LOG("LOG_CHANNEL", "struct_idx ->" + structure_idx);
|
|
|
|
int num_items = dataTableGetNumRows(BUILDABLE_STRUCTURE_DATATABLE);
|
|
if (num_items > structure_idx)
|
|
return dataTableGetRow(BUILDABLE_STRUCTURE_DATATABLE, structure_idx);
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getBuildableStructureStats. Uses template
|
|
* or name instead of index.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string template template or name of buildable structure
|
|
*
|
|
* @return dictionary keys: template, name, cost, construction_time,
|
|
* faction
|
|
*********************************************************************/
|
|
dictionary getBuildableStructureStats(obj_id master_object, string template)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
// Find the position of the object in the datatable.
|
|
int bf_idx = getBattlefieldIndex(master_object, BUILDABLE_STRUCTURE_DATATABLE);
|
|
if (bf_idx == -1)
|
|
return null;
|
|
|
|
string[] structures = getBuildableStructures(master_object, "ANY");
|
|
if (structures == null)
|
|
return null;
|
|
|
|
for (int i = 0; i < structures.length; i++)
|
|
{
|
|
dictionary stats = dataTableGetRow(BUILDABLE_STRUCTURE_DATATABLE, i + 1 + bf_idx);
|
|
if (stats.getString("template").equals(template))
|
|
return stats;
|
|
else if (stats.getString("name").equals(template))
|
|
return stats;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Attachs the battlefield's game script to the master object
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
boolean attachGameScript(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string script = GAME_SCRIPT_PATH + getBattlefieldGameType(master_object).toLowerCase();
|
|
|
|
LOG("LOG_CHANNEL", "battlefield::attachGameScript -- attaching " + script + " to " + master_object);
|
|
if (!hasScript(master_object, script))
|
|
{
|
|
attachScript(master_object, script);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Removes the battlefield's game script to the master object
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
boolean detachGameScript(obj_id master_object)
|
|
{
|
|
if (!isIdValid(master_object))
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::detachGameScript -- master_object is null");
|
|
return false;
|
|
}
|
|
|
|
string script;
|
|
string game_type = getBattlefieldGameType(master_object);
|
|
if (game_type != null)
|
|
script = GAME_SCRIPT_PATH + game_type.toLowerCase();
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::detachGameScript -- game_type is null for " + master_object);
|
|
return false;
|
|
}
|
|
|
|
LOG("LOG_CHANNEL", "battlefield::detachGameScript -- detaching " + script + " to " + master_object);
|
|
if (hasScript(master_object, script))
|
|
{
|
|
detachScript(master_object, script);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's chatroom root name
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getChatRoomName(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string bf_name = getBattlefieldName(master_object);
|
|
string chat_name = "SWG." + getGalaxyName() + "." + getCurrentSceneName() + ".battlefield." + bf_name;
|
|
|
|
return chat_name;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's all faction chatroom root name
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getChatRoomNameAllFactions(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
return getChatRoomName(master_object) + ".allFactions";
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a faction's battlefield chatroom root name
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getChatRoomNameFaction(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
return getChatRoomName(master_object) + "." + faction;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the number of registered kills for a given faction
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getFactionKills(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
string objVar_team_kills = VAR_KILLS + faction;
|
|
if (hasObjVar(master_object, objVar_team_kills))
|
|
return getIntObjVar(master_object, objVar_team_kills);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the number of deaths for a given faction
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getFactionDeaths(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
string objVar_team_deaths = VAR_DEATHS + faction;
|
|
if (hasObjVar(master_object, objVar_team_deaths))
|
|
return getIntObjVar(master_object, objVar_team_deaths);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the participants in the battlefield game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return obj_id[] null on error or no game in progress
|
|
*********************************************************************/
|
|
obj_id[] getParticipantsOnBattlefield(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(master_object, VAR_PARTICIPANTS))
|
|
return utils.getObjIdBatchObjVar(master_object, VAR_PARTICIPANTS);
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getParticipantsOnBattlefield
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return obj_id[] null on error or no game in progress
|
|
*********************************************************************/
|
|
obj_id[] getParticipantsOnBattlefield(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getParticipantsOnBattlefield(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the specified faction's team in the battlefield game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return obj_id[] null on fail
|
|
*********************************************************************/
|
|
obj_id[] getFactionTeam(obj_id master_object, string faction)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.getFactionTeam");
|
|
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
obj_id[] players = getPlayersOnBattlefield(master_object);
|
|
resizeable obj_id[] faction_team = new obj_id[0];
|
|
if (players != null)
|
|
{
|
|
for (int i = 0; i < players.length; i++)
|
|
{
|
|
string player_faction = getPlayerTeamFaction(players[i]);
|
|
if (player_faction != null)
|
|
{
|
|
if (player_faction.equals(faction))
|
|
faction_team = utils.addElement(faction_team, players[i]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return null;
|
|
|
|
return faction_team;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getFactionTeam
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return obj_id[] null on error or no game in progress
|
|
*********************************************************************/
|
|
obj_id[] getFactionTeam(region r, string faction)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getFactionTeam(master_object, faction);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's player allowed factions
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getFactionsAllowed(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
return getStringArrayObjVar(master_object, VAR_FACTIONS_ALLOWED);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getFactionsAllowed
|
|
*
|
|
* @param region r
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getFactionsAllowed(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getFactionsAllowed(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the player factions remaining in a game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getFactionsRemaining(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(master_object, VAR_FACTIONS_REMAINING))
|
|
{
|
|
return getStringArrayObjVar(master_object, VAR_FACTIONS_REMAINING);
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the ai factions allowed in a game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getAIFactionsAllowed(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(master_object, VAR_FACTIONS_AI_ALLOWED))
|
|
{
|
|
return getStringArrayObjVar(master_object, VAR_FACTIONS_AI_ALLOWED);
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the ai factions remaining in a game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getAIFactionsRemaining(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(master_object, VAR_FACTIONS_AI_REMAINING))
|
|
{
|
|
return getStringArrayObjVar(master_object, VAR_FACTIONS_AI_REMAINING);
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a list of both ai and player factions remaining
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getAllFactionsRemaining(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string[] factions_remaining_array = getFactionsRemaining(master_object);
|
|
resizeable string[] factions_remaining = factions_remaining_array;
|
|
string[] ai_factions = getAIFactionsRemaining(master_object);
|
|
|
|
if (factions_remaining != null && ai_factions != null)
|
|
{
|
|
factions_remaining = utils.concatArrays(factions_remaining, ai_factions);
|
|
return factions_remaining;
|
|
}
|
|
|
|
else if (ai_factions == null)
|
|
return factions_remaining;
|
|
|
|
else if (factions_remaining == null)
|
|
return ai_factions;
|
|
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getAllFactionsRemaining -- there are no factions remaining for " + master_object);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a list of both ai and player factions allowed
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return string[] null on fail
|
|
*********************************************************************/
|
|
string[] getAllFactionsAllowed(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string[] factions_allowed_array = getFactionsAllowed(master_object);
|
|
resizeable string[] factions_allowed = factions_allowed_array;
|
|
string[] ai_factions = getAIFactionsAllowed(master_object);
|
|
|
|
if (factions_allowed != null && ai_factions != null)
|
|
{
|
|
factions_allowed = utils.concatArrays(factions_allowed, ai_factions);
|
|
return factions_allowed;
|
|
}
|
|
|
|
else if (ai_factions == null)
|
|
return factions_allowed;
|
|
|
|
else if (factions_allowed == null)
|
|
return ai_factions;
|
|
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getAllFactionsRemaining -- there are no factions remaining for " + master_object);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a faction id from the string
|
|
*
|
|
* @param string faction
|
|
*
|
|
* @return return int
|
|
*********************************************************************/
|
|
int getFactionId(string faction)
|
|
{
|
|
int faction_num = factions.getFactionNumber(faction);
|
|
if (faction_num == -1)
|
|
return 0;
|
|
|
|
int faction_id = dataTableGetInt("datatables/faction/faction.iff", faction_num, "pvpFaction");
|
|
|
|
return faction_id;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's minimum game restart time
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameRestartMinimum(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
return getIntObjVar(master_object, VAR_RESTART_TIME_MIN);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns the battlefield's maximum game restart time
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getGameRestartMaximum(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
return getIntObjVar(master_object, VAR_RESTART_TIME_MAX);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns a faction's build point total
|
|
*
|
|
* @param obj_id master_object
|
|
* @params string faction
|
|
*
|
|
* @return int -1 on fail
|
|
*********************************************************************/
|
|
int getFactionBuildPoints(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
string objVar_name = VAR_BUILD_POINTS + faction;
|
|
if (hasObjVar(master_object, objVar_name))
|
|
return getIntObjVar(master_object, objVar_name);
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief returns all of the objects in the battlefield marked
|
|
* as game critical.
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return obj_id[] null on fail
|
|
*********************************************************************/
|
|
obj_id[] getGameCriticalObjects(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
resizeable obj_id[] critical_items = new obj_id[0];
|
|
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
obj_id[] items = pvpBattlefieldGetParticipantsForFaction(bf, 0);
|
|
|
|
if (items != null)
|
|
{
|
|
for (int i = 0; i < items.length; i++)
|
|
{
|
|
// only critical items have the game critical objvar
|
|
if (hasObjVar(items[i], VAR_GAME_CRITICAL))
|
|
critical_items = utils.addElement(critical_items, items[i]);
|
|
}
|
|
}
|
|
|
|
if (critical_items.length > 0)
|
|
return critical_items;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief gets all players within the battlefield. Performs an
|
|
* extensive search of the entire battlefield.
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return obj_id[] null on fail
|
|
*********************************************************************/
|
|
obj_id[] getPlayersOnBattlefieldComplete(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
float radius = getBattlefieldExtent(master_object);
|
|
// The master object is always at the center of the battlefield
|
|
location loc = getLocation(master_object);
|
|
resizeable obj_id[] players = new obj_id[0];
|
|
obj_id[] items = getObjectsInRange(loc, radius);
|
|
if (items != null)
|
|
{
|
|
for (int i = 0; i < items.length; i++)
|
|
{
|
|
if (isPlayer(items[i]))
|
|
players = utils.addElement(players, items[i]);
|
|
else if (player_structure.isBuilding(items[i]))
|
|
{
|
|
// Look for players inside each building.
|
|
obj_id[] player_building = player_structure.getPlayersInBuilding(items[i]);
|
|
if (player_building != null)
|
|
players = utils.concatArrays(players, player_building);
|
|
}
|
|
}
|
|
}
|
|
return players;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief gets all players within the battlefield. Using the prebuilt
|
|
* list. Does not search through everything in the battlefield.
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return obj_id[] null on fail
|
|
*********************************************************************/
|
|
obj_id[] getPlayersOnBattlefield(obj_id master_object)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD))
|
|
{
|
|
obj_id[] players = utils.getObjIdBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
if (players == null || players.length < 1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.getPlayersOnBattlefield -- players is null.");
|
|
return null;
|
|
}
|
|
resizeable obj_id[] loaded_players = new obj_id[0];
|
|
// Only return the players that are loaded. Disconnected players don't trigger
|
|
for (int i = 0; i < players.length; i++)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getPlayersOnBattlefield -- players[" + i + "] ->" + players[i]);
|
|
if (players[i].isLoaded())
|
|
loaded_players = utils.addElement(loaded_players, players[i]);
|
|
}
|
|
if (loaded_players.length < 0)
|
|
return null;
|
|
else
|
|
return loaded_players;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for getPlayersOnBattlefield
|
|
*
|
|
* @param region r battlefield
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
obj_id[] getPlayersOnBattlefield(region r)
|
|
{
|
|
if (r == null)
|
|
return null;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return getPlayersOnBattlefield(master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the player's declared battlefield faction
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return string null on fail
|
|
*********************************************************************/
|
|
string getPlayerTeamFaction(obj_id player)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(player, VAR_TEAM_FACTION))
|
|
return getStringObjVar(player, VAR_TEAM_FACTION);
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the master object of the battlefield a player entered
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return obj_id null on fail
|
|
*********************************************************************/
|
|
obj_id getBattlefieldEntered(obj_id player)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
if (hasObjVar(player, VAR_BATTLEFIELD_ENTERED))
|
|
return getObjIdObjVar(player, VAR_BATTLEFIELD_ENTERED);
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns the battlefield's location in the datatable
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return int -1 on fail or no match
|
|
*********************************************************************/
|
|
int getBattlefieldIndex(obj_id master_object, string datatable)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
int numItems = dataTableGetNumRows(datatable);
|
|
string bf_name = getBattlefieldName(master_object);
|
|
string bf_area = getCurrentSceneName();
|
|
|
|
for (int i = 0; i < numItems; i++)
|
|
{
|
|
string name = dataTableGetString(datatable, i, DATATABLE_COL_NAME);
|
|
|
|
if (datatable == BATTLEFIELD_DATATABLE)
|
|
{
|
|
// Check for area and name for the battlefield table.
|
|
string area = dataTableGetString(datatable, i, DATATABLE_COL_AREA);
|
|
if (area.equals(bf_area))
|
|
{
|
|
if (name.equals(bf_name))
|
|
return i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Otherwise, just check for the name.
|
|
if (name.equals(bf_name))
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Gets a faction's starting location
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return location null on fail or if there is no starting location
|
|
*********************************************************************/
|
|
location getFactionStartLocation(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
|
|
if (faction == null)
|
|
return null;
|
|
|
|
int idx = utils.getElementPositionInArray(factions_allowed, faction);
|
|
|
|
if (idx == -1)
|
|
return null;
|
|
|
|
location[] start_locations = getLocationArrayObjVar(master_object, VAR_START_LOCATIONS);
|
|
location loc = start_locations[idx];
|
|
|
|
// If all three coordinates are 0, then the starting location was not specified.
|
|
if (loc.x == 0.0f && loc.y == 0.0f && loc.z == 0.0f)
|
|
return null;
|
|
else
|
|
return loc;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Returns a dictionary of data for a given spawner
|
|
*
|
|
* @param string spawner_name reference name used in the battlefield
|
|
* datatables.
|
|
*
|
|
* @return dictionary "spawn_template" - string array of templates to spawn
|
|
* "min_number" - int array of minimum number to spawn
|
|
* "max_number" - int array of maximum number to spawn
|
|
* "weight" - int array of probability weights
|
|
*********************************************************************/
|
|
dictionary getSpawnerData(string spawner_name)
|
|
{
|
|
//LOG("LOG_CHANNEL", "spawner_name ->" + spawner_name);
|
|
|
|
if (spawner_name == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getSpawnerData -- spawner_name is null");
|
|
return null;
|
|
}
|
|
|
|
int idx = dataTableSearchColumnForString(spawner_name, DATATABLE_COL_SPAWNER_TYPE, SPAWNER_DATATABLE);
|
|
//LOG("LOG_CHANNEL", "idx ->" + idx);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::getSpawnerData -- unable to find an entry for " + spawner_name);
|
|
return null;
|
|
}
|
|
|
|
int num_items = dataTableGetNumRows(SPAWNER_DATATABLE);
|
|
resizeable string[] spawn_template = new string[0];
|
|
resizeable int[] min_number = new int[0];
|
|
resizeable int[] max_number = new int[0];
|
|
resizeable int[] weight = new int[0];
|
|
for (int i = idx + 1; i < num_items; i++)
|
|
{
|
|
//LOG("LOG_CHANNEL", "battlefield::getSpawnerData -- " + i);
|
|
dictionary row = dataTableGetRow(SPAWNER_DATATABLE, i);
|
|
|
|
// When the next spawner name is reached, we've gotten everything there is to get.
|
|
if (row.getString(DATATABLE_COL_SPAWNER_TYPE).length() > 0)
|
|
break;
|
|
else
|
|
{
|
|
spawn_template = utils.addElement(spawn_template, row.getString(DATATABLE_COL_SPAWNER_TEMPLATE));
|
|
min_number = utils.addElement(min_number, row.getInt(DATATABLE_COL_SPAWNER_MIN_NUMBER));
|
|
max_number = utils.addElement(max_number, row.getInt(DATATABLE_COL_SPAWNER_MAX_NUMBER));
|
|
weight = utils.addElement(weight, row.getInt(DATATABLE_COL_SPAWNER_WEIGHT));
|
|
}
|
|
}
|
|
|
|
dictionary spawn_data = new dictionary();
|
|
spawn_data.put("spawn_template", spawn_template);
|
|
spawn_data.put("min_number", min_number);
|
|
spawn_data.put("max_number", max_number);
|
|
spawn_data.put("weight", weight);
|
|
|
|
return spawn_data;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Creates random spawn for the specified spawner
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string spawner_name reference name used in the battlefield
|
|
* datatables.
|
|
*
|
|
* @return obj_id[] returns the creatures spawned.
|
|
*********************************************************************/
|
|
obj_id[] createRandomSpawn(obj_id master_object, obj_id spawner)
|
|
{
|
|
//LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- spawner ->" + spawner + " master_object ->" + master_object);
|
|
|
|
if (spawner == null || spawner == obj_id.NULL_ID)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- spawner is null.");
|
|
return null;
|
|
}
|
|
|
|
int max_population = getIntObjVar(spawner, VAR_SPAWNER_MAX_POPULATION);
|
|
int max_spawn = getIntObjVar(spawner, VAR_SPAWNER_MAX);
|
|
|
|
int current_population = 0;
|
|
if (hasObjVar(spawner, VAR_SPAWNER_CURRENT_POPULATION))
|
|
current_population = getIntObjVar(spawner, VAR_SPAWNER_CURRENT_POPULATION);
|
|
|
|
int current_spawn = 0;
|
|
if (hasObjVar(spawner, VAR_SPAWNER_CURRENT))
|
|
current_spawn = getIntObjVar(spawner, VAR_SPAWNER_CURRENT);
|
|
|
|
if (current_population >= max_population)
|
|
{
|
|
// Population can never exceed the maximum
|
|
//LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- Max population already reached for " + spawner);
|
|
return null;
|
|
}
|
|
|
|
if (current_spawn >= max_spawn)
|
|
{
|
|
// Population can never exceed the maximum
|
|
//LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- Max number of spawns already reached for " + spawner);
|
|
return null;
|
|
}
|
|
|
|
string spawner_type = getStringObjVar(spawner, VAR_SPAWNER_TYPE);
|
|
dictionary spawn_data = getSpawnerData(spawner_type);
|
|
|
|
//LOG("LOG_CHANNEL", "spawn_data ->" + spawn_data);
|
|
|
|
if (spawn_data == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- spawn_data is null for " + spawner);
|
|
return null;
|
|
}
|
|
|
|
string[] spawn_template = spawn_data.getStringArray("spawn_template");
|
|
int[] min_number = spawn_data.getIntArray("min_number");
|
|
int[] max_number = spawn_data.getIntArray("max_number");
|
|
int[] weight = spawn_data.getIntArray("weight");
|
|
|
|
if (spawn_template == null || min_number == null || max_number == null || weight == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- spawn data contains a null array.");
|
|
return null;
|
|
}
|
|
|
|
// Determine which template to use based on the probability weights
|
|
int total_weight = 0;
|
|
for (int i = 0; i < weight.length; i++)
|
|
{
|
|
// Find the total of all weight probabilities.
|
|
total_weight = total_weight + weight[i];
|
|
}
|
|
|
|
//LOG("LOG_CHANNEL", "total_weight ->" + total_weight);
|
|
|
|
if (total_weight < 1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- total probility weight is < 1 for " + spawner);
|
|
return null;
|
|
}
|
|
|
|
int weight_index = rand(1, total_weight);
|
|
|
|
//LOG("LOG_CHANNEL", "weight_index ->" + weight_index);
|
|
|
|
int array_index = -1;
|
|
for (int i = 0; i < weight.length; i++)
|
|
{
|
|
// Turn the weight_index into an array index.
|
|
weight_index = weight_index - weight[i];
|
|
if (weight_index < 1)
|
|
{
|
|
array_index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//LOG("LOG_CHANNEL", "array_index ->" + array_index);
|
|
if (array_index == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- unable to find an array index for " + spawner);
|
|
return null;
|
|
}
|
|
|
|
// Now that we've got the index, create the critters.
|
|
int num_spawn = rand(min_number[array_index], max_number[array_index]);
|
|
string template = spawn_template[array_index];
|
|
location spawner_loc = getLocation(spawner);
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
int faction_id = pvpBattlefieldGetFaction(spawner, bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
resizeable obj_id[] spawned_mobs = new obj_id[0];
|
|
|
|
//LOG("LOG_CHANNEL", "num_spawn ->" + num_spawn + " template ->" + template);
|
|
|
|
while (num_spawn > 0)
|
|
{
|
|
if (max_population > current_population)
|
|
{
|
|
location spawn_loc = utils.getRandomAwayLocation(spawner_loc, 5.0f, 10.0f);
|
|
obj_id mob = addBattlefieldMob(master_object, template, spawn_loc, faction);
|
|
wander(mob);
|
|
|
|
//LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- " + mob + " created.");
|
|
spawned_mobs = utils.addElement(spawned_mobs, mob);
|
|
|
|
// Mark it as battlefield constructed
|
|
setObjVar(mob, battlefield.VAR_CONSTRUCTED, 1);
|
|
|
|
// Keep track of the spawner and battlefield where the mob originated.
|
|
setObjVar(mob, VAR_SPAWNED_BY, spawner);
|
|
setObjVar(mob, VAR_SPAWNED_BATTLEFIELD, master_object);
|
|
|
|
//LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- mob ->" + mob);
|
|
|
|
current_population++;
|
|
num_spawn--;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
|
|
if (spawned_mobs.length < 1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::createRandomSpawn -- unable to create spawn for " + spawner);
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
setObjVar(spawner, VAR_SPAWNER_CURRENT_POPULATION, current_population);
|
|
setObjVar(spawner, VAR_SPAWNER_CURRENT, current_spawn + 1);
|
|
return spawned_mobs;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Sends a chat message to the battlefield players.
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean false on fail
|
|
*********************************************************************/
|
|
boolean sendBattlefieldMessage(obj_id master_object, string text)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string chatroom = getChatRoomNameAllFactions(master_object);
|
|
LOG("LOG_CHANNEL", "chatroom ->" + chatroom);
|
|
chatSendToRoom(chatroom, text, "");
|
|
LOG("LOG_CHANNEL", master_object + " (Battlefield Message) ->" + text);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for sendBattlefieldMessage
|
|
*
|
|
* @param region r battlefield
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean sendBattlefieldMessage(region r, string text)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return sendBattlefieldMessage(master_object, text);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Sends a chat message to a specified faction
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean false on fail
|
|
*********************************************************************/
|
|
boolean sendFactionMessage(obj_id master_object, string faction, string text)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
int idx = utils.getElementPositionInArray(factions_allowed, faction);
|
|
if (idx != -1)
|
|
{
|
|
string chatroom = getChatRoomNameFaction(master_object, faction);
|
|
chatSendToRoom(chatroom, text, "");
|
|
LOG("LOG_CHANNEL", master_object + " (Battlefield " + faction + " Message) ->" + text);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload for sendFactionMessage
|
|
*
|
|
* @param region r battlefield
|
|
*
|
|
* @return boolean
|
|
***********************************************************************/
|
|
boolean sendFactionMessage(region r, string faction, string text)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return sendFactionMessage(master_object, faction, text);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief records a kill during a battlefield game.
|
|
*
|
|
* @param obj_id killer player who scored the kill.
|
|
* @param obj_id victim player who was killed.
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean false on fail
|
|
*********************************************************************/
|
|
boolean registerBattlefieldKill(obj_id killer, obj_id victim, obj_id master_object)
|
|
{
|
|
if (killer == null || killer == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
if (victim == null || victim == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!isBattlefieldActive(master_object))
|
|
return false;
|
|
|
|
// Give credit for the kill
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
if (isMob(killer) && isMob(victim))
|
|
{
|
|
if (killer != victim)
|
|
{
|
|
int faction_id = pvpBattlefieldGetFaction(killer, bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
if (faction == null)
|
|
return false;
|
|
|
|
int faction_kills = 0;
|
|
string objVar_team_kills = VAR_KILLS + faction;
|
|
if (hasObjVar(master_object, objVar_team_kills))
|
|
faction_kills = getIntObjVar(master_object, objVar_team_kills);
|
|
|
|
faction_kills++;
|
|
setObjVar(master_object, objVar_team_kills, faction_kills);
|
|
}
|
|
}
|
|
|
|
// Put a death on the faction of the victim
|
|
if (isMob(victim))
|
|
{
|
|
int faction_id = pvpBattlefieldGetFaction(victim, bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
if (faction == null)
|
|
return false;
|
|
|
|
int faction_deaths = 0;
|
|
string objVar_team_deaths = VAR_DEATHS + faction;
|
|
if (hasObjVar(master_object, objVar_team_deaths))
|
|
faction_deaths = getIntObjVar(master_object, objVar_team_deaths);
|
|
|
|
faction_deaths++;
|
|
setObjVar(master_object, objVar_team_deaths, faction_deaths);
|
|
}
|
|
|
|
// Send a message enabling the specific game script to do its thing with the kill.
|
|
dictionary params = new dictionary();
|
|
params.put("killer", killer);
|
|
params.put("victim", victim);
|
|
messageTo(master_object, "msgBattlefieldKill", params, 0.0f, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Adds a player to the player list.
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id master_object
|
|
*
|
|
* @return bolean
|
|
*********************************************************************/
|
|
boolean addPlayerToPlayerList(obj_id player, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
resizeable obj_id[] players = new obj_id[0];
|
|
if (hasObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD))
|
|
//players = getResizeableObjIdArrayObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
players = utils.getResizeableObjIdBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
|
|
int idx = utils.getElementPositionInArray(players, player);
|
|
if (idx != -1)
|
|
return false;
|
|
else
|
|
{
|
|
players = utils.addElement(players, player);
|
|
//setObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD, players);
|
|
removeObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
utils.setResizeableBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD, players);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Removes a player to the player list.
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id master_object
|
|
*
|
|
* @return bolean
|
|
*********************************************************************/
|
|
boolean removePlayerFromPlayerList(obj_id player, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!hasObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD))
|
|
return false;
|
|
|
|
resizeable obj_id[] players = utils.getResizeableObjIdBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
//resizeable obj_id[] players = utils.getResizeableObjIdBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
int idx = utils.getElementPositionInArray(players, player);
|
|
if (idx == -1)
|
|
return false;
|
|
else
|
|
{
|
|
players = utils.removeElementAt(players, idx);
|
|
//setObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD, players);
|
|
removeObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD);
|
|
utils.setResizeableBatchObjVar(master_object, VAR_PLAYERS_IN_BATTLEFIELD, players);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Adds a player to the specified team
|
|
*
|
|
* @param obj_id player
|
|
* @param string faction
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean addPlayerToTeam(obj_id player, string faction, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string player_faction = getPlayerTeamFaction(player);
|
|
if (player_faction != null)
|
|
return false;
|
|
|
|
//obj_id[] participants_array = getParticipantsOnBattlefield(master_object);
|
|
resizeable obj_id[] participants = new obj_id[0];
|
|
if (hasObjVar(master_object, battlefield.VAR_PARTICIPANTS))
|
|
participants = utils.getResizeableObjIdBatchObjVar(master_object, battlefield.VAR_PARTICIPANTS);
|
|
|
|
int part_idx = utils.getElementPositionInArray(participants, player);
|
|
if (part_idx == -1)
|
|
participants = utils.addElement(participants, player);
|
|
|
|
string[] factions_allowed = getStringArrayObjVar(master_object, VAR_FACTIONS_ALLOWED);
|
|
int idx = utils.getElementPositionInArray(factions_allowed, faction);
|
|
if (idx == -1)
|
|
return false;
|
|
|
|
utils.setResizeableBatchObjVar(master_object, VAR_PARTICIPANTS, participants);
|
|
//setObjVar(master_object, VAR_PARTICIPANTS, participants);
|
|
setObjVar(player, VAR_TEAM_FACTION, faction); // Suppress linting - Lint script is incorrectly
|
|
// catching this due to a similarly named array
|
|
if (movePlayerToStartLocation(player, master_object))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You have been moved to your faction's starting location. Good luck!");
|
|
sendSystemMessageTestingOnly(player, "You have been moved to your faction's starting location. Good luck!");
|
|
sendSystemMessageTestingOnly(player, "Note: use /battlefieldStatus to check on your faction's progress and /placeBattlefieldStructure to build.");
|
|
}
|
|
|
|
// Register the player with the PVP Battlefield system
|
|
region reg = getRegionFromMasterObject(master_object);
|
|
pvpBattlefieldSetParticipant(player, reg, getFactionId(faction));
|
|
|
|
// Mark the player has having entered the battlefield.
|
|
//setBattlefieldEntered(player, master_object);
|
|
|
|
// Give the player any battlefield waypoints.
|
|
//giveBattlefieldWaypoints(master_object, player);
|
|
|
|
// Add the player to the all faction battlefield chatroom.
|
|
dictionary params = new dictionary();
|
|
string chat_room = battlefield.getChatRoomNameAllFactions(master_object);
|
|
params.put("chat_room", chat_room);
|
|
messageTo(player, "msgJoinBattlefieldChat", params, 0.0f, false);
|
|
|
|
// Add player to the team chat channel. No need to join a faction chat channel
|
|
// if there's only one player faction.
|
|
if (factions_allowed.length > 1)
|
|
{
|
|
dictionary params_team = new dictionary();
|
|
string chat_room_team = battlefield.getChatRoomNameFaction(master_object, faction);
|
|
params_team.put("chat_room", chat_room_team);
|
|
messageTo(player, "msgJoinBattlefieldChat", params_team, 0.0f, false);
|
|
}
|
|
|
|
sendFactionMessage(master_object, faction, getFirstName(player) + " has joined the team.");
|
|
|
|
// Give the specific game script a chance to do something.
|
|
dictionary params_player = new dictionary();
|
|
params_player.put("player", player);
|
|
params_player.put("faction", faction);
|
|
messageTo(master_object, "msgAddPlayerToBattlefield", params_player, 3.0f, false);
|
|
|
|
LOG("LOG_CHANNEL", "battlefield::addPlayerToTeam -- added " + player);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overload addPlayerToTeam
|
|
*
|
|
* @param obj_id player
|
|
* @param string faction
|
|
* @param region r
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean addPlayerToTeam(obj_id player, string faction, region r)
|
|
{
|
|
if (r == null)
|
|
return false;
|
|
|
|
obj_id master_object = getMasterObjectFromRegion(r);
|
|
|
|
return addPlayerToTeam(player, faction, master_object);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Moves a player to his faction's starting location
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean movePlayerToStartLocation(obj_id player, obj_id master_object)
|
|
{
|
|
LOG("LOG_CHANNEL", "movePlayerToStartLocation --" + player + " " + master_object);
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string faction = getPlayerTeamFaction(player);
|
|
|
|
location start_loc = getFactionStartLocation(master_object, faction);
|
|
|
|
if (start_loc == null)
|
|
return false;
|
|
|
|
// Get a random location around the area.
|
|
location rand_loc = utils.getRandomAwayLocation(start_loc, MIN_START_LOCATION_TOLERANCE, MAX_START_LOCATION_TOLERANCE);
|
|
|
|
setLocation(player, rand_loc);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Expels the player from the battlefield
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean expelPlayerFromBattlefield(obj_id player, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
setObjVar(player, VAR_EXPELLED, 1);
|
|
expelFromTriggerVolume(master_object, STRING_TRIG_OUTER_PERIMETER, player);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Expels the player from the battlefield
|
|
*
|
|
* @param obj_id player
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean removeFactionItems(obj_id player)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
// If the player is declared, he can keep his battlefield items equipped.
|
|
int pvp_type = pvpGetType(player);
|
|
if (pvp_type == PVPTYPE_DECLARED)
|
|
return true;
|
|
|
|
factions.unequipFactionEquipment(player, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Decrements or resets the battlefield timer
|
|
*
|
|
* @param obj_id master_object
|
|
* @param boolean reset true decrements the timer at the pulse
|
|
* interval. False resets it.
|
|
*
|
|
* @return int time remaining. 0 if time expired, -1 on error.
|
|
*********************************************************************/
|
|
int setGameTimer(obj_id master_object, boolean reset)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return -1;
|
|
|
|
if (reset)
|
|
{
|
|
int game_time = getGameDuration(master_object);
|
|
setObjVar(master_object, VAR_TIME_REMAINING, game_time);
|
|
return game_time;
|
|
}
|
|
else
|
|
{
|
|
if (hasObjVar(master_object, VAR_TIME_REMAINING))
|
|
{
|
|
int time_remaining = getIntObjVar(master_object, VAR_TIME_REMAINING);
|
|
time_remaining = time_remaining - GAME_TIME_PULSE;
|
|
setObjVar(master_object, VAR_TIME_REMAINING, time_remaining);
|
|
if (time_remaining < 1)
|
|
return 0;
|
|
else
|
|
return time_remaining;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Marks the player as having entered the battlefield
|
|
*
|
|
* @param obj_id player
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean false on error
|
|
*********************************************************************/
|
|
boolean setBattlefieldEntered(obj_id player, obj_id master_object)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
setObjVar(player, VAR_BATTLEFIELD_ENTERED, master_object);
|
|
setObjVar(player, VAR_TIME_ENTERED, getGameTime());
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Decrements a faction's build points
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
* @param int amt Amount to decrement
|
|
*
|
|
* @return boolean false on fail or insufficient amount
|
|
*********************************************************************/
|
|
boolean decrementFactionBuildPoints(obj_id master_object, string faction, int amt)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (amt < 1)
|
|
return false;
|
|
|
|
int build_points = getFactionBuildPoints(master_object, faction);
|
|
if (amt > build_points)
|
|
return false;
|
|
|
|
build_points = build_points - amt;
|
|
string objVar_name = VAR_BUILD_POINTS + faction;
|
|
setObjVar(master_object, objVar_name, build_points);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Increases a faction's build points
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
* @param int amt Amount to decrement
|
|
*
|
|
* @return boolean false on fail
|
|
*********************************************************************/
|
|
boolean incrementFactionBuildPoints(obj_id master_object, string faction, int amt)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (amt < 1)
|
|
return false;
|
|
|
|
int build_points = getFactionBuildPoints(master_object, faction);
|
|
if (build_points == -1)
|
|
return false;
|
|
|
|
build_points = build_points + amt;
|
|
string objVar_name = VAR_BUILD_POINTS + faction;
|
|
setObjVar(master_object, objVar_name, build_points);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Spends a player's faction points.
|
|
*
|
|
* @param obj_id player
|
|
* @param float amt Amount to spend
|
|
*
|
|
* @return boolean false on fail or insufficient funds
|
|
*********************************************************************/
|
|
boolean spendFactionPoints(obj_id player, float amt)
|
|
{
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (amt < 1)
|
|
return false;
|
|
|
|
string faction = getPlayerTeamFaction(player);
|
|
if (faction == null)
|
|
return false;
|
|
|
|
float points = factions.getFactionStanding(player, faction);
|
|
|
|
// The player can never go below the faction minimum if declared. Treat that as the zero point.
|
|
int declared_faction = pvpGetAlignedFaction(player);
|
|
if (declared_faction != 0)
|
|
points = points - factions.FACTION_RATING_DECLARABLE_MIN;
|
|
|
|
if (amt > points)
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You do not have enough faction points remaining.");
|
|
sendSystemMessageTestingOnly(player, "You do not have enough faction points remaining.");
|
|
if (declared_faction != 0)
|
|
sendSystemMessageTestingOnly(player, "Note that your faction may not go below the " + factions.FACTION_RATING_DECLARABLE_MIN + " declared minimum.");
|
|
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
factions.addFactionStanding(player, faction, amt * -1);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Eliminates a team from the game.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param string faction
|
|
*
|
|
* @return boolean false on error
|
|
*********************************************************************/
|
|
boolean eliminateFaction(obj_id master_object, string faction)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
string[] factions_remaining_array = getFactionsRemaining(master_object);
|
|
resizeable string[] factions_remaining = factions_remaining_array;
|
|
if (factions_remaining == null)
|
|
return false;
|
|
|
|
int idx = utils.getElementPositionInArray(factions_remaining, faction);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.eliminateFaction -- eliminate ai faction " + faction);
|
|
// check the ai factions remaining.
|
|
string[] ai_factions_array = getAIFactionsRemaining(master_object);
|
|
resizeable string[] ai_factions = ai_factions_array;
|
|
int ai_idx = utils.getElementPositionInArray(ai_factions, faction);
|
|
if (ai_idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::eliminateFaction -- cannot find " + faction + " in " + master_object);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
ai_factions = utils.removeElementAt(ai_factions, idx);
|
|
if(ai_factions.length > 0) { // Zero length array check
|
|
|
|
setObjVar(master_object, VAR_FACTIONS_AI_REMAINING, ai_factions);
|
|
|
|
} else {
|
|
|
|
if(hasObjVar(master_object, VAR_FACTIONS_AI_REMAINING)) {
|
|
|
|
removeObjVar(master_object, VAR_FACTIONS_AI_REMAINING);
|
|
}
|
|
}
|
|
|
|
// Remove the ai opponents of the faction.
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
obj_id[] base_objects = pvpBattlefieldGetParticipantsForFaction(bf, 0);
|
|
if (base_objects != null)
|
|
{
|
|
for (int i = 0; i < base_objects.length; i++)
|
|
{
|
|
// We only want to remove the spawned creatures.
|
|
if (isBattlefieldSpawned(base_objects[i]))
|
|
{
|
|
// We don't use removeBattlefieldObject here. Spawned creatures
|
|
// must be destroyed directly. They clean up themselves.
|
|
destroyObject(base_objects[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
sendBattlefieldMessage(master_object, "The " + faction + " faction has been eliminated from the battle.");
|
|
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield.eliminateFaction -- eliminate player faction " + faction);
|
|
// remove faction from faction remaining.
|
|
factions_remaining = utils.removeElementAt(factions_remaining, idx);
|
|
if(factions_remaining.length > 0) {
|
|
|
|
setObjVar(master_object, VAR_FACTIONS_REMAINING, factions_remaining);
|
|
|
|
} else {
|
|
|
|
if(hasObjVar(master_object, VAR_FACTIONS_REMAINING)) {
|
|
|
|
removeObjVar(master_object, VAR_FACTIONS_REMAINING);
|
|
}
|
|
}
|
|
|
|
// Remove faction members from the battlefield.
|
|
sendFactionMessage(master_object, faction, "Your faction has been eliminated from the battle.");
|
|
obj_id[] faction_team = getFactionTeam(master_object, faction);
|
|
if (faction_team != null)
|
|
{
|
|
for (int i = 0; i < faction_team.length; i++)
|
|
expelPlayerFromBattlefield(faction_team[i], master_object);
|
|
}
|
|
|
|
sendBattlefieldMessage(master_object, "The " + faction + " faction has been eliminated from the battle.");
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Starts a new game
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean startBattlefield(obj_id master_object)
|
|
{
|
|
LOG("LOG_CHANNEL", "Starting battlefield game for " + master_object);
|
|
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
setGameTimer(master_object, true);
|
|
|
|
// Expel everyone inside the battlefield at the start of the game.
|
|
obj_id[] players = getPlayersOnBattlefield(master_object);
|
|
if (players != null)
|
|
{
|
|
for (int i = 0; i < players.length; i++)
|
|
expelPlayerFromBattlefield(players[i], master_object);
|
|
}
|
|
|
|
// Create battlefield objects
|
|
int idx = getBattlefieldIndex(master_object, BATTLEFIELD_DATATABLE);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::startBattlefield -- Unable to find the index for " + master_object);
|
|
return false;
|
|
}
|
|
|
|
createBattlefieldObjects(master_object, idx);
|
|
|
|
// Set all factions as remaining.
|
|
string[] factions_allowed = getFactionsAllowed(master_object);
|
|
if (factions_allowed != null && factions_allowed.length > 0) { // Zero length array check
|
|
|
|
setObjVar(master_object, VAR_FACTIONS_REMAINING, factions_allowed);
|
|
}
|
|
|
|
string[] factions_ai = getAIFactionsAllowed(master_object);
|
|
if (factions_ai != null && factions_ai.length > 0) { // Zero length array check
|
|
|
|
setObjVar(master_object, VAR_FACTIONS_AI_REMAINING, factions_ai);
|
|
}
|
|
|
|
// Set starting build points for each faction.
|
|
for (int i = 0; i < factions_allowed.length; i++)
|
|
{
|
|
string objVar_name = VAR_BUILD_POINTS + factions_allowed[i];
|
|
setObjVar(master_object, objVar_name, STARTING_BUILD_POINTS);
|
|
}
|
|
|
|
// Start the game time pulse.
|
|
messageTo(master_object, "msgGameTimePulse", null, (int)GAME_TIME_PULSE, false);
|
|
|
|
// Attach the game script to the battlefield object
|
|
attachGameScript(master_object);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Ends the game, doing necessary clean-up.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param boolean restart whether or not to restart another game
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean endBattlefield(obj_id master_object, boolean restart)
|
|
{
|
|
LOG("LOG_CHANNEL", "Ending battlefield game for " + master_object);
|
|
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
// Send ending message to all participants.
|
|
obj_id[] participants = getParticipantsOnBattlefield(master_object);
|
|
if (participants != null)
|
|
{
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
for (int i = 0; i < participants.length; i++)
|
|
{
|
|
|
|
dictionary end_params = new dictionary();
|
|
|
|
string chatroom = getChatRoomNameAllFactions(master_object);
|
|
end_params.put("chatroom", chatroom);
|
|
|
|
int faction_id = pvpBattlefieldGetFaction(participants[i], bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
if (faction != null)
|
|
{
|
|
string chatroom_faction = getChatRoomNameFaction(master_object, faction);
|
|
end_params.put("chatroom_faction", chatroom_faction);
|
|
}
|
|
|
|
end_params.put("master_object", master_object);
|
|
messageTo(participants[i], "msgEndBattlefieldGame", end_params, 1.0f, true);
|
|
}
|
|
}
|
|
|
|
// Clear game obj vars
|
|
if (hasObjVar(master_object, VAR_GAME))
|
|
removeObjVar(master_object, VAR_GAME);
|
|
|
|
// Stamp game end time
|
|
setObjVar(master_object, VAR_NEXT_GAME, getGameTime());
|
|
|
|
// Clean up battlefield objects.
|
|
destroyBaseObjects(master_object);
|
|
|
|
//Remove everything from the battlefield PVP permissions.
|
|
region reg = getRegionFromMasterObject(master_object);
|
|
|
|
LOG("LOG_CHANNEL", "battlefield::endBattlefield -- reg ->" + reg);
|
|
pvpBattlefieldClearParticipants(reg);
|
|
|
|
// Send message for next game start
|
|
if (restart)
|
|
{
|
|
int restart_min = getGameRestartMinimum(master_object);
|
|
int restart_max = getGameRestartMaximum(master_object);
|
|
int restart_time = rand(restart_min, restart_max);
|
|
setObjVar(master_object, VAR_NEXT_GAME, getGameTime() + restart_time);
|
|
messageTo(master_object, "msgStartGame", null, (float)restart_time, true);
|
|
}
|
|
else
|
|
{
|
|
// Setting next game to -9999 marks the battlefield as disabled.
|
|
setObjVar(master_object, VAR_NEXT_GAME, -9999);
|
|
}
|
|
|
|
//Detach the game script from the battlefield object
|
|
detachGameScript(master_object);
|
|
|
|
return true;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Overloaded for endBattlefield
|
|
*
|
|
* @param obj_id master_object
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean endBattlefield(obj_id master_object)
|
|
{
|
|
return endBattlefield(master_object, true);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Creates objects and defines start locations within the battlefield
|
|
*
|
|
* @param obj_id master_object
|
|
* @param int index datatable location to read the objects
|
|
*
|
|
* @return void
|
|
*********************************************************************/
|
|
void createBattlefieldObjects(obj_id master_object, int idx)
|
|
{
|
|
int num_items = dataTableGetNumRows(BATTLEFIELD_DATATABLE);
|
|
if (num_items > idx + 1)
|
|
{
|
|
// Look for objects immediately after the battlefield index
|
|
//resizeable obj_id[] object_list = new obj_id[0];
|
|
for (int i = idx + 1; i < num_items; i++)
|
|
{
|
|
string bf_name = dataTableGetString(BATTLEFIELD_DATATABLE, i, DATATABLE_COL_NAME);
|
|
// There are no more objects if the next battlefield is reached
|
|
if (bf_name.length() > 0)
|
|
return;
|
|
|
|
string planet = getCurrentSceneName();
|
|
dictionary object_row = dataTableGetRow(BATTLEFIELD_DATATABLE, i);
|
|
string obj_template = object_row.getString(DATATABLE_COL_OBJECT);
|
|
float x = object_row.getFloat(DATATABLE_COL_OBJECT_X);
|
|
float y = object_row.getFloat(DATATABLE_COL_OBJECT_Y);
|
|
float z = object_row.getFloat(DATATABLE_COL_OBJECT_Z);
|
|
int delta = object_row.getInt(DATATABLE_COL_OBJECT_DELTA);
|
|
float heading = object_row.getFloat(DATATABLE_COL_HEADING);
|
|
string faction = object_row.getString(DATATABLE_COL_FACTION);
|
|
string structure_type = object_row.getString(DATATABLE_COL_STRUCTURE_TYPE);
|
|
int game_critical = object_row.getInt(DATATABLE_COL_CRITICAL);
|
|
string script = object_row.getString(DATATABLE_COL_SCRIPT);
|
|
float value1 = object_row.getFloat(DATATABLE_COL_VALUE1);
|
|
float value2 = object_row.getFloat(DATATABLE_COL_VALUE2);
|
|
|
|
if (obj_template == "START_LOC")
|
|
{
|
|
// This is a start location for a faction
|
|
int jidx = utils.getElementPositionInArray(getFactionsAllowed(master_object), faction);
|
|
if (jidx != -1)
|
|
{
|
|
location faction_start;
|
|
if (delta == 1)
|
|
{
|
|
location bf_loc = getLocation(master_object);
|
|
faction_start = new location(bf_loc.x - x, bf_loc.y - y, bf_loc.z - z, planet);
|
|
}
|
|
else
|
|
faction_start = new location(x, y, z, planet);
|
|
|
|
location[] start_locations = getLocationArrayObjVar(master_object, VAR_START_LOCATIONS);
|
|
if(start_locations != null && start_locations.length > 0) { // Zero length array check
|
|
|
|
start_locations[jidx] = faction_start;
|
|
setObjVar(master_object, VAR_START_LOCATIONS, start_locations);
|
|
}
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// Determine the object's location and create it
|
|
location obj_loc;
|
|
if (delta == 1)
|
|
{
|
|
// Use delta coordinates from the battlefield center.
|
|
location bf_loc = getLocation(master_object);
|
|
obj_loc = new location(bf_loc.x - x, bf_loc.y - y, bf_loc.z - z, planet);
|
|
}
|
|
else
|
|
obj_loc = new location(x, y, z, planet);
|
|
|
|
obj_id object = createObject(obj_template, obj_loc);
|
|
//LOG("LOG_CHANNEL", "object ->" + object + " template ->" + obj_template);
|
|
//LOG("LOG_CHANNEL", "...structure_type ->" + structure_type);
|
|
|
|
if (obj_loc == null)
|
|
LOG("LOG_CHANNEL", "Unable to create " + obj_template);
|
|
else
|
|
{
|
|
if (heading != 0.0f);
|
|
setYaw(object, heading);
|
|
|
|
// Register the object with the battlefield
|
|
region reg = getRegionFromMasterObject(master_object);
|
|
int faction_id = getFactionId(faction);
|
|
//LOG("LOG_CHANNEL", "... faction ->" + faction + "faction_id ->" + faction_id);
|
|
if (faction_id != 0)
|
|
pvpBattlefieldSetParticipant(object, reg, faction_id);
|
|
|
|
// Check for special structure types
|
|
if (structure_type.length() > 0)
|
|
{
|
|
if (structure_type.equals("healing"))
|
|
{
|
|
// This is a healing station.
|
|
setObjVar(object, "healing.canhealwound", 1);
|
|
}
|
|
|
|
if (structure_type.startsWith("spawner"))
|
|
{
|
|
// This is a spawner. Spawner types are in the format "spawner_type"
|
|
int spawn_idx = dataTableSearchColumnForString(structure_type, DATATABLE_COL_SPAWNER_TYPE, SPAWNER_DATATABLE);
|
|
if (spawn_idx == -1)
|
|
LOG("LOG_CHANNEL", "battlefield::createBattlefieldObjects -- Invalid spawner type for " + object + " in battlefield " + master_object);
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", "spawn_idx ->" + spawn_idx);
|
|
dictionary spawn_row = dataTableGetRow(SPAWNER_DATATABLE, spawn_idx);
|
|
string spawner_type = spawn_row.getString(DATATABLE_COL_SPAWNER_TYPE);
|
|
int pulse = spawn_row.getInt(DATATABLE_COL_SPAWNER_PULSE);
|
|
int spawner_max = spawn_row.getInt(DATATABLE_COL_SPAWNER_MAX_SPAWN);
|
|
int population_max = spawn_row.getInt(DATATABLE_COL_SPAWNER_MAX_POPULATION);
|
|
|
|
setObjVar(object, VAR_SPAWNER_TYPE, spawner_type);
|
|
setObjVar(object, VAR_SPAWNER_PULSE, pulse);
|
|
setObjVar(object, VAR_SPAWNER_MAX, spawner_max);
|
|
setObjVar(object, VAR_SPAWNER_MAX_POPULATION, population_max);
|
|
attachScript(object, SCRIPT_BATTLEFIELD_SPAWNER);
|
|
|
|
// Set the spawner in motion.
|
|
messageTo(object, "msgBattlefieldSpawn", null, pulse, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add objvars and scripts to game critical objects
|
|
if (game_critical == 1)
|
|
{
|
|
setObjVar(object, VAR_GAME_CRITICAL, 1);
|
|
if (value1 != 0.0f)
|
|
setObjVar(object, VAR_VALUE1, value1);
|
|
|
|
if (value2 != 0.0f)
|
|
setObjVar(object, VAR_VALUE2, value2);
|
|
|
|
if (script.length() > 0)
|
|
{
|
|
attachScript(object, script);
|
|
}
|
|
}
|
|
|
|
//object_list = utils.addElement(object_list, object);
|
|
|
|
// Battlefield object script goes on every non-crit
|
|
attachScript(object, SCRIPT_BATTLEFIELD_OBJECT);
|
|
|
|
//persistObject(object);
|
|
}
|
|
|
|
// Store the list of created objects on the structure
|
|
//if (object_list.length > 0)
|
|
//{
|
|
// setObjVar(master_object, VAR_BASE_OBJECTS, object_list);
|
|
//}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Starts the construction of a buildable object.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player player that requested the construction
|
|
* @param location where the structure is to be built
|
|
* @param dictionary dictionary of buildable object stats
|
|
* (in the format of getBuildableObjectStats)
|
|
*
|
|
* @return void
|
|
*********************************************************************/
|
|
void startBuildingConstruction(obj_id master_object, obj_id player, location position, int rotation, dictionary stats)
|
|
{
|
|
LOG("LOG_CHANNEL", "battlefield::startBuildingConstruction --" + stats);
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return;
|
|
|
|
string name = stats.getString("name");
|
|
int time = stats.getInt("construction_time");
|
|
string template = stats.getString("construction_template");
|
|
int cost = stats.getInt("cost");
|
|
float height = stats.getFloat("height");
|
|
float yaw = (float)(rotation * 90);
|
|
region bf = getRegionFromMasterObject(master_object);
|
|
int faction_id = pvpBattlefieldGetFaction(player, bf);
|
|
string faction = factions.getFactionNameByHashCode(faction_id);
|
|
int repair_cost = cost / 10;
|
|
if (repair_cost < 1)
|
|
repair_cost = 1;
|
|
|
|
// Add the construction site to the battlefield
|
|
obj_id structure = addBattlefieldObject(master_object, template, position, yaw, faction);
|
|
LOG("LOG_CHANNEL", "structure ->" + structure + " template ->" + template);
|
|
if (structure == null)
|
|
return;
|
|
|
|
// Set construction site objvars.
|
|
setObjVar(structure, VAR_BUILDTIME, time);
|
|
setObjVar(structure, VAR_TIMESTAMP, getGameTime());
|
|
setObjVar(structure, VAR_NAME, name);
|
|
setObjVar(structure, VAR_REPAIR_COST, repair_cost);
|
|
setObjVar(structure, VAR_HEIGHT, height);
|
|
|
|
// Send a message on building completion.
|
|
stats.put("player", player);
|
|
messageTo(structure, "msgConstructionComplete", stats, time, true);
|
|
|
|
// Send a faction message
|
|
sendFactionMessage(master_object, faction, getFirstName(player) + " started construction on " + name);
|
|
|
|
return;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Creates a reinforcement and gives control of it to the
|
|
* specified player.
|
|
*
|
|
* @param obj_id structure installation from which the reinforcement
|
|
* is generated.
|
|
* @param obj_id player
|
|
*
|
|
* @return obj_id reinforcement created
|
|
*********************************************************************/
|
|
obj_id buildReinforcement(obj_id master_object, obj_id structure, obj_id player)
|
|
{
|
|
if (structure == null || structure == obj_id.NULL_ID)
|
|
return null;
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
return null;
|
|
|
|
string template = getStringObjVar(structure, VAR_REINFORCEMENT_TEMPLATE);
|
|
if (template == null)
|
|
return null;
|
|
|
|
string name = getStringObjVar(structure, VAR_REINFORCEMENT_NAME);
|
|
float cost = getFloatObjVar(structure, VAR_REINFORCEMENT_COST);
|
|
|
|
if (spendFactionPoints(player, cost))
|
|
{
|
|
// Create the reinforcement
|
|
location loc = getLocation(structure);
|
|
location spawn_loc = utils.getRandomAwayLocation(loc, 5.0f, 10.0f);
|
|
string faction = getPlayerTeamFaction(player);
|
|
obj_id reinforcement = addBattlefieldMob(master_object, template, spawn_loc, faction);
|
|
|
|
LOG("LOG_CHANNEL", "battlefield.buildReinforcement -- created " + reinforcement);
|
|
|
|
// Make the reinforcement a pet of the player.
|
|
pet_lib.makePet(reinforcement, player);
|
|
pet_lib.setupDefaultCommands(reinforcement);
|
|
|
|
// Mark it as battlefield constructed
|
|
setObjVar(reinforcement, battlefield.VAR_CONSTRUCTED, 1);
|
|
|
|
// Record last build time
|
|
setObjVar(structure, battlefield.VAR_LAST_BUILD, getGameTime());
|
|
|
|
// send a message to the faction
|
|
sendFactionMessage(master_object, faction, getName(player) + " has acquired a reinforcement " + name + ".");
|
|
|
|
return reinforcement;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief Intiates repairs in the specified structure.
|
|
*
|
|
* @param obj_id master_object
|
|
* @param obj_id player player initiating the repair
|
|
* @param obj_id structure structure to repair.
|
|
*
|
|
* @return boolean
|
|
*********************************************************************/
|
|
boolean repairBattlefieldStructure(obj_id master_object, obj_id player, obj_id structure)
|
|
{
|
|
if (master_object == null || master_object == obj_id.NULL_ID)
|
|
return false;
|
|
if (structure == null || structure == obj_id.NULL_ID)
|
|
return false;
|
|
|
|
if (!hasScript(structure, SCRIPT_DESTRUCTIBLE_BUILDING) && !hasScript(structure, SCRIPT_DESTROY_OBJECTIVE))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You cannot repair that.");
|
|
sendSystemMessageTestingOnly(player, "You cannot repair that.");
|
|
return false;
|
|
}
|
|
|
|
if (getHitpoints(structure) == getMaxHitpoints(structure))
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->That does not need repairing.");
|
|
sendSystemMessageTestingOnly(player, "That does not need repairing.");
|
|
return false;
|
|
}
|
|
|
|
// Decrement build points by the repair cost.
|
|
int repair_cost = getIntObjVar(structure, VAR_REPAIR_COST);
|
|
string faction = getPlayerTeamFaction(player);
|
|
if (decrementFactionBuildPoints(master_object, faction, repair_cost))
|
|
{
|
|
// Start the repair loop.
|
|
setObjVar(structure, VAR_REPAIRING, 1);
|
|
messageTo(structure, "msgRepairPulse", null, REPAIR_PULSE, true);
|
|
LOG("LOG_CHANNEL", player + " ->Repairs initiated.");
|
|
sendSystemMessageTestingOnly(player, "Repairs initiated.");
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
LOG("LOG_CHANNEL", player + " ->You do not have the " + repair_cost + " build points to initiate repair.");
|
|
sendSystemMessageTestingOnly(player, "You do not have the " + repair_cost + " build points to initiate repair.");
|
|
return false;
|
|
}
|
|
}
|
|
|