/** * Copyright (c)2000-2002 Sony Online Entertainment Inc. * All Rights Reserved * * Title: faction_perk.scriptlib * Description: function library for species innate abilities/commands * @author $Author:$ * @version $Revision:$ */ /***** 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; }