From a9767f6f33faff00d7515c4704af7bc124bf3338 Mon Sep 17 00:00:00 2001 From: Cekis Date: Sat, 28 Jan 2017 23:38:35 +0000 Subject: [PATCH] Revamped City Invasion timer system to now work properly. --- .../compiled/game/script/library/gcw.java | 299 ++++++++++++------ .../game/script/planet/planet_base.java | 29 +- .../game/script/systems/gcw/gcw_city.java | 59 +++- .../script/systems/spawning/spawn_base.java | 15 +- 4 files changed, 290 insertions(+), 112 deletions(-) mode change 100644 => 100755 sku.0/sys.server/compiled/game/script/library/gcw.java mode change 100644 => 100755 sku.0/sys.server/compiled/game/script/planet/planet_base.java diff --git a/sku.0/sys.server/compiled/game/script/library/gcw.java b/sku.0/sys.server/compiled/game/script/library/gcw.java old mode 100644 new mode 100755 index dd17fb8e8..0488b22ab --- a/sku.0/sys.server/compiled/game/script/library/gcw.java +++ b/sku.0/sys.server/compiled/game/script/library/gcw.java @@ -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 activeCities = new Vector(); + 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 { diff --git a/sku.0/sys.server/compiled/game/script/planet/planet_base.java b/sku.0/sys.server/compiled/game/script/planet/planet_base.java old mode 100644 new mode 100755 index a3fe9d500..3d40e41a1 --- a/sku.0/sys.server/compiled/game/script/planet/planet_base.java +++ b/sku.0/sys.server/compiled/game/script/planet/planet_base.java @@ -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."); diff --git a/sku.0/sys.server/compiled/game/script/systems/gcw/gcw_city.java b/sku.0/sys.server/compiled/game/script/systems/gcw/gcw_city.java index 106c7bbb1..021a0fa2b 100755 --- a/sku.0/sys.server/compiled/game/script/systems/gcw/gcw_city.java +++ b/sku.0/sys.server/compiled/game/script/systems/gcw/gcw_city.java @@ -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; diff --git a/sku.0/sys.server/compiled/game/script/systems/spawning/spawn_base.java b/sku.0/sys.server/compiled/game/script/systems/spawning/spawn_base.java index 56b3b7a70..9500e28f1 100755 --- a/sku.0/sys.server/compiled/game/script/systems/spawning/spawn_base.java +++ b/sku.0/sys.server/compiled/game/script/systems/spawning/spawn_base.java @@ -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 {