diff --git a/sku.0/sys.server/compiled/game/datatables/planet_map/map_locations.tab b/sku.0/sys.server/compiled/game/datatables/planet_map/map_locations.tab index 6cb67490c..33702cf97 100755 --- a/sku.0/sys.server/compiled/game/datatables/planet_map/map_locations.tab +++ b/sku.0/sys.server/compiled/game/datatables/planet_map/map_locations.tab @@ -6,7 +6,7 @@ object/building/tatooine/bank_tatooine.iff bank object/building/naboo/bank_naboo.iff bank object/building/corellia/bank_corellia.iff bank object/building/tatooine/cantina_tatooine.iff cantina 1 -object/building/tatooine/capitol_tatooine.iff @loc_n:bestine capitol +object/building/tatooine/capitol_tatooine.iff @loc_n:bestine capitol object/building/tatooine/guild_combat_tatooine_style_01.iff guild guild_combat object/building/tatooine/guild_commerce_tatooine_style_01.iff guild guild_commerce object/building/tatooine/guild_theater_tatooine_style_01.iff guild guild_theater 1 @@ -50,9 +50,9 @@ object/building/military/outpost_cloning_facility_s03.iff cloningfacility object/building/military/outpost_starport.iff starport object/building/military/small_imperial_cloning_facility.iff cloningfacility object/building/military/small_imperial_cloning_facility_s02.iff cloningfacility -object/building/military/military_base_shed_imperial_style_cantina_s01.iff cantina -object/building/military/military_base_shed_imperial_style_hospital_01.iff medicalcenter -object/building/corellia/capitol_corellia.iff capitol +object/building/military/military_base_shed_imperial_style_cantina_s01.iff cantina +object/building/military/military_base_shed_imperial_style_hospital_01.iff medicalcenter +object/building/corellia/capitol_corellia.iff capitol object/building/poi/scout_camp_s4.iff camp 1 object/building/poi/scout_camp_s5.iff camp 1 object/building/player/city/cloning_naboo.iff cloningfacility @@ -64,47 +64,53 @@ object/building/player/city/hospital_tatooine.iff medicalcenter object/building/player/city/cityhall_tatooine.iff city object/building/player/city/cityhall_naboo.iff city object/building/player/city/cityhall_corellia.iff city -object/building/player/city/theater_tatooine.iff theater -object/building/player/city/theater_naboo.iff theater -object/building/player/city/theater_corellia.iff theater -object/building/player/city/shuttleport_tatooine.iff shuttleport -object/building/player/city/shuttleport_naboo.iff shuttleport -object/building/player/city/shuttleport_corellia.iff shuttleport -object/building/player/city/bank_corellia.iff bank -object/building/player/city/bank_tatooine.iff bank -object/building/player/city/bank_naboo.iff bank -object/building/player/city/cantina_tatooine.iff cantina -object/building/player/city/cantina_naboo.iff cantina -object/building/player/city/cantina_corellia.iff cantina -object/building/corellia/garage_corellia.iff garage -object/building/naboo/parking_garage_naboo_style_1.iff garage -object/building/tatooine/parking_garage_tatooine_style_1.iff garage -object/building/player/player_garage_tatooine_style_01.iff garage +object/building/player/city/theater_tatooine.iff theater +object/building/player/city/theater_naboo.iff theater +object/building/player/city/theater_corellia.iff theater +object/building/player/city/shuttleport_tatooine.iff shuttleport +object/building/player/city/shuttleport_naboo.iff shuttleport +object/building/player/city/shuttleport_corellia.iff shuttleport +object/building/player/city/bank_corellia.iff bank +object/building/player/city/bank_tatooine.iff bank +object/building/player/city/bank_naboo.iff bank +object/building/player/city/cantina_tatooine.iff cantina +object/building/player/city/cantina_naboo.iff cantina +object/building/player/city/cantina_corellia.iff cantina +object/building/corellia/garage_corellia.iff garage +object/building/naboo/parking_garage_naboo_style_1.iff garage +object/building/tatooine/parking_garage_tatooine_style_1.iff garage +object/building/player/player_garage_tatooine_style_01.iff garage object/building/player/player_garage_corellia_style_01.iff garage object/building/player/player_garage_naboo_style_01.iff garage object/building/tatooine/salon_tatooine.iff salon object/building/corellia/salon_corellia.iff salon object/building/naboo/salon_naboo.iff salon -object/building/faction_perk/hq/hq_s01_rebel_pvp.iff rebel sf_rebel_forward_base 1 -object/building/faction_perk/hq/hq_s01_imp_pvp.iff imperial sf_imperial_forward_base 1 -object/building/faction_perk/hq/hq_s02_rebel_pvp.iff rebel sf_rebel_minor_base 1 -object/building/faction_perk/hq/hq_s02_imp_pvp.iff imperial sf_imperial_minor_base 1 -object/building/faction_perk/hq/hq_s03_rebel_pvp.iff rebel sf_rebel_major_base 1 -object/building/faction_perk/hq/hq_s03_imp_pvp.iff imperial sf_imperial_major_base 1 -object/building/faction_perk/hq/hq_s04_rebel_pvp.iff rebel sf_rebel_hq 1 -object/building/faction_perk/hq/hq_s04_imp_pvp.iff imperial sf_imperial_hq 1 -object/building/faction_perk/hq/hq_s05_rebel_pvp.iff rebel sf_rebel_hq 1 -object/building/faction_perk/hq/hq_s05_imp_pvp.iff imperial sf_imperial_hq 1 -object/building/faction_perk/hq/hq_s04_rebel.iff rebel rebel_hq -object/building/faction_perk/hq/hq_s04_imp.iff imperial imperial_hq -object/building/faction_perk/hq/hq_s05_rebel.iff rebel rebel_hq -object/building/faction_perk/hq/hq_s05_imp.iff imperial imperial_hq -object/building/kashyyyk/mun_kachirho_starport.iff starport -object/building/mustafar/structures/must_new_mining_facility.iff cantina -object/building/mustafar/structures/must_mining_cantina_marker.iff starport -object/building/mustafar/structures/must_mining_clone_marker.iff cloningfacility -object/building/naboo/rori_restuss_starport.iff starport -object/building/naboo/rori_restuss_shuttleport.iff shuttleport -object/building/dathomir/dathomir_quarantine_zone_starport.iff starport -object/building/dathomir/dathomir_quarantine_zone_cantina.iff cantina -object/building/tatooine/bestine_museum.iff @loc_n:bestine museum +object/building/kashyyyk/mun_kachirho_starport.iff starport +object/building/mustafar/structures/must_new_mining_facility.iff cantina +object/building/mustafar/structures/must_mining_cantina_marker.iff starport +object/building/mustafar/structures/must_mining_clone_marker.iff cloningfacility +object/building/naboo/rori_restuss_starport.iff starport +object/building/naboo/rori_restuss_shuttleport.iff shuttleport +object/building/dathomir/dathomir_quarantine_zone_starport.iff starport +object/building/dathomir/dathomir_quarantine_zone_cantina.iff cantina +object/building/tatooine/bestine_museum.iff @loc_n:bestine museum +object/building/faction_perk/hq/hq_s01_imp.iff player_placed_factional_base player_placed_factional_base_imperial +object/building/faction_perk/hq/hq_s01_rebel.iff player_placed_factional_base player_placed_factional_base_rebel +object/building/faction_perk/hq/hq_s01_imp_pvp.iff player_placed_factional_base player_placed_factional_base_imperial 1 +object/building/faction_perk/hq/hq_s01_rebel_pvp.iff player_placed_factional_base player_placed_factional_base_rebel 1 +object/building/faction_perk/hq/hq_s02_imp.iff player_placed_factional_base player_placed_factional_base_imperial +object/building/faction_perk/hq/hq_s02_rebel.iff player_placed_factional_base player_placed_factional_base_rebel +object/building/faction_perk/hq/hq_s02_imp_pvp.iff player_placed_factional_base player_placed_factional_base_imperial 1 +object/building/faction_perk/hq/hq_s02_rebel_pvp.iff player_placed_factional_base player_placed_factional_base_rebel 1 +object/building/faction_perk/hq/hq_s03_imp.iff player_placed_factional_base player_placed_factional_base_imperial +object/building/faction_perk/hq/hq_s03_rebel.iff player_placed_factional_base player_placed_factional_base_rebel +object/building/faction_perk/hq/hq_s03_imp_pvp.iff player_placed_factional_base player_placed_factional_base_imperial 1 +object/building/faction_perk/hq/hq_s03_rebel_pvp.iff player_placed_factional_base player_placed_factional_base_rebel 1 +object/building/faction_perk/hq/hq_s04_imp.iff player_placed_factional_base player_placed_factional_base_imperial +object/building/faction_perk/hq/hq_s04_rebel.iff player_placed_factional_base player_placed_factional_base_rebel +object/building/faction_perk/hq/hq_s04_imp_pvp.iff player_placed_factional_base player_placed_factional_base_imperial 1 +object/building/faction_perk/hq/hq_s04_rebel_pvp.iff player_placed_factional_base player_placed_factional_base_rebel 1 +object/building/faction_perk/hq/hq_s05_imp.iff player_placed_factional_base player_placed_factional_base_imperial +object/building/faction_perk/hq/hq_s05_rebel.iff player_placed_factional_base player_placed_factional_base_rebel +object/building/faction_perk/hq/hq_s05_imp_pvp.iff player_placed_factional_base player_placed_factional_base_imperial 1 +object/building/faction_perk/hq/hq_s05_rebel_pvp.iff player_placed_factional_base player_placed_factional_base_rebel 1 diff --git a/sku.0/sys.server/compiled/game/script/gm/cmd.java b/sku.0/sys.server/compiled/game/script/gm/cmd.java index ce8784896..2167c886d 100755 --- a/sku.0/sys.server/compiled/game/script/gm/cmd.java +++ b/sku.0/sys.server/compiled/game/script/gm/cmd.java @@ -4558,4 +4558,83 @@ public class cmd extends script.base_script return SCRIPT_CONTINUE; } + public int cmdGmRevive(obj_id self, obj_id target, String params, float defaultTime) throws InterruptedException { + + if (params.contains(gm.KEYWORD_TARGET)) + { + params = gm.removeKeyword(params, gm.KEYWORD_TARGET); + target = getTarget(self); + } else { + sendSystemMessageTestingOnly(self, "[Syntax] /gmRevive -target"); + return SCRIPT_CONTINUE; + } + + // fix a disabled vehicle + if(isGameObjectTypeOf(target, GOT_vehicle)) { + if(isDisabled(target)) { + clearCondition(target, CONDITION_DISABLED); + } + setHitpoints(target, getMaxHitpoints(target)); + sendSystemMessageTestingOnly(self, "The vehicle (" + target + ") was restored."); + return SCRIPT_CONTINUE; + } + + // revive a dead pet + if (pet_lib.isPet(target)) { + obj_id bcd = beast_lib.getBeastBCD(target); + obj_id master = beast_lib.getMaster(target); + if(pet_lib.isDead(target)) { + int maxHealth = getMaxAttrib(target, HEALTH); + beast_lib.storeBeast(bcd); + beast_lib.setBCDBeastIsDead(bcd, false); + beast_lib.setBCDBeastHealth(bcd, maxHealth); + beast_lib.createBeastFromBCD(master, bcd); + } else { + setHealth(target, getMaxHealth(target)); + setAction(target, getMaxAction(target)); + buff.removeAllDebuffs(target); + } + sendSystemMessageTestingOnly(self, beast_lib.getBeastName(target) + " (" + target + ") [beast] was restored."); + return SCRIPT_CONTINUE; + } + + // Heal a player and remove all debuffs. Also revive them if they're dead. + if (isPlayer(target)) { + if (getPosture(target) == POSTURE_DEAD) { + pclib.clearEffectsForDeath(target); + int suiClone = utils.getIntScriptVar(target, pclib.VAR_SUI_CLONE); + sui.closeSUI(target, suiClone); + utils.removeScriptVar(target, pclib.VAR_SUI_CLONE); + utils.removeScriptVar(target, pclib.VAR_REVIVE_OPTIONS); + pclib.trimLastKiller(target); + pvpRemoveAllTempEnemyFlags(target); + removeObjVar(target, pclib.VAR_BEEN_COUPDEGRACED); + playClientEffectObj(target, "clienteffect/player_clone_compile.cef", target, null); + } + healing.fullHealEveryone(target); + setAttrib(target, HEALTH, getMaxAttrib(target, HEALTH)); + setAttrib(target, ACTION, getMaxAttrib(target, ACTION)); + dot.removeAllDots(target); + buff.removeAllDebuffs(target); + sendSystemMessageTestingOnly(target, "You have been restored..."); + sendSystemMessageTestingOnly(self, getPlayerName(target)+" ("+target+") [player] was restored."); + return SCRIPT_CONTINUE; + + } else { + // heal an NPC, unless they're dead, in which case you can't revive them + if(isDead(target)) { + sendSystemMessageTestingOnly(self, "gmRevive: Unable to restore "+target+" because they are an NPC/Object and cannot return from death."); + return SCRIPT_CONTINUE; + } else { + setHealth(target, getMaxHealth(target)); + setAttrib(target, HEALTH, getMaxAttrib(target, HEALTH)); + setAction(target, getMaxAction(target)); + setAttrib(target, ACTION, getMaxAttrib(target, ACTION)); + buff.removeAllDebuffs(target); + sendSystemMessageTestingOnly(self, getName(target) + " (" + target + ") [npc/obj] was restored."); + return SCRIPT_CONTINUE; + } + } + } + } diff --git a/sku.0/sys.server/compiled/game/script/library/faction_perk.java b/sku.0/sys.server/compiled/game/script/library/faction_perk.java index 3320ce1c7..e13cb8083 100755 --- a/sku.0/sys.server/compiled/game/script/library/faction_perk.java +++ b/sku.0/sys.server/compiled/game/script/library/faction_perk.java @@ -86,6 +86,15 @@ public class faction_perk extends script.base_script public static final string_id SID_ALREADY_HAVE = new string_id("gcw", "comm_already_used"); public static final string_id SID_TOO_LOW_LEVEL = new string_id("gcw", "player_too_low"); public static final string_id SID_INDOORS = new string_id("gcw", "player_is_indoors"); + private static final float BASE_MODIFIER_01_PVE = utils.getFloatConfigSetting("GameServer", "gcwFactionBase01PvEBonusAmount", 0.01f); + private static final float BASE_MODIFIER_01_PVP = utils.getFloatConfigSetting("GameServer", "gcwFactionBase01PvPBonusAmount", 0.02f); + private static final float BASE_MODIFIER_02_PVE = utils.getFloatConfigSetting("GameServer", "gcwFactionBase02PvEBonusAmount", 0.03f); + private static final float BASE_MODIFIER_02_PVP = utils.getFloatConfigSetting("GameServer", "gcwFactionBase02PvPBonusAmount", 0.05f); + private static final float BASE_MODIFIER_03_PVE = utils.getFloatConfigSetting("GameServer", "gcwFactionBase03PvEBonusAmount", 0.06f); + private static final float BASE_MODIFIER_03_PVP = utils.getFloatConfigSetting("GameServer", "gcwFactionBase03PvPBonusAmount", 0.08f); + private static final float BASE_MODIFIER_04_PVE = utils.getFloatConfigSetting("GameServer", "gcwFactionBase04PvEBonusAmount", 0.10f); + private static final float BASE_MODIFIER_04_PVP = utils.getFloatConfigSetting("GameServer", "gcwFactionBase04PvPBonusAmount", 0.12f); + public static int prejudicePerkCost(obj_id player, String faction, int base_cost) throws InterruptedException { if (!isIdValid(player) || (faction == null) || (faction.equals("")) || (base_cost < 1)) @@ -157,6 +166,21 @@ public class faction_perk extends script.base_script sendSystemMessage(player, new string_id("gcw", "cannot_place_additional_base")); return false; } + + // GU 17.2 cannot place base in contested region your faction doesn't control at least 51% + int impScore = gcw.getGcwImperialScorePercentile(gcw.getGcwRegion(player)); + if(pvpGetAlignedFaction(player) == FACTION_HASH_IMPERIAL) { + if(impScore < 51) { + sendSystemMessage(player, new string_id("gcw", "not_controlling_contested_region")); + return false; + } + } else if (pvpGetAlignedFaction(player) == FACTION_HASH_REBEL) { + if(impScore > 49) { + sendSystemMessage(player, new string_id("gcw", "not_controlling_contested_region")); + 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(""))) @@ -1053,4 +1077,83 @@ public class faction_perk extends script.base_script } return true; } + + /** + * Wrapper for getRebel/ImperialFactionBases methods to pass faction hash + */ + public static Vector getFactionBasesForFaction(int faction) { + if(faction == FACTION_HASH_IMPERIAL) { + return getImperialFactionBases(); + } else if (faction == FACTION_HASH_REBEL) { + return getRebelFactionBases(); + } + return null; + } + + /** + * Returns a Vector of obj_ids of all Rebel bases in the galaxy + */ + public static Vector getRebelFactionBases() { + Vector bases = new Vector(); + map_location[] locs = getPlanetaryMapLocations("player_placed_factional_base", "player_placed_factional_base_rebel"); + for (map_location loc : locs) { + bases.add(loc.getLocationId()); + } + return bases; + } + + /** + * Returns a Vector of obj_ids of all Imperial bases in the galaxy + */ + public static Vector getImperialFactionBases() { + Vector bases = new Vector(); + map_location[] locs = getPlanetaryMapLocations("player_placed_factional_base", "player_placed_factional_base_imperial"); + for (map_location loc : locs) { + bases.add(loc.getLocationId()); + } + return bases; + } + + /** + * Provides the bonus multiplier to GCW points/presence for a particular base type + */ + public static float getBaseBonusValueByTemplate(String template) { + + switch (template) { + // Forward Outpost + case "object/building/faction_perk/hq/hq_s01_imp.iff": + case "object/building/faction_perk/hq/hq_s01_rebel.iff": + return BASE_MODIFIER_01_PVE; + // SF Forward Outpost + case "object/building/faction_perk/hq/hq_s01_imp_pvp.iff": + case "object/building/faction_perk/hq/hq_s01_rebel_pvp.iff": + return BASE_MODIFIER_01_PVP; + // Field Hospital + case "object/building/faction_perk/hq/hq_s02_imp.iff": + case "object/building/faction_perk/hq/hq_s02_rebel.iff": + return BASE_MODIFIER_02_PVE; + // SF Field Hospital + case "object/building/faction_perk/hq/hq_s02_imp_pvp.iff": + case "object/building/faction_perk/hq/hq_s02_rebel_pvp.iff": + return BASE_MODIFIER_02_PVP; + // Tactical Center + case "object/building/faction_perk/hq/hq_s03_imp.iff": + case "object/building/faction_perk/hq/hq_s03_rebel.iff": + return BASE_MODIFIER_03_PVE; + // SF Tactical Center + case "object/building/faction_perk/hq/hq_s03_imp_pvp.iff": + case "object/building/faction_perk/hq/hq_s03_rebel_pvp.iff": + return BASE_MODIFIER_03_PVP; + // Detachment HQ + case "object/building/faction_perk/hq/hq_s04_imp.iff": + case "object/building/faction_perk/hq/hq_s04_rebel.iff": + return BASE_MODIFIER_04_PVE; + // SF Detachment HQ + case "object/building/faction_perk/hq/hq_s04_imp_pvp.iff": + case "object/building/faction_perk/hq/hq_s04_rebel_pvp.iff": + return BASE_MODIFIER_04_PVP; + } + return 0.0f; + } + } diff --git a/sku.0/sys.server/compiled/game/script/library/gcw.java b/sku.0/sys.server/compiled/game/script/library/gcw.java index b5b3bb8f4..5d1c5686c 100755 --- a/sku.0/sys.server/compiled/game/script/library/gcw.java +++ b/sku.0/sys.server/compiled/game/script/library/gcw.java @@ -2,8 +2,7 @@ package script.library; import script.*; -import java.util.Arrays; -import java.util.Vector; +import java.util.*; public class gcw extends script.base_script { @@ -68,7 +67,9 @@ public class gcw extends script.base_script public static final int GCW_POINT_TYPE_GROUND_QUEST = 6; public static final int GCW_POINT_TYPE_TRADING = 7; public static final int GCW_POINT_TYPE_ENTERTAINING = 8; - public static final int GCW_POINT_TYPE_MAX = 9; + public static final int GCW_POINT_TYPE_CITY_INVASION = 9; + public static final int GCW_POINT_TYPE_GCW2_SPACE_BATTLE = 10; + public static final int GCW_POINT_TYPE_MAX = 11; public static final String[] validScenes = { "tatooine", @@ -121,7 +122,9 @@ public class gcw extends script.base_script "space_pvp", "pve", "trading", - "entertaining" + "entertaining", + "city_invasions", + "gcw2_space" }; public static final float COLLECTION_DAMAGE_RATIO_MIN = 0.41f; public static final String PVP_PUSHBACK_REGION = "pvp_pushback"; @@ -254,10 +257,23 @@ public class gcw extends script.base_script public static final String GCW_TUTORIAL_FLAG = "gcw_tutorial_flag.has_received_tutorial"; public static final String COLOR_REBELS = "\\" + colors_hex.COLOR_REBELS; public static final String COLOR_IMPERIALS = "\\" + colors_hex.COLOR_IMPERIALS; + public static final boolean DEBUG_LEADERBOARD = true; private static final float GCW_POINT_BONUS = utils.getFloatConfigSetting("GameServer", "gcwPointBonus", 1.0f); private static final float GCW_TOKEN_BONUS = utils.getFloatConfigSetting("GameServer", "gcwTokenBonus", 1.0f); private static final int GCW_CYCLE_INVASION_TIME = utils.getIntConfigSetting("GameServer", "gcwInvasionCycleTime", 3); private static final int GCW_MAX_INVASION_CITY_RUNNING = utils.getIntConfigSetting("GameServer", "gcwInvasionCityMaximumRunning", 3); + private static final boolean DISABLE_GCW_BASE_POINT_MULTIPLIER = utils.checkConfigFlag("GameServer", "gcwFactionBaseDisableBonusMultipliers"); + private static final float BASE_RANGE_01 = utils.getFloatConfigSetting("GameServer", "gcwFactionBase01BonusRadius", 750.0f); + private static final float BASE_RANGE_02 = utils.getFloatConfigSetting("GameServer", "gcwFactionBase02BonusRadius", 1000.0f); + private static final float BASE_RANGE_03 = utils.getFloatConfigSetting("GameServer", "gcwFactionBase03BonusRadius", 1250.0f); + private static final float BASE_RANGE_04 = utils.getFloatConfigSetting("GameServer", "gcwFactionBase04BonusRadius", 1500.0f); + private static final int PRESENCE_RANK_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceGcwRankBonusPct", 10); + private static final int PRESENCE_LEVEL_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceLevelPct", 10); + private static final int PRESENCE_MOUNT_PENALTY = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceMountedPct", 20); + private static final int PRESENCE_PLAYER_SCALED_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresencePlayerBonusPct", 5); + private static final int PRESENCE_ALIGNED_CITY_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceAlignedCityBonusPct", 100); + private static final int PRESENCE_CITY_RANK_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceAlignedCityRankBonusPct", 10); + private static final int PRESENCE_CITY_AGE_BONUS = utils.getIntConfigSetting("GameServer", "gcwFactionalPresenceAlignedCityAgeBonusPct", 5); public static void assignScanInterests(obj_id npc) throws InterruptedException { @@ -1280,6 +1296,7 @@ public class gcw extends script.base_script { return; } + pointValue *= getGcwFactionBasesMultiplierForPlayerAtPoint(attacker); pointValue *= GCW_POINT_BONUS; pvpModifyCurrentGcwPoints(attacker, pointValue); prose_package pp = new prose_package(); @@ -1378,6 +1395,12 @@ public class gcw extends script.base_script { return; } + // GU 17.6 PvP Killer must be Factional Presence Eligible to Contribute to Region Score + if(pointType == GCW_POINT_TYPE_GROUND_PVP_REGION) { + if(!isFactionPresenceEligible(player)) { + return; + } + } String category = getGcwCategory(pointType); String regionName = getGcwRegion(player); if (category == null || category.length() <= 0 || regionName == null || regionName.length() <= 0) @@ -1740,6 +1763,10 @@ public class gcw extends script.base_script CustomerServiceLog("GCW_points_player_base_busting", "There are no valid players in the filtered list"); return; } + // GU 20 - Scale Points Earned for Base Busting when Total Players Involved > 8 + if(filteredList.size() > 8) { + value = (value * 8) / filteredList.size(); + } for (Object o : filteredList) { grantModifiedGcwPoints(((obj_id) o), value, gcw.GCW_POINT_TYPE_BASE_BUSTING, template); } @@ -2467,6 +2494,7 @@ public class gcw extends script.base_script continue; } grantUnmodifiedGcwPoints(((obj_id) o), gcwPointAmt); + //grantGcwLeaderboardPoints(((obj_id) o), gcwPointAmt, GCW_POINT_TYPE_CITY_INVASION); if (tokenStaticName == null || tokenStaticName.length() <= 0) { CustomerServiceLog("gcw_city_invasion", "gcw.awardGcwInvasionParticipants: Player: " + ((obj_id) o) + " is NOT receiving " + gcwTokenAmt + " " + tokenStaticName + " tokens or " + gcwPointAmt + " " + factionFlag + " GCW points (GCW points only awarded to pure faction players, not factionalHelpers) because the token string name is INVALID. This is probably due to an edge case where the player changed their faction status to be neutral."); continue; @@ -2957,4 +2985,192 @@ public class gcw extends script.base_script flushSUIPage(page); return true; } + + /** + * GU 17.2 Addition: + * Determines how many factional bases are within the defined range of the player to + * award a multiplier to GCW Points and Factional Presence based on those values. + * These are configurable. But the defaults are: + * - Forward Outpost - 1%, 750m + * - SF Forward Outpost - 2%, 750m + * - Field Hospital - 3%, 1000m + * - SF Field Hospital - 5%, 1000m + * - Tactical Center - 6%, 1250m + * - SF Tactical Center - 8%, 1250m + * - Detachment Headquarters - 10%, 1500m + * - SF Detachment Headquarters - 12%, 1500m + */ + public static float getGcwFactionBasesMultiplierForPlayerAtPoint(obj_id player) { + float multiplier = 1.0f; + if(DISABLE_GCW_BASE_POINT_MULTIPLIER) { + return multiplier; + } + String template; + location playerLoc = getLocation(player); + location baseLoc; + Vector bases = faction_perk.getFactionBasesForFaction(pvpGetAlignedFaction(player)); + if(bases == null) { + return multiplier; + } + for (obj_id base : bases) { + template = getTemplateName(base); + baseLoc = getLocation(base); + if (baseLoc.area.equalsIgnoreCase(playerLoc.area)) { + if (template.contains("01")) { + if (getDistance(playerLoc, baseLoc) <= BASE_RANGE_01) { + multiplier += faction_perk.getBaseBonusValueByTemplate(getTemplateName(base)); + } + } else if (template.contains("02")) { + if (getDistance(playerLoc, baseLoc) <= BASE_RANGE_02) { + multiplier += faction_perk.getBaseBonusValueByTemplate(getTemplateName(base)); + } + } else if (template.contains("03")) { + if (getDistance(playerLoc, baseLoc) <= BASE_RANGE_03) { + multiplier += faction_perk.getBaseBonusValueByTemplate(getTemplateName(base)); + } + } else if (template.contains("04")) { + if (getDistance(playerLoc, baseLoc) <= BASE_RANGE_04) { + multiplier += faction_perk.getBaseBonusValueByTemplate(getTemplateName(base)); + } + } + } + } + return multiplier; + } + + /** + * This method handles granting Factional Presence + * It was ported from the SRC to DSRC to allow ease of customization/advancement + * This is called in a 60-second loop in base_player the entire time a player is + * online, replicating how it was handled in the SRC (through LFG updater loop) + * + * Calculation: + * bonus = 100 + * bonus += GCW Rank * GcwRankBonusPtc + * bonus += Up to 8 Players in Range who are Faction Presence Eligible * PlayerBonusPtc + * bonus *= Multiplier for Faction Bases in Range + * bonus += City Bonus for Same Faction Alignment + * bonus += City Rank * CityRankBonusPtc + * bonus += City Age in Years * CityAgeBonusPtc + * Final Value = PlayerLevel * LevelBonusPtc * bonus * mountPenalty / 1000000 + */ + public static void grantGcwFactionalPresenceScore(obj_id player) throws InterruptedException { + if(isFactionPresenceEligible(player)) { + final String region = getGcwRegion(player); + final location playerLoc = getLocation(player); + final int faction = pvpGetAlignedFaction(player); + int bonus = 100; + int mountPenalty = 100; + + // Determine Bonus based on GCW Rank (1 - 12) + bonus += pvpGetCurrentGcwRank(player) * PRESENCE_RANK_BONUS; + // Determine Combat Level and City Bonus Eligibility + int cityBonus = 0; + int level = 1; + // -------------------- player is in space ---------------- + if(isSpaceScene()) { + // determine combat level by using relative pilot skills + if(space_skill.isMasterPilot(player)) { + level = 90; + } else if (space_skill.hasTier3Skills(player)) { + level = 69; + } else if (space_skill.hasTier2Skills(player)) { + level = 45; + } else if (space_skill.hasTier1Skills(player)) { + level = 21; + } + // give city bonus if player's citizenship city is on the + // corresponding ground planet & is same faction as player + int citizenOfCity = getCitizenOfCityId(player); + if (citizenOfCity > 0) { + String cityLoc = cityGetLocation(citizenOfCity).area; + String spaceLoc; + // handle planets w/o space zone matching + if(cityLoc.equalsIgnoreCase("rori")) { + spaceLoc = "space_naboo"; + } else if (cityLoc.equalsIgnoreCase("talus")) { + spaceLoc = "space_corellia"; + } else { + spaceLoc = "space_"+cityLoc; + } + if(spaceLoc.equalsIgnoreCase(getCurrentSceneName())) { + cityBonus = citizenOfCity; + } + } + } + // -------------------- player is on the ground ---------------- + else { + level = getLevel(player); // use actual combat level + // give city bonus if player is standing in a city that is of the same + // factional alignment as the player + int cityAtLoc = getCityAtLocation(playerLoc, 0); + if (cityAtLoc > 0) { + if(cityGetFaction(cityAtLoc) == faction) { + cityBonus = cityAtLoc; + } + } + // determine mount penalty + if(isIdValid(getMountId(player))) { + mountPenalty = Math.min(Math.max(PRESENCE_MOUNT_PENALTY, 1), 100); + } + // scale up the bonus based on players in the area + obj_id[] players = getAllPlayers(playerLoc, 500.0f); + int playerBonus = 1; + for (obj_id p : players) { + if(isFactionPresenceEligible(p)) { + ++playerBonus; + } + } + playerBonus = Math.min(playerBonus, 8); + bonus += playerBonus * PRESENCE_PLAYER_SCALED_BONUS; + // apply nearby factional bases bonus + bonus *= getGcwFactionBasesMultiplierForPlayerAtPoint(player); + } + // Handle City Bonuses + if(cityBonus > 0) { + if(pvpGetAlignedFaction(player) == cityGetFaction(cityBonus)) { + // bonus just for having an aligned city + bonus += PRESENCE_ALIGNED_CITY_BONUS; + // bonus for each level of city rank + bonus += city.getCityRank(cityBonus) * PRESENCE_CITY_RANK_BONUS; + // bonus for each year of age your city is + bonus += Math.max(0, (getCalendarTime() - Math.max(1041408000, cityGetCreationTime(cityBonus))) / 31536000 * PRESENCE_CITY_AGE_BONUS); + } + } + // Points Calculation + final int points = Math.max(1, level * PRESENCE_LEVEL_BONUS * Math.min(1000, bonus) * mountPenalty / 1000000); + + // Update GCW Score + if(faction == FACTION_HASH_IMPERIAL) { + adjustGcwImperialScore("FactionalPresence", player, region, points); + } else if (faction == FACTION_HASH_REBEL) { + adjustGcwRebelScore("FactionalPresence", player, region, points); + } + + // Log the Points + LOG("factional_presence", "Player "+getPlayerName(player)+" ("+player+") added "+points+" of presence with bonus "+bonus+" to region "+region+" for faction "+faction); + } + } + + /** + * The conditions a player must meet to contribute to the factional presence score. + * Also used for finding other "faction presence eligible" players in the region. + * + * Conditions: + * Player must be active (provided input in last 15 minutes, not including macros) + * Player must be Special Forces + * Player must be within a GCW Contested Region + * Player cannot be cloaked, incapacitated, or in a structure + */ + public static boolean isFactionPresenceEligible(obj_id player) throws InterruptedException { + if(!isPlayerActive(player) || isDead(player) || isIncapacitated(player)) { + return false; + } + if(!factions.isDeclared(player) || structure.isInside(player) || !getCreatureCoverVisibility(player)) { + return false; + } + String region = getGcwRegion(player); + return region != null && !region.equalsIgnoreCase(""); + } + } diff --git a/sku.0/sys.server/compiled/game/script/library/space_skill.java b/sku.0/sys.server/compiled/game/script/library/space_skill.java index 61c305b4e..66c19eebe 100755 --- a/sku.0/sys.server/compiled/game/script/library/space_skill.java +++ b/sku.0/sys.server/compiled/game/script/library/space_skill.java @@ -170,4 +170,50 @@ public class space_skill extends script.base_script } return false; } + public static boolean hasTier3Skills(obj_id player) throws InterruptedException { + if (hasRebelSkill(player)) + { + return (hasSkill(player, "pilot_rebel_navy_droid_03")); + } + if (hasImperialSkill(player)) + { + return (hasSkill(player, "pilot_imperial_navy_droid_03")); + } + if (hasPilotSkill(player)) + { + return (hasSkill(player, "pilot_neutral_droid_03")); + } + return false; + } + public static boolean hasTier2Skills(obj_id player) throws InterruptedException { + if (hasRebelSkill(player)) + { + return (hasSkill(player, "pilot_rebel_navy_droid_02")); + } + if (hasImperialSkill(player)) + { + return (hasSkill(player, "pilot_imperial_navy_droid_02")); + } + if (hasPilotSkill(player)) + { + return (hasSkill(player, "pilot_neutral_droid_02")); + } + return false; + } + public static boolean hasTier1Skills(obj_id player) throws InterruptedException { + if (hasRebelSkill(player)) + { + return (hasSkill(player, "pilot_rebel_navy_droid_01")); + } + if (hasImperialSkill(player)) + { + return (hasSkill(player, "pilot_imperial_navy_droid_01")); + } + if (hasPilotSkill(player)) + { + return (hasSkill(player, "pilot_neutral_droid_01")); + } + return false; + } + } diff --git a/sku.0/sys.server/compiled/game/script/player/base/base_player.java b/sku.0/sys.server/compiled/game/script/player/base/base_player.java index 3ac5e08b6..c09099a7c 100755 --- a/sku.0/sys.server/compiled/game/script/player/base/base_player.java +++ b/sku.0/sys.server/compiled/game/script/player/base/base_player.java @@ -12281,4 +12281,8 @@ public class base_player extends script.base_script warpPlayer(self, loc.area, loc.x, loc.y, loc.z, loc.cell, 0, 0, 0, "noHandler", false); return SCRIPT_CONTINUE; } + public int playerFactionalPresenceHeartbeat(obj_id self, dictionary params) throws InterruptedException { + gcw.grantGcwFactionalPresenceScore(self); + return SCRIPT_CONTINUE; + } } diff --git a/sku.0/sys.server/compiled/game/script/player/live_conversions.java b/sku.0/sys.server/compiled/game/script/player/live_conversions.java index fd0c3de55..8b1389d9c 100755 --- a/sku.0/sys.server/compiled/game/script/player/live_conversions.java +++ b/sku.0/sys.server/compiled/game/script/player/live_conversions.java @@ -104,6 +104,7 @@ public class live_conversions extends script.base_script handleEsbAnniversaryGifts(player); handleMailOptInRewards(player); handleCombatUpgradePlaqueReward(player); + startFactionalPresenceTrackingLoop(player); } public void runOncePerTravelConversions(obj_id player) throws InterruptedException { @@ -1006,4 +1007,11 @@ public class live_conversions extends script.base_script } } + /** + * Handles looper to start tracking factional presence + */ + public void startFactionalPresenceTrackingLoop(obj_id player) throws InterruptedException { + recurringMessageTo(player, "playerFactionalPresenceHeartbeat", null, 60.0f); + } + } diff --git a/sku.0/sys.shared/compiled/game/datatables/command/command_table.tab b/sku.0/sys.shared/compiled/game/datatables/command/command_table.tab index 0fd979067..4a0cb30d7 100755 --- a/sku.0/sys.shared/compiled/game/datatables/command/command_table.tab +++ b/sku.0/sys.shared/compiled/game/datatables/command/command_table.tab @@ -732,9 +732,9 @@ gmForceCommand immediate gmForceCommand admin 0 1 gmForceRank immediate cmdGMForceRank admin 1 1 0 1 1 0 0 0 0 optional 0 40 csr 0 gmFsVillage immediate cmdGMFsVillage admin 1 1 0 1 1 0 0 0 0 optional 0 40 csr 0 gmJediState immediate gmJediState admin 0 1 1 gm.cmd optional 0 40 csr 0 -gmr immediate gmRevive admin 1 1 0 1 1 none 0 40 csr 0 +gmr immediate cmdGmRevive admin 1 1 0 1 1 gm.cmd none 0 40 csr 0 gmregrantQuest immediate cmdGmRegrantQuest admin 0 1 gm.cmd none 0 40 csr 0 -gmRevive immediate gmRevive admin 1 1 0 1 1 none 0 40 csr 0 +gmRevive immediate cmdGmRevive admin 1 1 0 1 1 gm.cmd none 0 40 csr 0 gmShowQuest immediate cmdGmShowQuest admin 0 1 gm.cmd none 0 40 csr 0 gmWeapon immediate cmdGmWeapon admin 1 1 0 1 1 0 0 0 0 optional 0 40 csr 0 goto immediate cmdGoto failAdmin admin 1 1 0 1 1 gm.cmd optional 0 0 40 csr 0 diff --git a/sku.0/sys.shared/compiled/game/datatables/player/planet_map_cat.tab b/sku.0/sys.shared/compiled/game/datatables/player/planet_map_cat.tab index 88f136247..f6dfe1111 100755 --- a/sku.0/sys.shared/compiled/game/datatables/player/planet_map_cat.tab +++ b/sku.0/sys.shared/compiled/game/datatables/player/planet_map_cat.tab @@ -14,22 +14,22 @@ guild_university 11 0 1 hotel 12 medicalcenter 13 1 shuttleport 14 -starport 15 -themepark 16 -city 17 -waypoint 18 -trainer 19 -trainer_brawler 20 0 1 -trainer_artisan 21 0 1 -trainer_scout 22 0 1 -trainer_marksman 23 0 1 -trainer_entertainer 24 0 1 -trainer_medic 25 0 1 -junkshop 26 -tavern 27 1 -barracks 28 1 -vendor 29 -vendor_armor 30 0 1 +starport 15 +themepark 16 +city 17 +waypoint 18 +trainer 19 +trainer_brawler 20 0 1 +trainer_artisan 21 0 1 +trainer_scout 22 0 1 +trainer_marksman 23 0 1 +trainer_entertainer 24 0 1 +trainer_medic 25 0 1 +junkshop 26 +tavern 27 1 +barracks 28 1 +vendor 29 +vendor_armor 30 0 1 vendor_clothing 31 0 1 vendor_components 32 0 1 vendor_droids 33 0 1 @@ -88,3 +88,7 @@ gcw_factional_presence 83 gcw_factional_presence_rebel_only 84 0 1 gcw_factional_presence_imperial_only 85 0 1 gcw_factional_presence_rebel_and_imperial 86 0 1 +player_placed_factional_base 87 1 0 0 +player_placed_factional_base_rebel 88 0 1 1 +player_placed_factional_base_imperial 89 0 1 1 +vendor_chronicles 90 0 1 0