Various Updates

Refactors factional presence tracking from src to dsrc for more flexibility and hooking to GCW leaderboard for scaled scoring later
Addresses a number of faction base and faction presence GU items
Rescripted gmRevive to have more functionality
Restore Planet Map Cats to final day
This commit is contained in:
AconiteGodOfSWG
2021-03-31 12:13:09 -04:00
parent bb20b35fd8
commit 04a32e3e95
9 changed files with 531 additions and 65 deletions
@@ -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<obj_id> 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("");
}
}