Revamped City Invasion timer system to now work properly.

This commit is contained in:
Cekis
2018-03-23 16:00:10 -07:00
committed by CekisSWG
parent 984f4e8368
commit a9767f6f33
4 changed files with 290 additions and 112 deletions
+200 -99
View File
@@ -1,25 +1,8 @@
package script.library;
import script.*;
import script.base_class.*;
import script.combat_engine.*;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
import script.base_script;
import script.ai.ai_combat;
import script.library.buff;
import script.library.colors_hex;
import script.library.factions;
import script.library.faction_perk;
import script.library.loot;
import script.library.pet_lib;
import script.library.prose;
import script.library.regions;
import script.library.space_flags;
import script.library.trial;
import script.library.utils;
import java.util.Vector;
public class gcw extends script.base_script
{
@@ -260,6 +243,7 @@ public class gcw extends script.base_script
public static final int GCW_TOKENS_LOSER_PARTICIPANTS = 10;
public static final int GCW_POINTS_CONSTRUCTION_PHASE = 100;
public static final int GCW_TOKENS_CONSTRUCTION_PHASE = 20;
public static final String[] INVASION_CITIES = {"dearic", "keren", "bestine"};
public static final String DEARIC_CITY_TABLE = "datatables/gcw/gcw_city_dearic.iff";
public static final String KEREN_CITY_TABLE = "datatables/gcw/gcw_city_keren.iff";
public static final String BESTINE_CITY_TABLE = "datatables/gcw/gcw_city_bestine.iff";
@@ -2811,9 +2795,9 @@ public class gcw extends script.base_script
{
time = 6;
}
if (time < 2)
if (time < 1)
{
time = 2;
time = 1;
}
return time;
}
@@ -2834,97 +2818,207 @@ public class gcw extends script.base_script
return false;
}
String cityConfig = getConfigSetting("GameServer", "gcwcity" + city);
if (cityConfig == null || cityConfig.length() <= 0)
if (cityConfig == null || (!cityConfig.equals("1") && !cityConfig.toLowerCase().equals("true")))
{
CustomerServiceLog("gcw_city_invasion", "gcw.gcwIsInvasionCityOn: GCW City: " + city + " is not configured to run a city invasion. Function returning False.");
return false;
}
return true;
}
public static int gcwGetCityInterval(String cityName, int cycle) throws InterruptedException
public static int gcwGetNextInvasionHour(String cityName) throws InterruptedException
{
if (cycle < 0 || cycle > 2)
int activeCityCount = gcwGetActiveCityCount();
int currentCycle = gcwCalculateInvasionCycle();
int invasionInterval = gcwGetTimeToInvasion();
int currentHour = player_structure.convertSecondsTime(getCalendarTime())[1];
// loop through possible cycles to find when the city will be next active.
int checkCycle = currentCycle;
int checkHour = currentHour;
for(int i = 0; i < activeCityCount; i++){
checkCycle++;
checkHour = checkHour + invasionInterval;
if(checkCycle >= activeCityCount) checkCycle = 0;
if(gcwHasInvasionInCycle(cityName, checkCycle)) {
break;
}
}
int nextHour = checkHour;
if(nextHour > 23)
nextHour = nextHour - 24;
return nextHour;
}
public static boolean gcwHasInvasionInCycle(String cityName, int cycle) throws InterruptedException
{
// if the max is set to 0 then nothing should happen.
int maxRunning = gcwGetInvasionMaximumRunning();
if(maxRunning == 0){
LOG("gcwlog","maxrunning is 0");
return false;
}
// if the total active cities is 0 or if the cycle is larger that the cities that are active
// then nothing should happen.
String[] activeCities = gcwGetActiveCities();
if(activeCities.length == 0 || cycle >= activeCities.length)
{
return -1;
LOG("gcwlog","no active cities or cycle is bigger than active cities. Active city length is " + activeCities.length + " and cycle is " + cycle);
return false;
}
int cityIndex = -1;
for(int i = 0; i < activeCities.length; i++){
if(activeCities[i].equals(cityName)){
cityIndex = i;
break;
}
}
// if the city in question was not found in the active cities then nothing should happen.
if(cityIndex == -1)
{
LOG("gcwlog","hmmm... " + cityName + " wasn't found in active cities...");
return false;
}
// make sure total active cities is capped at total available to be active.
if(maxRunning > activeCities.length)
maxRunning = INVASION_CITIES.length;
LOG("gcwlog","Checking if city (" + cityName + ") is active in cycle (" + cycle + ") with active city count of (" + activeCities.length + ") and max running (" + maxRunning + ") with city index of (" + cityIndex + ").");
switch(activeCities.length){
case 1:
return true;
case 2:
if(maxRunning == 1){
return cityIndex == cycle;
}
return true;
case 3:
switch(maxRunning){
case 1:
return cityIndex == cycle;
case 2:
return ((cycle == 0 && (cityIndex == 0 || cityIndex == 1))
|| (cycle == 1 && (cityIndex == 1 || cityIndex == 2))
|| (cycle == 2 && (cityIndex == 2 || cityIndex == 0)));
case 3:
return true;
}
break;
default:
return false;
}
return false;
/*
int totalActiveCities = gcwGetActiveCityCount();
if (cycle < 0 || cycle >= totalActiveCities)
{
return false;
}
int maximumRunning = gcwGetInvasionMaximumRunning();
int[] bestineSchedule = null;
int[] dearicSchedule = null;
int[] kerenSchedule = null;
boolean[] bestineSchedule = null;
boolean[] dearicSchedule = null;
boolean[] kerenSchedule = null;
switch (maximumRunning)
{
case 0:
return -1;
return false;
case 1:
bestineSchedule = new int[]
{
1,
0,
0
};
dearicSchedule = new int[]
{
0,
1,
0
};
kerenSchedule = new int[]
{
0,
0,
1
};
break;
bestineSchedule = new boolean[]
{
true,
false,
false
};
dearicSchedule = new boolean[]
{
false,
true,
false
};
kerenSchedule = new boolean[]
{
false,
false,
true
};
break;
case 2:
bestineSchedule = new int[]
{
1,
0,
1
};
dearicSchedule = new int[]
{
1,
1,
0
};
kerenSchedule = new int[]
{
0,
1,
1
};
break;
bestineSchedule = new boolean[]
{
true,
false,
true
};
dearicSchedule = new boolean[]
{
true,
true,
false
};
kerenSchedule = new boolean[]
{
false,
true,
true
};
break;
case 3:
return 1;
return true;
default:
return -1;
return false;
}
if (cityName.equals("bestine"))
{
return bestineSchedule[cycle];
if(gcwIsInvasionCityOn(cityName))
return bestineSchedule[cycle];
}
else if (cityName.equals("dearic"))
{
return dearicSchedule[cycle];
if(gcwIsInvasionCityOn(cityName))
return dearicSchedule[cycle];
}
else if (cityName.equals("keren"))
{
return kerenSchedule[cycle];
if(gcwIsInvasionCityOn(cityName))
return kerenSchedule[cycle];
}
return -1;
return false;
*/
}
public static String[] gcwGetActiveCities() throws InterruptedException
{
Vector<String> activeCities = new Vector<String>();
for (String cityName : INVASION_CITIES){
String value = getConfigSetting("GameServer", "gcwcity" + cityName);
if (value != null && (value.equals("1") || value.toLowerCase().equals("true"))) {
activeCities.add(cityName);
}
}
return activeCities.toArray(new String[activeCities.size()]);
}
public static int gcwGetActiveCityCount() throws InterruptedException
{
return gcwGetActiveCities().length;
}
public static int gcwCalculateInvasionCycle() throws InterruptedException
{
int invasionInterval = gcwGetTimeToInvasion();
int invasionInterval = gcwGetTimeToInvasion(); // from config setting.
int totalActiveCities = gcwGetActiveCityCount();
if (invasionInterval <= 0)
{
invasionInterval = 3;
}
int[] convertedCalendarTime = player_structure.convertSecondsTime(getCalendarTime());
int hour = convertedCalendarTime[1];
return ((hour / invasionInterval) % invasionInterval);
return ((hour / invasionInterval) % totalActiveCities);
}
// GMT
// Returns seconds until the next invasion
public static int gcwGetNextInvasionTime(String cityName) throws InterruptedException
{
LOG("gcwlog", "gcwGetNextInvasionTime cityName: " + cityName);
@@ -2933,49 +3027,56 @@ public class gcw extends script.base_script
LOG("gcwlog", "cityName: " + cityName + " !gcwIsInvasionCityOn(cityName): " + !gcwIsInvasionCityOn(cityName));
return -1;
}
// Get the invasion interval. Interval defines the amount of time between invasion cycles.
int invasionInterval = gcwGetTimeToInvasion();
// Divide by zero?
if (invasionInterval <= 0)
{
invasionInterval = 3;
invasionInterval = 3; // Default to an invasion every three hours; 8 per day per city, if all cities are on
}
int calendarTime = getCalendarTime();
int[] convertedCalendarTime = player_structure.convertSecondsTime(calendarTime);
int hour = convertedCalendarTime[1];
// get what cycle we are currently in. A cycle is defined as a single invasion and where it occurs in the day.
// Depending on configuration, each city may have 1 invasion per cycle. Interval determines the amount of time
// (in hours) between the start of each cycle.
int cycle = gcwCalculateInvasionCycle();
int nextCycle = cycle + 1;
if (nextCycle > 2 || 24 - hour <= invasionInterval)
int totalActiveCities = gcwGetActiveCityCount();
if (nextCycle >= totalActiveCities)
{
nextCycle = 0;
}
int nextInterval = gcwGetCityInterval(cityName, nextCycle);
LOG("gcwlog", "XXXXXXXX cityName: " + cityName + " nextInterval: " + nextInterval + " cycle: " + cycle + " hour: " + hour + " nextCycle: " + nextCycle);
if (nextInterval < 0)
// Find out if the given city is running in the next cycle or not.
boolean invasionOnNextInterval = gcwHasInvasionInCycle(cityName, nextCycle);
LOG("gcwlog", "XXXXXXXX cityName: " + cityName + (invasionOnNextInterval ? " does" : " does not") + " have an invasion next cycle. Cycle: " + cycle + " hour: " + hour + " nextCycle: " + nextCycle);
int nextHour;
// Next interval is skipped? Return the time to the next interval plus another interval cycle.
if (!invasionOnNextInterval)
{
LOG("gcwlog", "cityName: " + cityName + " nextInterval: " + nextInterval);
return -1;
// next hour should be the next time the given city should run.
nextHour = gcwGetNextInvasionHour(cityName);
}
if (nextInterval == 0)
else
{
int nextHour = hour + (invasionInterval - (hour % invasionInterval)) + invasionInterval;
if (nextHour > 23)
{
nextHour = nextHour - 24;
}
LOG("gcwlog", "cityName: " + cityName + " nextInterval: " + nextInterval + " nextHour: " + nextHour);
return secondsUntilNextDailyTime(nextHour, 0, 0);
// next hour should be the next time the given city should run.
nextHour = hour + invasionInterval;
}
if (nextInterval == 1)
if (nextHour > 23)
{
int nextHour = hour + (invasionInterval - (hour % invasionInterval));
if (nextHour > 23)
{
nextHour = nextHour - 24;
}
LOG("gcwlog", "cityName: " + cityName + " nextInterval: " + nextInterval + " nextHour: " + nextHour);
return secondsUntilNextDailyTime(nextHour, 0, 0);
nextHour = nextHour - 24;
}
LOG("gcwlog", "cityName: " + cityName + " nextInterval: " + nextInterval);
return -1;
LOG("gcwlog", "cityName: " + cityName + " nextInterval: " + invasionOnNextInterval + " nextHour: " + nextHour);
return secondsUntilNextDailyTime(nextHour, 0, 0);
}
public static boolean gcwTutorialCheck(obj_id player) throws InterruptedException
{
+20 -9
View File
@@ -1,16 +1,11 @@
package script.planet;
import script.*;
import script.base_class.*;
import script.combat_engine.*;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Vector;
import script.base_script;
import script.library.cloninglib;
import script.library.gcw;
import script.library.regions;
import script.library.scheduled_drop;
import script.library.utils;
@@ -189,6 +184,10 @@ public class planet_base extends script.base_script
return SCRIPT_CONTINUE;
}
String city = params.getString("city");
if(!gcw.gcwIsInvasionCityOn(city))
{
return SCRIPT_CONTINUE;
}
obj_id sequencer = params.getObjId("sequencer");
int messageGameTime = params.getInt("gameTime" + city);
int lastTrackTime = utils.getIntScriptVar(self, "gcw.lastTrackTime." + city);
@@ -208,6 +207,8 @@ public class planet_base extends script.base_script
{
return SCRIPT_CONTINUE;
}
// if there is no calendar_time it is assumed it has not run since server restart.
int scheduleTime = utils.getIntScriptVar(self, "gcw.calendar_time." + city);
int calendarTime = getCalendarTime();
int timeToInvasion = gcw.gcwGetNextInvasionTime(city);
@@ -215,28 +216,38 @@ public class planet_base extends script.base_script
{
timeToInvasion = 1;
}
// set calendar_time to essentially show that we've evaluated if an evasion has been run or not.
utils.setScriptVar(self, "gcw.calendar_time." + city, calendarTime);
// this is the case if we haven't run an invasion yet at all.
if (scheduleTime <= 0)
{
// timeToInvasion should never be in the past. Reset and try again - possibly skipping this cycle.
if (timeToInvasion < 0)
{
LOG("gcwlog", "gcwInvasionTracker city: " + city + " has an invalid time. Retrying the calculation.");
utils.removeScriptVar(self, "gcw.calendar_time." + city);
messageTo(self, "gcwInvasionTracker", params, 5.0f, false);
}
// the invasion is scheduled to start at some point... check this calc again when it is scheduled to start.
else
{
LOG("gcwlog", "gcwInvasionTracker city: " + city + " has not been run today. timeToInvasion: " + timeToInvasion);
messageTo(self, "gcwInvasionTracker", params, timeToInvasion, false);
messageTo(self, "gcwInvasionTracker", params, timeToInvasion, false); // check again when invasion is expected to start.
}
return SCRIPT_CONTINUE;
}
if (timeToInvasion > 0)
if (timeToInvasion >= 0 && gcw.gcwHasInvasionInCycle(city, gcw.gcwCalculateInvasionCycle()))
{
LOG("gcwlog", "gcwInvasionTracker city: " + city + " is starting now. Next invasion after this one: " + timeToInvasion);
LOG("gcwlog", "gcwInvasionTracker city: " + city + " is starting now. Next invasion after this one: " + timeToInvasion / 60 + " minutes from now.");
gcwInvasionMessage(self, sequencer, city);
messageTo(self, "gcwInvasionTracker", params, timeToInvasion, false);
}
else if(timeToInvasion >= 0){
LOG("gcwlog","gcwInvasionTracker city: " + city + " is not ready to start. Next invasion is scheduled to start in " + timeToInvasion / 60 + " minutes.");
messageTo(self, "gcwInvasionTracker", params, timeToInvasion, false);
}
else
{
LOG("gcwlog", "gcwInvasionTracker city: " + city + " has an invalid time. Retrying the calculation.");
@@ -21,6 +21,12 @@ public class gcw_city extends script.base_script
public static final float DEARIC_ANNOUNCEMENT_RADIUS = 650.0f;
public static final String COLOR_REBELS = "\\" + colors_hex.COLOR_REBELS;
public static final String COLOR_IMPERIALS = "\\" + colors_hex.COLOR_IMPERIALS;
/*
CITY_OBJECT_BESTINE 9835358 tatooine(-1292.5868, 12.0, -3590.0999)
CITY_OBJECT_DEARIC 9805353 talus(329.7967, 6.0, -2930.803)
CITY_OBJECT_KEREN 9865353 naboo(1434.6715, 13.0, 2771.1726)
*/
public static final obj_id CITY_OBJECT_BESTINE = getObjIdWithNull(9835358);
public static final obj_id CITY_OBJECT_DEARIC = getObjIdWithNull(9805353);
public static final obj_id CITY_OBJECT_KEREN = getObjIdWithNull(9865353);
@@ -248,7 +254,7 @@ public class gcw_city extends script.base_script
}
obj_id planet = getPlanetByName("tatooine");
String cityName = gcw.getCityFromTable(self);
if (cityName != null && cityName.length() > 0 && isIdValid(planet))
if (cityName != null && cityName.length() > 0 && isIdValid(planet) && gcw.gcwIsInvasionCityOn(cityName))
{
CustomerServiceLog("gcw_city_invasion", "gcw_city.checkForInvasion: The city sequencer object is being checked for a running invasion. session: " + params.getInt(trial.MESSAGE_SESSION));
params = new dictionary();
@@ -274,6 +280,11 @@ public class gcw_city extends script.base_script
}
return SCRIPT_CONTINUE;
}
/*
This is the messageHandler received when construction
phase starts.
*/
public int beginInvasion(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_announcement", "beginInvasion init");
@@ -295,6 +306,8 @@ public class gcw_city extends script.base_script
return SCRIPT_CONTINUE;
}
utils.removeScriptVar(self, "gcw.configOverride");
// If the invasion is already running, then do not start again.
if (utils.hasScriptVar(self, "gcw.invasionRunning"))
{
CustomerServiceLog("gcw_city_invasion", "gcw_city.beginInvasion: beginInvasion has been called but according to the city object AN INVASION IS CURRENTLY RUNNING. session: " + params.getInt(trial.MESSAGE_SESSION));
@@ -315,6 +328,8 @@ public class gcw_city extends script.base_script
return SCRIPT_CONTINUE;
}
int calendarTime = getCalendarTime();
// When did this city last have its invasion?
int[] convertedCalendarTime = player_structure.convertSecondsTime(calendarTime);
int hour = convertedCalendarTime[1];
CustomerServiceLog("gcw_city_invasion_started", "gcw_city.beginInvasion: cityName: " + cityName + " interval: " + gcw.gcwGetTimeToInvasion() + " cycle: " + gcw.gcwCalculateInvasionCycle() + " hour: " + hour);
@@ -436,6 +451,11 @@ public class gcw_city extends script.base_script
messageTo(self, "updateGcwMapData", params, 0.0f, false);
return SCRIPT_CONTINUE;
}
/*
This is the messageHandler received when the construction
phase is about to end.
*/
public int constructionEndsSoon(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_announcement", "constructionEndsSoon init");
@@ -493,6 +513,11 @@ public class gcw_city extends script.base_script
CustomerServiceLog("gcw_city_invasion", "gcw_city.constructionEndsSoon: constructionEndsSoon has sent all players messages regarding the construction phase ending soon. Message sent at: " + getGameTime() + " session: " + params.getInt(trial.MESSAGE_SESSION));
return SCRIPT_CONTINUE;
}
/*
This is the messageHandler received when the battle phase is
about to end.
*/
public int invasionEndsSoon(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_announcement", "invasionEndsSoon init");
@@ -778,6 +803,10 @@ public class gcw_city extends script.base_script
setInvulnerable(defendingGeneral, false);
return SCRIPT_CONTINUE;
}
/*
The City has been invaded and the defenders have lost.
*/
public int defendersEvacuate(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_announcement", "defendersEvacuate init");
@@ -889,6 +918,10 @@ public class gcw_city extends script.base_script
}
return SCRIPT_CONTINUE;
}
/*
The Defenders have won.
*/
public int cityAttackUnsuccessful(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_announcement", "cityAttackUnsuccessful init");
@@ -1027,6 +1060,17 @@ public class gcw_city extends script.base_script
CustomerServiceLog("gcw_city_invasion", "gcw_city.cleanupInvasion: cleanupInvasion is cleaning up all the assets for the battle. This happened at: " + getGameTime() + " session: " + params.getInt(trial.MESSAGE_SESSION));
return SCRIPT_CONTINUE;
}
/*
This handler updates the player overhead map. There are a few possible phases identified
in the handler:
1. Rebel Construction
2. Imperial Construction
3. Rebel Attack
4. Imperial Attack
5. Rebel Occupation
6. Imperial Occupation
*/
public int updateGcwMapData(obj_id self, dictionary params) throws InterruptedException
{
LOG("gcw_map_data", "updateGcwMapData init");
@@ -1052,6 +1096,11 @@ public class gcw_city extends script.base_script
LOG("gcw_map_data_faction", "(!isValidId(cityObject) || !exists(cityObject))");
return SCRIPT_CONTINUE;
}
/*
CHECK TO MAKE SURE THE CITY REGION FACTION IS THE SAME AS
THE OCCUPATION FACTION
*/
if (phase == gcw.GCW_CITY_PHASE_UNKNOWN)
{
LOG("gcw_map_data_faction", "verifyCurrentOccupyFaction");
@@ -1194,11 +1243,14 @@ public class gcw_city extends script.base_script
return false;
}
int percentage = gcw.getRebelPercentileByRegion(cityObject);
// Rebels own this region?
if (percentage > 50 && faction == factions.FACTION_FLAG_IMPERIAL)
{
LOG("gcw_map_data", "switchCurrentOccupyFaction switching to REB faction");
utils.setScriptVar(cityObject, "currentOccupyFaction", factions.FACTION_FLAG_REBEL);
}
// Imperials own this region
else if (percentage < 50 && faction == factions.FACTION_FLAG_REBEL)
{
LOG("gcw_map_data", "switchCurrentOccupyFaction switching to IMP faction");
@@ -1213,12 +1265,17 @@ public class gcw_city extends script.base_script
messageTo(cityObject, "updateGcwMapData", dict, 0.0f, false);
return true;
}
// The general is checked every 30 seconds to see if the object is valid.
public int checkGeneral(obj_id self, dictionary params) throws InterruptedException
{
// self is invalid if the object is null or does not exist
if (!isIdValid(self) || !exists(self))
{
return SCRIPT_CONTINUE;
}
// only process messageTo()'s that are for this version of the sequencer
if (!trial.verifySession(self, params))
{
return SCRIPT_CONTINUE;
@@ -257,6 +257,9 @@ public class spawn_base extends script.base_script
strFileName = "datatables/spawning/spawn_lists/" + strPlanetName + "/" + strPlanetName + "_" + strRegionName + ".iff";
break;
}
if(strFileName == null){
return null;
}
String[] strTemplates = dataTableGetStringColumn(strFileName, "strTemplate");
int[] intMinDifficulties = dataTableGetIntColumn(strFileName, "intMinDifficulty");
int[] intMaxDifficulties = dataTableGetIntColumn(strFileName, "intMaxDifficulty");
@@ -481,9 +484,15 @@ public class spawn_base extends script.base_script
}
public String getFictionalRegionFileName(String strPlanet, String strFullName) throws InterruptedException
{
String strRegionName = utils.unpackString(strFullName).getAsciiId();
LOG("spawning", "Unable to get spawns for planet (" + strPlanet + ") in region with name (" + strFullName + ").");
return "datatables/spawning/spawn_lists/" + strPlanet + "/" + strRegionName + ".iff";
try {
String strRegionName = utils.unpackString(strFullName).getAsciiId();
return "datatables/spawning/spawn_lists/" + strPlanet + "/" + strRegionName + ".iff";
}
catch(Exception e) {
LOG("spawning", "Unable to get spawns for planet (" + strPlanet + ") in region with name (" + strFullName + ").");
Thread.dumpStack();
return null;
}
}
public String getOverLoadRegionFileName(String strRegionName) throws InterruptedException
{