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 8210c5b80..d15cf53d5 100755 --- a/sku.0/sys.server/compiled/game/script/library/gcw.java +++ b/sku.0/sys.server/compiled/game/script/library/gcw.java @@ -3,6 +3,8 @@ package script.library; import script.*; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; public class gcw extends script.base_script { @@ -3329,4 +3331,69 @@ public class gcw extends script.base_script } } + /** + * Helper to determine if the given faction is winning the given control group + * by at least the provided threshold + * + * @param controlGroup string of a GcwGroup in gcw_score_category.iff, for example + * "tatooine" or "galaxy" + * @param faction int hash of faction (from e.g. pvpGetAlignedFaction() or + * FACTION_HASH_* const + * @param thresholdToWinBy the % score, between 1 and 100, that the faction control + * group must be winning by + * @return true if winning by at least the given threshold + */ + public static boolean isWinningByControlScoreForGroup(String controlGroup, int faction, int thresholdToWinBy) { + if(faction == FACTION_HASH_IMPERIAL) { + return getGcwGroupImperialScorePercentile(controlGroup) >= thresholdToWinBy; + } else if (faction == FACTION_HASH_REBEL) { + return (100 - getGcwGroupImperialScorePercentile(controlGroup)) >= thresholdToWinBy; + } + return false; + } + + /** + * This is a helper method for scaling a number based on a GCW Control Score Grouping + * for the given player's faction. It is used, for example, to scale the cloning sickness + * time and cost of GCW Officers to provide either a perk or penalty for not controlling + * that particular planet. + * + * @param controlGroup string of a GcwGroup in gcw_score_category.iff. In general, this can + * either be "galaxy" for the entire game or a specific planet name such + * as "tatooine" + * @param faction int hash of faction (from e.g. pvpGetAlignedFaction() or FACTION_HASH_* const + * @param initialValue int value as the base number to add multipliers to if it meets criteria + * otherwise you'll just get returned this value + * @param threshold the planetary control score that must be met for the faction as the minimum + * to start any multiplier actions (e.g. 70 is 70% planetary control) + * @param multiply boolean true if the thresholdSlide should multiply, false if it should divide + * @param atThresholdSlide the slide is what is applied to the base if the score at least meets + * the threshold and before any additional iteration. E.g. if at 70% means + * you've met the minimum, so the base should be cut in half, set this to 2. + * Set to 0 to do nothing. + * @param aboveThresholdIterateBy the amount of change that should happen for each score point above + * the threshold (e.g. continue to reduce base by 5 for each score point + * above the threshold. Can be positive or negative. Set to 0 to disable. + * @return scaled value if it meets the requirements, otherwise returns the initial value + */ + public static int getScaledValueFromControlScore(String controlGroup, int faction, int initialValue, int threshold, + boolean multiply, int atThresholdSlide, int aboveThresholdIterateBy) { + AtomicInteger scale = new AtomicInteger(initialValue); + int score = 0; + if(faction == FACTION_HASH_IMPERIAL) { + score = getGcwGroupImperialScorePercentile(controlGroup); + } else if (faction == FACTION_HASH_REBEL) { + score = (100 - getGcwGroupImperialScorePercentile(controlGroup)); + } + if(score >= threshold) { + if(atThresholdSlide != 0) { + scale.updateAndGet(v -> multiply ? v * atThresholdSlide : v / atThresholdSlide); + } + if(score > threshold && aboveThresholdIterateBy != 0) { + IntStream.rangeClosed(threshold, score).forEach(x -> { + scale.addAndGet(aboveThresholdIterateBy);}); + } + } + return scale.intValue(); + } } diff --git a/sku.0/sys.server/compiled/game/script/library/pclib.java b/sku.0/sys.server/compiled/game/script/library/pclib.java index 6582703d0..68781a382 100755 --- a/sku.0/sys.server/compiled/game/script/library/pclib.java +++ b/sku.0/sys.server/compiled/game/script/library/pclib.java @@ -160,6 +160,19 @@ public class pclib extends script.base_script public static final float MAX_CLONING_SICKNESS_COST = 5000; public static int getCloningSicknessCureCost(obj_id player) throws InterruptedException { + final String area = getLocation(player).area; + final int faction = pvpGetAlignedFaction(player); + final int oppositeFaction = faction == FACTION_HASH_IMPERIAL ? FACTION_HASH_REBEL : FACTION_HASH_IMPERIAL; + final int rank = pvpGetCurrentGcwRank(player); + // GU 17.2 for GCW Officers of the losing faction, the cost is 50,000CR for up to first 2 min after clone, based on other side's score + if(rank > 6 && gcw.isWinningByControlScoreForGroup(area, oppositeFaction, 70)) { + if(buff.hasBuff(player, "cloning_sickness") && buff.getBuffTimeRemaining(player, "cloning_sickness") >= 480) { + int penaltyTime = gcw.getScaledValueFromControlScore(area, oppositeFaction, 60, 70, false, 0, 2); + if(buff.getBuffTimeRemaining(player, "cloning_sickness") + penaltyTime >= 480) { + return 50000; + } + } + } float minCost = MIN_CLONING_SICKNESS_COST; float maxCost = MAX_CLONING_SICKNESS_COST; int city_id = city.checkCity(player, false); @@ -168,7 +181,13 @@ public class pclib extends script.base_script minCost = MIN_CLONING_SICKNESS_COST / 2; maxCost = MAX_CLONING_SICKNESS_COST / 2; } - return (int) (minCost + ((maxCost - minCost) * (getLevel(player) / 90.0f))); + // GU 17.2 for winners of the current faction, modify the cost of cloning based on planetary control score + final int costWithoutGcwModifier = (int) (minCost + ((maxCost - minCost) * (getLevel(player) / 90.0f))); + if(rank > 6) { + return Math.max((int)MIN_CLONING_SICKNESS_COST, gcw.getScaledValueFromControlScore(area, faction, costWithoutGcwModifier, 70, false, 2, -50)); + } else { + return costWithoutGcwModifier; + } } public static boolean canAffordCloningSicknessCure(obj_id player) throws InterruptedException { 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 8e994adaf..3b0bda20d 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 @@ -3,7 +3,6 @@ package script.player.base; import script.*; import script.library.*; -import java.util.Iterator; import java.util.Set; import java.util.Vector; @@ -3373,7 +3372,13 @@ public class base_player extends script.base_script playClientEffectObj(self, "clienteffect/player_clone_compile.cef", self, null); if (!utils.hasScriptVar(self, "no_cloning_sickness") && !instance.isInInstanceArea(self)) { - buff.applyBuff(self, "cloning_sickness"); + // GU 17.2 - scale down cloning sickness time for GCW Officers if they are + // currently on a planet their faction is winning >= 70% + int cloningSicknessTime = 600; + if(pvpGetCurrentGcwRank(self) > 6) { + cloningSicknessTime = gcw.getScaledValueFromControlScore(getLocation(self).area, pvpGetAlignedFaction(self), 600, 70, false, 2, -6); + } + buff.applyBuff(self, "cloning_sickness", cloningSicknessTime); } else if (utils.hasScriptVar(self, "no_cloning_sickness")) {