mirror of
https://bitbucket.org/seefoe/dsrc.git
synced 2026-07-31 01:15:55 -04:00
1317 lines
42 KiB
Plaintext
1317 lines
42 KiB
Plaintext
/**
|
|
* Title: faction_perk.scriptlib
|
|
* Description: function library for species innate abilities/commands
|
|
*/
|
|
|
|
/***** INCLUDES ********************************************************/
|
|
|
|
include library.money;
|
|
include library.npc;
|
|
include library.skill;
|
|
include library.factions;
|
|
include library.prose;
|
|
include library.player_structure;
|
|
include library.structure;
|
|
include library.regions;
|
|
include library.utils;
|
|
include library.sui;
|
|
include library.datatable;
|
|
include library.pet_lib;
|
|
include library.create;
|
|
include library.ai_lib;
|
|
include library.temp_schematic;
|
|
include library.static_item;
|
|
include library.stealth;
|
|
include java.util.StringTokenizer;
|
|
|
|
/***** CONSTANTS *******************************************************/
|
|
|
|
const string TBL_PREJUDICE = "datatables/faction/prejudice.iff";
|
|
const string TBL_PERK_INVENTORY_BASE = "datatables/npc/faction_recruiter/perk_inventory/";
|
|
|
|
//COVERT DETECTOR
|
|
const string VAR_COVERT_DETECTOR = "covert_detector";
|
|
const string VAR_COVERT_DETECTOR_FACTION = VAR_COVERT_DETECTOR + ".faction";
|
|
const string VAR_COVERT_DETECTOR_RANGE = VAR_COVERT_DETECTOR + ".range";
|
|
const string VAR_COVERT_DETECTOR_SPEED = VAR_COVERT_DETECTOR + ".speed";
|
|
|
|
const float BASE_COVERT_DETECT_TIME = 5f;
|
|
|
|
const float DETECTOR_NOTIFY_RANGE = 128f;
|
|
|
|
const string_id PROSE_COVERT_UNCLOAK = new string_id("base_player","prose_covert_uncloak");
|
|
|
|
//MINEFIELD
|
|
const string VAR_MINEFIELD_BASE = "minefield";
|
|
|
|
const string VAR_MINEFIELD_SIZE = VAR_MINEFIELD_BASE + ".size";
|
|
|
|
const string VAR_MINEFIELD_ACTIVE = VAR_MINEFIELD_BASE + ".active";
|
|
|
|
const string VAR_MINEFIELD_TARGETS = VAR_MINEFIELD_BASE + ".targets";
|
|
const string VAR_MINEFIELD_TARGET_IDS = VAR_MINEFIELD_TARGETS + ".ids";
|
|
const string VAR_MINEFIELD_TARGET_LOCS = VAR_MINEFIELD_TARGETS + ".locs";
|
|
|
|
const string VAR_MINEFIELD_EXTENTS_BASE = VAR_MINEFIELD_BASE + ".extents";
|
|
const string VAR_MINEFIELD_MIN_X = VAR_MINEFIELD_EXTENTS_BASE + ".minX";
|
|
const string VAR_MINEFIELD_MIN_Z = VAR_MINEFIELD_EXTENTS_BASE + ".minZ";
|
|
const string VAR_MINEFIELD_MAX_X = VAR_MINEFIELD_EXTENTS_BASE + ".maxX";
|
|
const string VAR_MINEFIELD_MAX_Z = VAR_MINEFIELD_EXTENTS_BASE + ".maxZ";
|
|
|
|
const float BASE_MINEFIELD_TICK = 1f;
|
|
const int CHANCE_PER_METER = 25;
|
|
const float MINE_DAMAGE_RADIUS = 6f;
|
|
|
|
//STRING IDS
|
|
const string STF_PERK = "faction_perk";
|
|
const string_id MNU_DEPLOY = new string_id(STF_PERK, "deploy");
|
|
const string_id MNU_PACKUP = new string_id(STF_PERK, "packup");
|
|
|
|
const string_id SID_NO_BUILD_AREA = new string_id(STF_PERK, "no_build_area");
|
|
const string_id SID_NO_BUILD_INSIDE = new string_id(STF_PERK, "no_build_inside");
|
|
|
|
const string_id PROSE_BE_DECLARED = new string_id(STF_PERK, "prose_be_declared");
|
|
const string_id PROSE_DECLARED_FATION = new string_id(STF_PERK, "prose_be_declared_faction");
|
|
|
|
const string_id PROSE_MUST_HAVE_SKILL = new string_id(STF_PERK, "prose_must_have_skill");
|
|
|
|
const string_id PROSE_NSF_LOTS = new string_id(STF_PERK, "prose_nsf_lots");
|
|
|
|
const string_id PROSE_WRONG_FACTION = new string_id(STF_PERK, "prose_wrong_faction");
|
|
|
|
const string_id PROSE_NOT_NEUTRAL = new string_id(STF_PERK, "prose_not_neutral");
|
|
|
|
//FACTION PERK PURCHASE
|
|
|
|
const string_id[] FACTION_PERK_GROUPS = {
|
|
new string_id("faction_recruiter", "option_purchase_weapons_armor"),
|
|
new string_id("faction_recruiter", "option_purchase_installation")};
|
|
|
|
const float FACTION_LOSING_COST_MODIFIER = .70f;
|
|
|
|
const string VAR_FACTION = "faction_recruiter.faction";
|
|
|
|
const string SCRIPT_FACTION_RECRUITER = "npc.faction_recruiter.faction_recruiter";
|
|
const string SCRIPT_PLAYER_RECRUITER = "npc.faction_recruiter.player_recruiter";
|
|
const string SCRIPT_FACTION_ITEM = "npc.faction_recruiter.faction_item";
|
|
|
|
const string VAR_TRAINING_SELECTION = "faction_recruiter.training_selection";
|
|
const string VAR_TRAINING_COST = "faction_recruiter.cost";
|
|
const string VAR_TRAINING_XP = "faction_recruiter.xp";
|
|
const string VAR_DECLARED = "faction_recruiter.declared";
|
|
const string VAR_FACTION_HIRELING = "faction_recruiter.faction_hireling";
|
|
const string VAR_PLAYER = "faction_recruiter.player";
|
|
const string VAR_BIO_LINK_FACTION_POINTS = "biolink.faction_points";
|
|
|
|
const string_id SID_NO_ITEMS_AVAILABLE = new string_id("faction_recruiter", "no_items_available");
|
|
const string_id SID_RESIGN_COMPLETE = new string_id("faction_recruiter", "resign_complete");
|
|
const string_id SID_COVERT_COMPLETE = new string_id("faction_recruiter", "covert_complete");
|
|
const string_id SID_INVALID_AMOUNT_ENTERED = new string_id("faction_recruiter", "invalid_amount_entered");
|
|
const string_id SID_NOT_ENOUGH_STANDING_SPEND = new string_id("faction_recruiter", "not_enough_standing_spend");
|
|
const string_id SID_NOT_ENOUGH_CREDITS = new string_id("faction_recruiter", "not_enough_credits");
|
|
const string_id SID_AMOUNT_TOO_SMALL = new string_id("faction_recruiter", "amount_to_spend_too_small");
|
|
const string_id SID_EXPERIENCE_GRANTED = new string_id("faction_recruiter", "training_experience_granted");
|
|
const string_id SID_ITEM_PURCHASED = new string_id("faction_recruiter", "item_purchase_complete");
|
|
const string_id SID_ACQUIRE_HIRELING = new string_id("faction_recruiter", "hireling_purchase_complete");
|
|
const string_id SID_TOO_MANY_HIRELINGS = new string_id("faction_recruiter", "too_many_hirelings");
|
|
const string_id SID_HIRELING_RELEASED = new string_id("faction_recruiter", "hireling_released");
|
|
const string_id SID_INVENTORY_FULL = new string_id("faction_recruiter", "inventory_full");
|
|
const string_id SID_DATAPAD_FULL = new string_id("faction_recruiter", "datapad_full");
|
|
const string_id SID_ORDER_PURCHASED = new string_id("faction_recruiter", "order_purchase_complete");
|
|
const string_id SID_SCHEMATIC_PURCHASED = new string_id("faction_recruiter", "schematic_purchase_complete");
|
|
const string_id SID_SCHEMATIC_DUPLICATE = new string_id("faction_recruiter", "schematic_duplicate");
|
|
|
|
//ComLink
|
|
const int FACTION_NONE = -1;
|
|
const int FACTION_REBEL = 0;
|
|
const int FACTION_IMPERIAL = 1;
|
|
|
|
const string COMM_COOLDOWN = "pvp_gcw_comlink.cooldown";
|
|
const int COMM_REUSE = 900;
|
|
|
|
const string_id SID_ALREADY_HAVE = new string_id("gcw", "comm_already_used");
|
|
const string_id SID_TOO_LOW_LEVEL = new string_id("gcw", "player_too_low");
|
|
const string_id SID_INDOORS = new string_id("gcw", "player_is_indoors");
|
|
|
|
|
|
/***** FUNCTIONS *******************************************************/
|
|
/***********************************************************************
|
|
* @brief modifies faction perk cost based on species
|
|
*
|
|
* @return int; modified cost; -1 on error
|
|
***********************************************************************/
|
|
int prejudicePerkCost(obj_id player, string faction, int base_cost)
|
|
{
|
|
if ( !isIdValid(player) || (faction == null) || (faction.equals("")) || (base_cost < 1) )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int species = getSpecies(player);
|
|
float mod = getFactionPrejudice(species, faction);
|
|
if ( mod > 1.05f )
|
|
{
|
|
mod = 1.05f;
|
|
}
|
|
|
|
// General expertise faction bonus. Capped at 3%.
|
|
float expertiseFactionCostBonus = getSkillStatisticModifier(player, "expertise_faction_cost_bonus");
|
|
|
|
if(expertiseFactionCostBonus > 3)
|
|
expertiseFactionCostBonus = 3;
|
|
|
|
mod = mod - (expertiseFactionCostBonus/100);
|
|
|
|
if ( mod > 0 )
|
|
{
|
|
float cost = base_cost * mod;
|
|
return (int)cost;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief retrieves the faction prejudice vs the specified species
|
|
*
|
|
* @return float; modifier
|
|
***********************************************************************/
|
|
float getFactionPrejudice(int species, string faction)
|
|
{
|
|
faction = toLower(faction);
|
|
|
|
string strSpecies = utils.getPlayerSpeciesName(species);
|
|
return dataTableGetFloat(TBL_PREJUDICE, strSpecies, faction);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* @brief attempts to deploy a factional deed
|
|
*
|
|
* @return boolean; false on error
|
|
***********************************************************************/
|
|
boolean canDeployFactionalDeed(obj_id player, obj_id deed)
|
|
{
|
|
|
|
if ( !isIdValid(player) || !isIdValid(deed) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( getOwner(deed) != player )
|
|
{
|
|
LOG("LOG_CHANNEL","canDeployFactionalDeed: player != deed owner");
|
|
return false;
|
|
}
|
|
|
|
string pFac = factions.getFaction(player);
|
|
int pvpType = pvpGetType( player );
|
|
if ( pvpType == PVPTYPE_NEUTRAL )
|
|
{
|
|
prose_package ppBeDeclared = prose.getPackage(PROSE_NOT_NEUTRAL, deed);
|
|
sendSystemMessageProse(player, ppBeDeclared);
|
|
return false;
|
|
}
|
|
|
|
string dFac = factions.getFaction(deed);
|
|
if ( dFac != null && !dFac.equals("") )
|
|
{
|
|
if ( !pFac.equals(dFac) )
|
|
{
|
|
prose_package ppWrongFaction = prose.getPackage(PROSE_WRONG_FACTION, deed, dFac);
|
|
sendSystemMessageProse(player, ppWrongFaction);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
string template = player_structure.getDeedTemplate(deed);
|
|
if ( (template == null) || (template.equals("")) )
|
|
{
|
|
LOG("LOG_CHANNEL","canDeployFactionalDeed: bad deed template!!");
|
|
return false;
|
|
}
|
|
|
|
if (!gcw.canPlaceFactionBaseByPlanet(player, deed, getLocation(player).area))
|
|
{
|
|
sendSystemMessage(player, new string_id("gcw", "cannot_place_additional_base"));
|
|
return false;
|
|
}
|
|
|
|
int used = getIntObjVar(player, player_structure.VAR_LOTS_USED);
|
|
|
|
string fp_template = player_structure.getFootprintTemplate(template);
|
|
if ( (fp_template == null) || (fp_template.equals("")) )
|
|
{
|
|
fp_template = template;
|
|
}
|
|
|
|
location here = getLocation(player);
|
|
if ( isIdValid(here.cell) )
|
|
{
|
|
sendSystemMessage(player, SID_NO_BUILD_AREA);
|
|
return false;
|
|
}
|
|
|
|
region[] rgnTest = getRegionsWithBuildableAtPoint(here, regions.BUILD_FALSE);
|
|
if ( rgnTest != null )
|
|
{
|
|
sendSystemMessage(player, SID_NO_BUILD_AREA);
|
|
return false;
|
|
}
|
|
|
|
// check obehjcts in range
|
|
// check obehjcts in range
|
|
if(!player_structure.canPlaceFactionPerkDeed(deed, player))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/***** COVERT DETECTOR FUNCTIONS ****************************************/
|
|
void decloakCovertFactionMember(obj_id detector, obj_id player)
|
|
{
|
|
if ( !isIdValid(detector) || !isIdValid(player) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( isPlayer(player) )
|
|
{
|
|
//LOG("covert_detector"," * player: " + player + " faction = " + factions.getFaction(player));
|
|
int dFac = pvpGetAlignedFaction(detector);
|
|
int pFac = pvpGetAlignedFaction(player);
|
|
if ( pvpAreFactionsOpposed(dFac, pFac) && !factions.isDeclared(player) )
|
|
{
|
|
string pFacName = factions.getFaction(player);
|
|
string dFacName = factions.getFactionNameByHashCode(dFac);
|
|
|
|
boolean hasGlobalTef = false;
|
|
string[] tefs = pvpGetEnemyFlags(player);
|
|
if ( tefs != null && tefs.length > 0 )
|
|
{
|
|
for ( int i = 0; i < tefs.length; i++ )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(tefs[i]);
|
|
string sTarget = st.nextToken();
|
|
string sTefFac = st.nextToken();
|
|
string sExpiration = st.nextToken();
|
|
|
|
int iTefFac = utils.stringToInt(sTefFac);
|
|
string tefFac = factions.getFactionNameByHashCode(iTefFac);
|
|
if ( tefFac != null && !tefFac.equals("") )
|
|
{
|
|
//LOG("covert_detector"," * TEF #" + i + " tef faction = " + tefFac);
|
|
//LOG("covert_detector"," * TEF #" + i + " detector faction = " + dFacName);
|
|
if ( tefFac.equals(dFacName) )
|
|
{
|
|
obj_id target = utils.stringToObjId(sTarget);
|
|
//LOG("covert_detector"," * TEF #" + i + " target = " + target);
|
|
if ( !isIdValid(target) )
|
|
{
|
|
hasGlobalTef = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( hasGlobalTef )
|
|
return;
|
|
|
|
|
|
//LOG("covert_detector"," + FOUND COVERT ENEMY! setting TEF...");
|
|
string_id sidPlayerFactionName = factions.getLocalizedFactionName(pFacName);
|
|
prose_package ppUncloak = prose.getPackage(PROSE_COVERT_UNCLOAK, detector, sidPlayerFactionName);
|
|
sendSystemMessageProse(player, ppUncloak);
|
|
if ( !factions.setTemporaryEnemyFlag(player, detector) )
|
|
{
|
|
//LOG("covert_detector"," + UNABLE TO SET TEF ON PLAYER = " + player + "!!!");
|
|
}
|
|
else
|
|
{
|
|
obj_id[] inRange = getNonCreaturesInRange(detector, DETECTOR_NOTIFY_RANGE);
|
|
if ( (inRange != null) && (inRange.length > 0) )
|
|
{
|
|
dictionary d = new dictionary();
|
|
d.put("target", player);
|
|
for ( int i = 0; i < inRange.length; i++ )
|
|
{
|
|
if ( getGameObjectType(inRange[i]) == GOT_installation_turret )
|
|
messageTo(inRange[i], "enemyDecloaked", d, 3, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/***** FACTION PERK PURCHASE: ****************************************/
|
|
|
|
boolean displayAvailableFactionItemRanks(obj_id player, obj_id npc, int playerGcwRank, string playerGcwFaction)
|
|
{
|
|
if ( playerGcwRank > 0 )
|
|
{
|
|
string perksDatatable = "datatables/npc/faction_recruiter/perk_inventory/gcw_rewards.iff";
|
|
|
|
// Determine how many items the player has available for each rank.
|
|
// If none, that rank will be greyed out (if shown).
|
|
int[] itemsPerRankList = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
int num_items = dataTableGetNumRows(perksDatatable);
|
|
for (int i = 0; i < num_items; i++)
|
|
{
|
|
dictionary row = dataTableGetRow(perksDatatable, i);
|
|
if ( row != null && !row.isEmpty() )
|
|
{
|
|
int[] requiredRank = dataTableGetIntColumn(perksDatatable, "requiredGcwRank");
|
|
string[] requiredFaction = dataTableGetStringColumn(perksDatatable,"requiredFaction");
|
|
|
|
int row_requiredRank = row.getInt("requiredGcwRank");
|
|
string row_requiredFaction = row.getString("requiredFaction");
|
|
|
|
if ( playerGcwRank >= row_requiredRank && ( row_requiredFaction.equals(playerGcwFaction) || row_requiredFaction.equals("Either") ) )
|
|
{
|
|
string row_template = row.getString("template");
|
|
string row_name = row.getString("name");
|
|
int row_cost = row.getInt("cost");
|
|
|
|
boolean addItem = true;
|
|
|
|
string row_requiredClasses = row.getString("requiredClasses");
|
|
int row_requiredLevel = row.getInt("requiredLevel");
|
|
string row_requiredSkill = row.getString("requiredSkill");
|
|
|
|
if ( row_template.startsWith("object/draft_schematic") )
|
|
{
|
|
if ( row_name == null || row_name.length() == 0 )
|
|
{
|
|
string_id nameId = getProductNameFromSchematic(row_template);
|
|
if ( nameId != null )
|
|
row_name = "@" + nameId;
|
|
}
|
|
|
|
if ( hasSchematic(player, row_template) )
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
if ( row_name == null || row_name.length() == 0 )
|
|
{
|
|
string_id nameId = getNameFromTemplate(row_template);
|
|
if ( nameId != null )
|
|
row_name = "@" + nameId;
|
|
}
|
|
|
|
// check class requirement
|
|
if ( row_requiredClasses != null && row_requiredClasses.length() > 0 )
|
|
{
|
|
addItem = utils.testItemClassRequirements(player, row_requiredClasses, true);
|
|
}
|
|
|
|
// check level requirement
|
|
if ( row_requiredLevel > 1 )
|
|
{
|
|
if(getLevel(player) < row_requiredLevel)
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
|
|
// check skill requirement
|
|
if ( row_requiredSkill != null && row_requiredSkill.length() > 0 )
|
|
{
|
|
addItem = hasSkill(player, row_requiredSkill);
|
|
}
|
|
|
|
// check for a unique item that the player already owns
|
|
if ( row_template.startsWith("static:") )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(row_template, ":");
|
|
if( st.countTokens() == 2 )
|
|
{
|
|
st.nextToken();
|
|
string itemName = st.nextToken();
|
|
|
|
if ( static_item.isUniqueStaticItem(itemName) )
|
|
{
|
|
if ( !static_item.canCreateUniqueStaticItem(player, itemName) )
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( addItem )
|
|
{
|
|
itemsPerRankList[row_requiredRank] = itemsPerRankList[row_requiredRank] + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string scriptvar_path = "recruiter.item_rank." + player;
|
|
|
|
resizeable string[] rankList = new string[0];
|
|
|
|
for ( int i = playerGcwRank; i > 0; i--)
|
|
{
|
|
string text = "@gcw_rank:" + toLower(playerGcwFaction) + "_rank" + i;
|
|
if ( itemsPerRankList[i] > 0 )
|
|
{
|
|
rankList = utils.addElement(rankList, text);
|
|
}
|
|
else
|
|
{
|
|
// if there are no items available for a rank, grey out the text.
|
|
string_id contrastText_sid = new string_id("faction_recruiter","rank_list_empty");
|
|
prose_package pp = prose.getPackage(contrastText_sid);
|
|
prose.setTO(pp, text);
|
|
rankList = utils.addElement(rankList, "\0" + packOutOfBandProsePackage(null, pp));
|
|
}
|
|
}
|
|
|
|
if ( rankList != null && rankList.length > 0 )
|
|
{
|
|
string prompt = getString(new string_id("faction_recruiter","select_item_rank"));
|
|
int pid = sui.listbox(npc, player, prompt, sui.OK_CANCEL, "@faction_recruiter:faction_purchase_rank", rankList, "msgFactionItemRankSelected");
|
|
|
|
if ( pid > -1 )
|
|
{
|
|
utils.setScriptVar(npc, scriptvar_path + ".pid", pid);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
boolean displayItemPurchaseSUI(obj_id player, int rank, string faction, obj_id objNPC)
|
|
{
|
|
return displayItemPurchaseSUI(player, rank, faction, 1.0f, objNPC);
|
|
}
|
|
|
|
boolean displayItemPurchaseSUI(obj_id player, int rank, string faction)
|
|
{
|
|
return displayItemPurchaseSUI(player, rank, faction, 1.0f);
|
|
}
|
|
|
|
boolean displayItemPurchaseSUI(obj_id player, int rank, string faction, float systemMultiplier)
|
|
{
|
|
return displayItemPurchaseSUI(player, rank, faction, systemMultiplier, null);
|
|
}
|
|
boolean displayItemPurchaseSUI(obj_id player, int rank, string faction, float systemMultiplier, obj_id objRecruiter)
|
|
{
|
|
|
|
//LOG("gcw", "showing sui");
|
|
obj_id self = getSelf();
|
|
|
|
if (player == null || player == obj_id.NULL_ID)
|
|
{
|
|
//LOG("LOG_CHANNEL", "faction_recruiter::displayItemPurchaseSUI -- player is null");
|
|
return false;
|
|
}
|
|
|
|
string scriptvar_path = "recruiter.item_purchase." + player;
|
|
if ( utils.hasScriptVar(self, scriptvar_path + ".pid") )
|
|
{
|
|
int oldpid = utils.getIntScriptVar(self, scriptvar_path + ".pid");
|
|
sui.closeSUI(player, oldpid);
|
|
|
|
utils.removeScriptVar(self, scriptvar_path + ".pid");
|
|
utils.removeBatchScriptVar(self, scriptvar_path + ".template");
|
|
utils.removeBatchScriptVar(self, scriptvar_path + ".item_names");
|
|
//utils.removeBatchScriptVar(self, scriptvar_path + ".rows");
|
|
utils.removeScriptVar(self, scriptvar_path + ".rank");
|
|
utils.removeScriptVar(self, scriptvar_path + ".faction");
|
|
}
|
|
|
|
int playerGcwRank = pvpGetCurrentGcwRank(player);
|
|
int playerFactionId = pvpGetAlignedFaction(player);
|
|
string playerGcwFaction = factions.getFactionNameByHashCode(playerFactionId);
|
|
|
|
if ( playerGcwRank < rank || !playerGcwFaction.equals(faction) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string perksDatatable = "datatables/npc/faction_recruiter/perk_inventory/gcw_rewards.iff";
|
|
|
|
resizeable string[] items = new string[0];
|
|
resizeable string[] templates = new string[0];
|
|
|
|
int num_items = dataTableGetNumRows(perksDatatable);
|
|
for (int i = 0; i < num_items; i++)
|
|
{
|
|
dictionary row = dataTableGetRow(perksDatatable, i);
|
|
if ( row != null && !row.isEmpty() )
|
|
{
|
|
int[] requiredRank = dataTableGetIntColumn(perksDatatable, "requiredGcwRank");
|
|
string[] requiredFaction = dataTableGetStringColumn(perksDatatable,"requiredFaction");
|
|
|
|
int row_requiredRank = row.getInt("requiredGcwRank");
|
|
string row_requiredFaction = row.getString("requiredFaction");
|
|
|
|
if ( row_requiredRank == rank && ( row_requiredFaction.equals(faction) || row_requiredFaction.equals("Either") ) )
|
|
{
|
|
string row_template = row.getString("template");
|
|
string row_name = row.getString("name");
|
|
int row_cost = row.getInt("cost");
|
|
|
|
boolean addItem = true;
|
|
|
|
string row_requiredClasses = row.getString("requiredClasses");
|
|
int row_requiredLevel = row.getInt("requiredLevel");
|
|
string row_requiredSkill = row.getString("requiredSkill");
|
|
|
|
if ( row_template.startsWith("object/draft_schematic") )
|
|
{
|
|
if ( row_name == null || row_name.length() == 0 )
|
|
{
|
|
string_id nameId = getProductNameFromSchematic(row_template);
|
|
if ( nameId != null )
|
|
row_name = "@" + nameId;
|
|
}
|
|
|
|
if ( hasSchematic(player, row_template) )
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
if ( row_name == null || row_name.length() == 0 )
|
|
{
|
|
string_id nameId = getNameFromTemplate(row_template);
|
|
if ( nameId != null )
|
|
row_name = "@" + nameId;
|
|
}
|
|
|
|
// check class requirement
|
|
if ( row_requiredClasses != null && row_requiredClasses.length() > 0 )
|
|
{
|
|
addItem = utils.testItemClassRequirements(player, row_requiredClasses, true);
|
|
}
|
|
|
|
// check level requirement
|
|
if ( row_requiredLevel > 1 )
|
|
{
|
|
if(getLevel(player) < row_requiredLevel)
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
|
|
// check skill requirement
|
|
if ( row_requiredSkill != null && row_requiredSkill.length() > 0 )
|
|
{
|
|
addItem = hasSkill(player, row_requiredSkill);
|
|
}
|
|
|
|
// check for a unique item that the player already owns
|
|
if ( row_template.startsWith("static:") )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(row_template, ":");
|
|
if( st.countTokens() == 2 )
|
|
{
|
|
st.nextToken();
|
|
string itemName = st.nextToken();
|
|
|
|
if ( static_item.isUniqueStaticItem(itemName) )
|
|
{
|
|
if ( !static_item.canCreateUniqueStaticItem(player, itemName) )
|
|
{
|
|
addItem = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( addItem )
|
|
{
|
|
int cost = faction_perk.prejudicePerkCost(player, faction.toLowerCase(), row_cost);
|
|
|
|
if ( cost > 0 )
|
|
{
|
|
if(isIdValid(objRecruiter))
|
|
{
|
|
float fltCost = (float)cost;
|
|
fltCost = faction_perk.getModifiedGCWCost(fltCost, objRecruiter, faction);
|
|
cost = (int)(fltCost);
|
|
}
|
|
|
|
cost *= systemMultiplier;
|
|
|
|
//validRows = utils.addElement(validRows, i);
|
|
items = utils.addElement(items, row_name + " (Cost: " + cost + ")");
|
|
templates = utils.addElement(templates, row_template);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string rankTitle = "@gcw_rank:" + toLower(playerGcwFaction) + "_rank" + rank;
|
|
|
|
if (items == null || items.length < 1)
|
|
{
|
|
// There are no items available for the selected rank, so show the rank selection sui
|
|
faction_perk.displayAvailableFactionItemRanks(player, self, playerGcwRank, playerGcwFaction);
|
|
|
|
prose_package pp = prose.getPackage(faction_perk.SID_NO_ITEMS_AVAILABLE, rankTitle);
|
|
sendSystemMessageProse(player, pp);
|
|
return false;
|
|
}
|
|
|
|
float totalMultiplier = 1f;
|
|
if ( !factions.isFactionWinning(faction) )
|
|
totalMultiplier *= faction_perk.FACTION_LOSING_COST_MODIFIER;
|
|
|
|
if ( systemMultiplier != 1f )
|
|
totalMultiplier *= systemMultiplier;
|
|
|
|
string prompt = getString(new string_id("faction_recruiter","select_item_purchase"));
|
|
if ( totalMultiplier != 1f )
|
|
{
|
|
int delta = (int)((totalMultiplier - 1f)*100);
|
|
prompt += "\n\nCost modifier at this time: " + delta + "%";
|
|
}
|
|
|
|
string myHandler = "msgFactionItemPurchaseSelected";
|
|
int pid = sui.listbox(self, player, prompt, sui.OK_CANCEL_REFRESH, rankTitle, items, myHandler, false, false);
|
|
if ( pid > -1 )
|
|
{
|
|
sui.listboxUseOtherButton(pid, "Back");
|
|
sui.showSUIPage(pid);
|
|
|
|
utils.setScriptVar(self, scriptvar_path + ".pid", pid);
|
|
utils.setBatchScriptVar(self, scriptvar_path + ".template", templates);
|
|
utils.setBatchScriptVar(self, scriptvar_path + ".item_names", items);
|
|
//utils.setBatchScriptVar(self, scriptvar_path + ".rows", validRows);
|
|
utils.setScriptVar(self, scriptvar_path + ".rank", rank);
|
|
utils.setScriptVar(self, scriptvar_path + ".faction", faction);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
float getModifiedGCWCost(float fltCost, obj_id objNPC, string strFaction )
|
|
{
|
|
float MINIMUM_MODIFIER = .50f;
|
|
float MAXIMUM_MODIFIER = 1.50f;
|
|
float fltRatio= 0f;
|
|
if(strFaction.equals("Imperial"))
|
|
{
|
|
fltRatio = gcw.getRebelRatio(objNPC);
|
|
}
|
|
else if (strFaction.equals("Rebel"))
|
|
{
|
|
fltRatio = gcw.getImperialRatio(objNPC);
|
|
}
|
|
else
|
|
{
|
|
return fltCost;
|
|
}
|
|
LOG("gcw", "Ratio is "+fltRatio);
|
|
|
|
float fltModifier = MINIMUM_MODIFIER + fltRatio;
|
|
if(fltModifier > MAXIMUM_MODIFIER)
|
|
{
|
|
fltModifier = MAXIMUM_MODIFIER;
|
|
}
|
|
LOG("gcw", "Modifier is "+fltModifier);
|
|
|
|
fltCost = fltCost * fltModifier;
|
|
return fltCost;
|
|
|
|
|
|
}
|
|
|
|
void factionItemPurchased(dictionary params)
|
|
{
|
|
factionItemPurchased(params, 1.0f);
|
|
}
|
|
|
|
void factionItemPurchased(dictionary params, float systemMultiplier)
|
|
{
|
|
obj_id self = getSelf();
|
|
|
|
if ( params == null || params.isEmpty() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
obj_id player = sui.getPlayerId(params);
|
|
if ( !isIdValid(player) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
string scriptvar_path = "recruiter.item_purchase." + player;
|
|
if ( !utils.hasScriptVar(self, scriptvar_path + ".pid") )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int oldPid = utils.getIntScriptVar(self, scriptvar_path + ".pid");
|
|
string[] available_items = utils.getStringBatchScriptVar(self, scriptvar_path + ".template");
|
|
string[] item_names = utils.getStringBatchScriptVar(self, scriptvar_path + ".item_names");
|
|
//int[] validRows = utils.getIntBatchScriptVar(self, scriptvar_path + ".rows");
|
|
int rank = utils.getIntScriptVar(self, scriptvar_path + ".rank");
|
|
string faction = utils.getStringScriptVar(self, scriptvar_path + ".faction");
|
|
|
|
utils.removeScriptVar(self, scriptvar_path + ".pid");
|
|
utils.removeBatchScriptVar(self, scriptvar_path + ".template");
|
|
utils.removeBatchScriptVar(self, scriptvar_path + ".item_names");
|
|
//utils.removeBatchScriptVar(self, scriptvar_path + ".rows");
|
|
utils.removeScriptVar(self, scriptvar_path + ".rank");
|
|
utils.removeScriptVar(self, scriptvar_path + ".faction");
|
|
|
|
|
|
if ( available_items == null || available_items.length == 0 )
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionItemPurchaseSelected -- the item template list is null.");
|
|
return;
|
|
}
|
|
|
|
if ( faction == null || faction.equals("") )
|
|
{
|
|
//faction = toLower(factions.getFaction(self));
|
|
int faction_id = pvpGetAlignedFaction(self);
|
|
faction = toLower(factions.getFactionNameByHashCode(faction_id));
|
|
}
|
|
|
|
int playerGcwRank = pvpGetCurrentGcwRank(player);
|
|
int playerFactionId = pvpGetAlignedFaction(player);
|
|
string playerGcwFaction = factions.getFactionNameByHashCode(playerFactionId);
|
|
|
|
if ( playerGcwRank < rank || !playerGcwFaction.equals(faction) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
int button = sui.getIntButtonPressed(params);
|
|
if ( button == sui.BP_CANCEL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( button == sui.BP_REVERT )
|
|
{
|
|
// Go back the Item Selection list
|
|
faction_perk.displayAvailableFactionItemRanks(player, self, playerGcwRank, playerGcwFaction);
|
|
return;
|
|
}
|
|
|
|
int row_selected = sui.getListboxSelectedRow(params);
|
|
if (row_selected < 0)
|
|
return;
|
|
|
|
if (row_selected >= available_items.length)
|
|
return;
|
|
|
|
// Get the selected item.
|
|
string item_template = available_items[row_selected];
|
|
if (item_template == null)
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionItemPurchaseSelected -- the item template selected by " + self + " is null.");
|
|
return;
|
|
}
|
|
|
|
string perksDatatable = "datatables/npc/faction_recruiter/perk_inventory/gcw_rewards.iff";
|
|
|
|
// Get the data for the selected item.
|
|
int idx = dataTableSearchColumnForString(item_template, "template", perksDatatable);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionItemPurchaseSelected -- cannot find " + item_template + " in the perk inventory datatable.");
|
|
return;
|
|
}
|
|
|
|
dictionary row = dataTableGetRow(perksDatatable, idx);
|
|
string name = row.getString("name");
|
|
int base_cost = row.getInt("cost");
|
|
int declared = row.getInt("declared");
|
|
|
|
string templateName = toLower(item_template);
|
|
obj_id inv = getObjectInSlot(player, "inventory");
|
|
if (inv == null || inv == obj_id.NULL_ID)
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionTrainingAmountSelected -- " + self + "'s inventory object is null.");
|
|
return;
|
|
}
|
|
|
|
int cost = faction_perk.prejudicePerkCost(player, faction, base_cost);
|
|
if ( cost < 0 )
|
|
{
|
|
cost = base_cost;
|
|
}
|
|
float fltCost = (float)cost;
|
|
fltCost = faction_perk.getModifiedGCWCost(fltCost, self, faction);
|
|
cost = (int)(fltCost);
|
|
|
|
cost *= systemMultiplier;
|
|
|
|
// Check player for required credits
|
|
if ( !money.hasFunds(player, money.MT_TOTAL, cost) )
|
|
{
|
|
string itemPurchased = item_names[row_selected];
|
|
prose_package pp = prose.getPackage(faction_perk.SID_NOT_ENOUGH_CREDITS, name);
|
|
sendSystemMessageProse(player, pp);
|
|
}
|
|
else
|
|
{
|
|
if ( item_template.startsWith("object/draft_schematic") )
|
|
{
|
|
if (hasSchematic(player, item_template))
|
|
{
|
|
faction_perk.displayItemPurchaseSUI(player, rank, playerGcwFaction, self);
|
|
sendSystemMessage(player, faction_perk.SID_SCHEMATIC_DUPLICATE);
|
|
return;
|
|
}
|
|
|
|
// Pay the costs
|
|
utils.moneyOutMetric(player, "GCW_REWARDS", cost);
|
|
money.requestPayment(player, self, cost, "pass_fail", null, true);
|
|
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + " is attempting to purchase schematic: " + item_template);
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + "'s purchase cost: " + cost);
|
|
|
|
int uses = row.getInt("uses");
|
|
if (uses > 0)
|
|
{
|
|
if (!temp_schematic.grant(player, item_template, uses))
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionTrainingAmountSelected -- unable to create " + item_template + " for " + self);
|
|
//factions.addFactionStanding(player, faction, cost);
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + "'s purchase of " + item_template + " has failed!");
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!grantSchematic(player, item_template))
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionTrainingAmountSelected -- unable to create " + item_template + " for " + self);
|
|
//factions.addFactionStanding(player, faction, cost);
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + "'s purchase of " + item_template + " has failed!");
|
|
return;
|
|
}
|
|
}
|
|
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + " has purchased schematic: " + item_template);
|
|
logBalance("perkPurchase;" + getGameTime() + ";" + faction + ";schematic;" + item_template + ";" + cost);
|
|
|
|
sendSystemMessage(player, faction_perk.SID_SCHEMATIC_PURCHASED);
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionItemPurchaseSelected -- " + item_template + " order purchased for " + self);
|
|
}
|
|
else if(templateName.startsWith("stealth:"))
|
|
{
|
|
// rangerLoot format can be
|
|
// stealth : trap|trapCaltrop|trapFlashbang|trapHx2|trapKamino|trigger|triggerTimer|triggerRemote|triggerProximity|sensor|flare|hep : intLevel : intCount
|
|
// don't put spaces though - only added those to the commend for clarity
|
|
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(templateName, ":");
|
|
if(st.countTokens() == 4)
|
|
{
|
|
string waste = st.nextToken();
|
|
string object = st.nextToken();
|
|
int level = utils.stringToInt(st.nextToken());
|
|
int count = utils.stringToInt(st.nextToken());
|
|
|
|
int free = getVolumeFree(inv);
|
|
if(free < count)
|
|
{
|
|
prose_package pp = prose.getPackage(new string_id("spam", "no_room_inventory"), count);
|
|
sendSystemMessageProse(player, pp);
|
|
return;
|
|
}
|
|
|
|
stealth.createRangerLoot(level, object, inv, count);
|
|
// Pay the costs
|
|
utils.moneyOutMetric(player, "GCW_REWARDS", cost);
|
|
money.requestPayment(player, self, cost, "pass_fail", null, true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This section handles the purchasing of inventory items.
|
|
|
|
// Check for inventory space.
|
|
int free_space = getVolumeFree(inv);
|
|
if (free_space < 1)
|
|
{
|
|
sendSystemMessage(player, faction_perk.SID_INVENTORY_FULL);
|
|
//factions.addFactionStanding(player, faction, cost);
|
|
return;
|
|
}
|
|
|
|
// Pay the costs
|
|
utils.moneyOutMetric(player, "GCW_REWARDS", cost);
|
|
money.requestPayment(player, self, cost, "pass_fail", null, true);
|
|
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + " is attempting to purchase item: " + item_template);
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + "'s purchase cost: " + cost);
|
|
|
|
// Create the item.
|
|
// Check if it's a static item, if so create with that function instead.
|
|
obj_id item = null;
|
|
if(templateName.startsWith("static:") )
|
|
{
|
|
java.util.StringTokenizer st = new java.util.StringTokenizer(item_template, ":");
|
|
if( st.countTokens() == 2 )
|
|
{
|
|
st.nextToken();
|
|
string itemName = st.nextToken();
|
|
if ( static_item.isUniqueStaticItem(itemName) )
|
|
{
|
|
if ( static_item.canCreateUniqueStaticItem(player, itemName) )
|
|
{
|
|
item = static_item.createNewItemFunction(itemName, inv);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item = static_item.createNewItemFunction(itemName, inv);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
item = weapons.createPossibleWeapon(item_template, inv, 0.8f);
|
|
|
|
if ( !isIdValid(item) )
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionTrainingAmountSelected -- unable to create " + item_template + " for " + self);
|
|
//factions.addFactionStanding(player, faction, cost);
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + "'s purchase of " + item_template + " has failed!");
|
|
return;
|
|
}
|
|
|
|
CustomerServiceLog("faction_perk", "(" + player + ")" + getName(player) + " has purchased (" + item + ")" + getName(item));
|
|
logBalance("perkPurchase;" + getGameTime() + ";" + faction + ";item;" + item_template + ";" + cost);
|
|
|
|
// Mark the item as a faction item.
|
|
setObjVar(item, faction_perk.VAR_FACTION, faction);
|
|
|
|
// Mark items that can only be used while declared.
|
|
if (declared == 1)
|
|
setObjVar(item, faction_perk.VAR_DECLARED, 1);
|
|
|
|
// Attach the faction item script.
|
|
attachScript(item, faction_perk.SCRIPT_FACTION_ITEM);
|
|
|
|
// Send the completion message.
|
|
prose_package pp = prose.getPackage(faction_perk.SID_ITEM_PURCHASED, player, item);
|
|
sendSystemMessageProse(player, pp);
|
|
|
|
LOG("LOG_CHANNEL", "faction_recruiter::msgFactionItemPurchaseSelected -- " + item + " purchased for " + self);
|
|
}
|
|
}
|
|
|
|
faction_perk.displayItemPurchaseSUI(player, rank, playerGcwFaction, self);
|
|
return;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the faction point cost a player will need to spend to use a faction crafted object, and sets that value on the object.
|
|
*/
|
|
void applyFactionCostObjvarFromSchematic(obj_id craftedObject, obj_id manfSchematic)
|
|
{
|
|
if ( !isIdValid(craftedObject) || !isIdValid(manfSchematic) )
|
|
{
|
|
CustomerServiceLog("Faction", "WARNING: faction_perk.applyFactionCostObjvarFromSchematic called with invalid object " +
|
|
craftedObject + " or schematic " + manfSchematic);
|
|
return;
|
|
}
|
|
|
|
// get the draft schematic template, and find it in the appropriate datatable
|
|
String draftSchematic = getDraftSchematic(manfSchematic);
|
|
if ( draftSchematic == null || draftSchematic.length() == 0)
|
|
{
|
|
CustomerServiceLog("Faction", "WARNING: faction_perk.applyFactionCostObjvarFromSchematic could not "+
|
|
"find draft schematic template from manf schematic " + manfSchematic);
|
|
return;
|
|
}
|
|
|
|
obj_id player = getCrafter(craftedObject);
|
|
if ( !isIdValid(player) )
|
|
{
|
|
CustomerServiceLog("Faction", "WARNING: faction_perk.applyFactionCostObjvarFromSchematic could not "+
|
|
"find owner of crafted object " + craftedObject);
|
|
return;
|
|
}
|
|
|
|
string factionName = getStringObjVar(craftedObject, VAR_FACTION);
|
|
if ( factionName == null || factionName.length() == 0 )
|
|
{
|
|
CustomerServiceLog("Faction", "WARNING: faction_perk.applyFactionCostObjvarFromSchematic could not "+
|
|
"get faction name from objvar " + VAR_FACTION + " on object ", craftedObject);
|
|
return;
|
|
}
|
|
string tbl = TBL_PERK_INVENTORY_BASE + toLower(factionName) + "/schematic.iff";
|
|
int schematicRow = dataTableSearchColumnForString(draftSchematic, "template", tbl);
|
|
if ( schematicRow < 0 )
|
|
{
|
|
CustomerServiceLog("Faction", "WARNING: faction_perk.applyFactionCostObjvarFromSchematic could not "+
|
|
"find draft schematic template " + draftSchematic + " in datatable " + tbl);
|
|
return;
|
|
}
|
|
|
|
int cost = dataTableGetInt(tbl, schematicRow, "owner_cost");
|
|
if ( cost > 0 )
|
|
{
|
|
setObjVar(craftedObject, VAR_BIO_LINK_FACTION_POINTS, cost);
|
|
}
|
|
}
|
|
|
|
/***** RECON DROID FUNCTIONS ****************************************/
|
|
boolean isValidReconTarget(obj_id player, obj_id target)
|
|
{
|
|
if ( !isIdValid(player) || !isIdValid(target) )
|
|
return false;
|
|
|
|
int pFac = pvpGetAlignedFaction(player);
|
|
int tFac = pvpGetAlignedFaction(target);
|
|
if ( isPlayer( player ) && pvpGetType( player ) == PVPTYPE_NEUTRAL )
|
|
pFac = 0;
|
|
if ( isPlayer( target ) && pvpGetType( target ) == PVPTYPE_NEUTRAL )
|
|
tFac = 0;
|
|
|
|
if ( !pvpAreFactionsOpposed(pFac, tFac) )
|
|
return false;
|
|
|
|
int got = getGameObjectType(target);
|
|
if ( isGameObjectTypeOf(got, GOT_installation_turret) )
|
|
{
|
|
return true;
|
|
}
|
|
else if ( isGameObjectTypeOf(got, GOT_installation_minefield) )
|
|
{
|
|
return true;
|
|
}
|
|
else if ( isGameObjectTypeOf(got, GOT_building_factional) )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
string[] getReconReport(obj_id player, obj_id target)
|
|
{
|
|
if ( !isIdValid(player) || !isIdValid(target) )
|
|
return null;
|
|
|
|
if ( !isValidReconTarget(player, target) )
|
|
return null;
|
|
|
|
resizeable string[] dta = new string[0];
|
|
|
|
int got = getGameObjectType(target);
|
|
if ( isGameObjectTypeOf(got, GOT_installation_turret) )
|
|
{
|
|
//add turret status
|
|
}
|
|
else if ( isGameObjectTypeOf(got, GOT_building_factional) )
|
|
{
|
|
//add hq report
|
|
}
|
|
|
|
if ( hasScript(target, "faction_perk.minefield.field") )
|
|
{
|
|
//add mine report
|
|
}
|
|
|
|
return dta;
|
|
}
|
|
|
|
|
|
|
|
void giveBonusBaseDeeds(obj_id player, obj_id inv, string item_template, string faction, int declared ) //this script was written lamely, but quickly
|
|
{
|
|
//figure out what bases to give
|
|
int level = 1;
|
|
if ( item_template.indexOf ("object/tangible/deed/faction_perk/hq/hq_s03") != -1 )
|
|
level = 2;
|
|
else if ( item_template.indexOf ("object/tangible/deed/faction_perk/hq/hq_s04") != -1 )
|
|
level = 3;
|
|
|
|
int level2 = 1;
|
|
if ( level == 3 )
|
|
level2 = 2;
|
|
|
|
string item_template1 = "object/tangible/deed/faction_perk/hq/hq_s0" + level + "_"+toLower(faction) + ".iff";
|
|
string item_template2 = "object/tangible/deed/faction_perk/hq/hq_s0" + level2 + "_"+toLower(faction) + ".iff";
|
|
|
|
//create two copies of that base in the player's inventory
|
|
obj_id item1 = createObjectInInventoryAllowOverload(item_template1, player);
|
|
|
|
// Mark the item as a faction item.
|
|
setObjVar(item1, VAR_FACTION, faction);
|
|
|
|
// Mark items that can only be used while declared.
|
|
if (declared == 1)
|
|
setObjVar(item1, VAR_DECLARED, 1);
|
|
|
|
// Attach the faction item script.
|
|
attachScript(item1, SCRIPT_FACTION_ITEM);
|
|
|
|
obj_id item2 = createObjectInInventoryAllowOverload(item_template2, player);
|
|
// Mark the item as a faction item.
|
|
setObjVar(item2, VAR_FACTION, faction);
|
|
|
|
// Mark items that can only be used while declared.
|
|
if (declared == 1)
|
|
setObjVar(item2, VAR_DECLARED, 1);
|
|
|
|
// Attach the faction item script.
|
|
attachScript(item2, SCRIPT_FACTION_ITEM);
|
|
|
|
//tell the player what we did
|
|
string_id PROSE_BONUS_BASE = new string_id(STF_PERK, "bonus_base_name");
|
|
string_id strSpam = new string_id("faction_perk", "given_extra_bases");
|
|
prose_package spam1 = prose.getPackage(PROSE_BONUS_BASE, getEncodedName(item1));
|
|
prose_package spam2 = prose.getPackage(PROSE_BONUS_BASE, getEncodedName(item2));
|
|
|
|
sendSystemMessage(player, strSpam);
|
|
sendSystemMessageProse(player, spam1);
|
|
sendSystemMessageProse(player, spam2);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
int grabFactionBasePointValue(obj_id base)
|
|
{
|
|
string base_template = getTemplateName(base);
|
|
int default_point_value = 1;
|
|
|
|
const string TBL_HQ_POINT_VALUE = "datatables/faction_perk/hq/hq_point_values.iff";
|
|
|
|
// Get the data for the selected item.
|
|
int idx = dataTableSearchColumnForString(base_template, "base_type", TBL_HQ_POINT_VALUE);
|
|
if (idx == -1)
|
|
{
|
|
LOG("LOG_CHANNEL", "faction_perk::grabFactionBasePointValue -- cannot find " + base_template + " in the hq_point_values datatable.");
|
|
return default_point_value;
|
|
}
|
|
|
|
dictionary row = dataTableGetRow(TBL_HQ_POINT_VALUE, idx);
|
|
int point_value = row.getInt("point_value");
|
|
|
|
if ( point_value < 1 )
|
|
point_value = default_point_value;
|
|
|
|
return point_value;
|
|
}
|
|
|
|
boolean executeComlinkReinforcements(obj_id player)
|
|
{
|
|
obj_id comlink = getPlayerComlink(player);
|
|
|
|
if (!isIdValid(comlink))
|
|
{
|
|
debugSpeakMsg(player, "no link");
|
|
return false;
|
|
}
|
|
if (utils.hasScriptVar(player, COMM_COOLDOWN))
|
|
{
|
|
int timeElapsed = getGameTime() - utils.getIntScriptVar(player, COMM_COOLDOWN);
|
|
if (timeElapsed < COMM_REUSE)
|
|
{
|
|
sendSystemMessage(player, SID_ALREADY_HAVE);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!static_item.validateLevelRequired(player, comlink))
|
|
{
|
|
sendSystemMessage(player, SID_TOO_LOW_LEVEL);
|
|
return false;
|
|
}
|
|
|
|
obj_id world = getTopMostContainer (player);
|
|
|
|
if (world != player)
|
|
{
|
|
sendSystemMessage(player, SID_INDOORS);
|
|
return false;
|
|
}
|
|
|
|
|
|
if (!spawnTroopers(player))
|
|
{
|
|
debugSpeakMsg(player, "failz to spawn");
|
|
return false;
|
|
}
|
|
sendCooldownGroupTimingOnly(player, ##"pvp_comm_link", 900.0f);
|
|
utils.setScriptVar(player, COMM_COOLDOWN, getGameTime());
|
|
|
|
return true;
|
|
}
|
|
|
|
obj_id getPlayerComlink(obj_id player)
|
|
{
|
|
if (factions.isRebel(player))
|
|
return utils.getStaticItemInInventory(player, "item_pvp_lieutenant_comm_link_rebel_reward_04_01");
|
|
else if (factions.isImperial(player))
|
|
return utils.getStaticItemInInventory(player, "item_pvp_lieutenant_comm_link_imperial_reward_04_01");
|
|
else
|
|
return null;
|
|
}
|
|
|
|
boolean spawnTroopers(obj_id player)
|
|
{
|
|
return spawnTroopers(player, null, -1);
|
|
}
|
|
|
|
boolean spawnTroopers(obj_id player, string faction, int rank)
|
|
{
|
|
|
|
if (rank == -1)
|
|
rank = pvpGetCurrentGcwRank(player);
|
|
|
|
if (faction == null || (faction != "rebel" && faction != "imperial"))
|
|
faction = factions.isRebel(player) ? "rebel" : "imperial";
|
|
|
|
if (rank < 7)
|
|
{
|
|
sendSystemMessage(player, new string_id("gcw", "gcw_officer_only_use"));
|
|
return false;
|
|
}
|
|
|
|
string toSpawn = "gcw_comm_link_reinforcement_"+faction+"_"+rank;
|
|
|
|
//if(!areReinforcementsAvailable(player))
|
|
// return false;
|
|
|
|
int atLevel = getLevel(player) - 10 + rank;
|
|
obj_id reinforcement = create.object(toSpawn, getLocation(player), atLevel);
|
|
|
|
if (!isIdValid(reinforcement))
|
|
return false;
|
|
|
|
setMaster(reinforcement, player);
|
|
attachScript(reinforcement, "item.gcw_buff_banner.pvp_lieutenant_comm_link_trooper");
|
|
|
|
obj_id[] haters = getWhoIsTargetingMe(player);
|
|
combat.sendCombatSpamMessage(player, new string_id("spam", "reinforcements_arrived"));
|
|
|
|
for (int i=0;haters != null && haters.length > 0 && i < haters.length;i++)
|
|
{
|
|
|
|
if (pvpCanAttack(player, haters[i]))
|
|
setHate(reinforcement, haters[i], 1);
|
|
}
|
|
|
|
return true;
|
|
}
|