diff --git a/src/main/java/com/hbm/config/MobConfig.java b/src/main/java/com/hbm/config/MobConfig.java index 226372ebf..c98ee9c95 100644 --- a/src/main/java/com/hbm/config/MobConfig.java +++ b/src/main/java/com/hbm/config/MobConfig.java @@ -53,14 +53,5 @@ public class MobConfig { enableDucks = CommonConfig.createConfigBool(config, CATEGORY, "12.D00_enableDucks", "Whether pressing O should allow the player to duck", true); enableMobGear = CommonConfig.createConfigBool(config, CATEGORY, "12.D01_enableMobGear", "Whether zombies and skeletons should have additional gear when spawning", true); - - final String CAT_SIEGE = "SIEGE_MODE"; - - /// TODO /// } - - public static boolean enableDropships = true; - public static boolean enableSiegeBases = true; - public static double spawnDist = 64D; - public static boolean enableMissiles = false; } diff --git a/src/main/java/com/hbm/handler/SiegeOrchestrator.java b/src/main/java/com/hbm/handler/SiegeOrchestrator.java index 18918f993..b17b03fb6 100644 --- a/src/main/java/com/hbm/handler/SiegeOrchestrator.java +++ b/src/main/java/com/hbm/handler/SiegeOrchestrator.java @@ -1,10 +1,199 @@ package com.hbm.handler; +import com.hbm.entity.mob.siege.EntitySiegeZombie; +import com.hbm.util.ChatBuilder; +import com.hbm.util.GameRuleHelper; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.GameRules; import net.minecraft.world.World; public class SiegeOrchestrator { + public static boolean lastWave = false; + + private static int level = 0; + private static int levelCounter = 0; + + private static int siegeMobCount = 0; + public static void update(World world) { + //abort loop if sieges are disabled + if(!siegeEnabled(world)) + return; + + int waveTime = getWaveDuration(world); + int pauseTime = getPauseDuration(world); + int interval = waveTime + pauseTime; + //whether we're in a wave or pause, pauses apply first in an interval + boolean wave = (int)(world.getTotalWorldTime() % interval) >= pauseTime; + + //send a server-wide message when the wave starts and ends + if(!lastWave && wave) { + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(ChatBuilder.start("[SIEGE MODE] A new wave is starting!").color(EnumChatFormatting.RED).flush()); + } else if(lastWave && !wave) { + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(ChatBuilder.start("[SIEGE MODE] The wave has ended!").color(EnumChatFormatting.RED).flush()); + } + + //if we're on pause, do nothing + if(!wave) + return; + + int spawnDelay = getSpawnDelay(world); + boolean threshold = spawnThresholdEnabled(world); + int thresholdSize = getSpawnThreshold(world); + + //if threshold is enabled, don't go into the spawn loop if the entity count exceeds the threshold + if(!(threshold && siegeMobCount > thresholdSize)) { + for(Object o : world.playerEntities) { + EntityPlayer player = (EntityPlayer) o; + + if((world.getTotalWorldTime() + player.getEntityId()) % spawnDelay == 0) { + perPlayerSpawn(player); + } + } + } + + int countCap = getTierDelay(world); + int prevLevel = level; + levelCounter++; + + //if the counter has reached the cap, tick up the tier and reset the counter + while(levelCounter >= countCap) { + levelCounter -= countCap; + level++; + } + + //if the counter is below 0, bring up the counter and deduct a tier + while(levelCounter < 0) { + levelCounter += countCap; + level--; + } + + //if the tier has changed, send a broadcast + if(prevLevel != level) { + MinecraftServer.getServer().getConfigurationManager().sendChatMsg(ChatBuilder.start("[SIEGE MODE] The siege tier is now " + level + "!").color(EnumChatFormatting.RED).flush()); + } + + //every 10s we recount the loaded siege mobs + if(world.getTotalWorldTime() % 200 == 0) { + refreshMobCount(world); + } + } + + public static void perPlayerSpawn(EntityPlayer player) { + //TODO: either spawn siege mobs outright or dropships, depending on whether dropships are enabled + } + + public static void playerDeathHook(EntityPlayer player) { + + } + + public static void mobDeathHook(EntityLivingBase entity) { + + } + + private static void refreshMobCount(World world) { + + siegeMobCount = 0; + + for(Object o : world.loadedEntityList) { + Entity entity = (Entity) o; + + if(isSiegeMob(entity)) { + siegeMobCount++; + } + } + } + + public static boolean isSiegeMob(Entity entity) { + + if(entity instanceof EntitySiegeZombie) + return true; + + return false; + } + + public static final String KEY_SAVE_RULES = "siegeSaveRules"; + public static final String KEY_ENABLE_SIEGES = "siegeEnable"; + public static final String KEY_WAVE_DURATION = "siegeWaveDuration"; + public static final String KEY_PAUSE_DURATION = "siegePauseDuration"; + public static final String KEY_ENABLE_DROPS = "siegeEnableDropships"; + public static final String KEY_ENABLE_BASES = "siegeEnableBases"; + public static final String KEY_ENABLE_MISSILES = "siegeEnableMissiles"; + public static final String KEY_SPAWN_DIST = "siegeSpawnDist"; + public static final String KEY_SPAWN_DELAY = "siegeSpawnDelay"; + public static final String KEY_TIER_DELAY = "siegeTierDuration"; + public static final String KEY_TIER_ADD_KILL = "siegeTierAddKill"; + public static final String KEY_TIER_SUB_DEATH = "siegeTierSubDeath"; + public static final String KEY_SPAWN_THRESHOLD = "siegeEnableSpawnThreshold"; + public static final String KEY_SPAWN_THRESHOLD_COUNT = "siegeSpawnThreshold"; + + public static void createGameRules(World world) { + + GameRules rules = world.getGameRules(); + + if(!rules.getGameRuleBooleanValue(KEY_SAVE_RULES)) { + rules.setOrCreateGameRule(KEY_SAVE_RULES, "true"); + rules.setOrCreateGameRule(KEY_ENABLE_SIEGES, "false"); + rules.setOrCreateGameRule(KEY_WAVE_DURATION, "" + (20 * 60 * 20)); + rules.setOrCreateGameRule(KEY_PAUSE_DURATION, "" + (10 * 60 * 20)); + rules.setOrCreateGameRule(KEY_ENABLE_DROPS, "true"); + rules.setOrCreateGameRule(KEY_ENABLE_BASES, "true"); + rules.setOrCreateGameRule(KEY_ENABLE_MISSILES, "true"); + rules.setOrCreateGameRule(KEY_SPAWN_DIST, "64"); + rules.setOrCreateGameRule(KEY_SPAWN_DELAY, "" + (10 * 20)); + rules.setOrCreateGameRule(KEY_TIER_DELAY, "" + (15 * 60 * 20)); + rules.setOrCreateGameRule(KEY_TIER_ADD_KILL, "" + (5 * 20)); + rules.setOrCreateGameRule(KEY_TIER_SUB_DEATH, "" + (15 * 20)); + rules.setOrCreateGameRule(KEY_SPAWN_THRESHOLD, "true"); + rules.setOrCreateGameRule(KEY_SPAWN_THRESHOLD_COUNT, "50"); + } + } + + public static boolean siegeEnabled(World world) { + return world.getGameRules().getGameRuleBooleanValue(KEY_ENABLE_SIEGES); + } + + public static int getWaveDuration(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_WAVE_DURATION, 20 * 60 * 10, 1); + } + + public static int getPauseDuration(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_PAUSE_DURATION, 10 * 60 * 10, 0); + } + + public static double getSpawnDist(World world) { + return GameRuleHelper.getDoubleMinimum(world, KEY_SPAWN_DIST, 64, 0); + } + + public static int getSpawnDelay(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_SPAWN_DELAY, 10 * 20, 1); + } + + public static int getTierDelay(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_TIER_DELAY, 15 * 60 * 20, 1); + } + + public static int getTierAddKill(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_TIER_ADD_KILL, 5 * 20, 0); + } + + public static int getTierSubDeath(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_TIER_SUB_DEATH, 15 * 20, 0); + } + + public static boolean spawnThresholdEnabled(World world) { + return world.getGameRules().getGameRuleBooleanValue(KEY_SPAWN_THRESHOLD); + } + + public static int getSpawnThreshold(World world) { + return GameRuleHelper.getIntegerMinimum(world, KEY_SPAWN_THRESHOLD_COUNT, 50, 1); } } diff --git a/src/main/java/com/hbm/main/MainRegistry.java b/src/main/java/com/hbm/main/MainRegistry.java index c70d34209..7230af212 100644 --- a/src/main/java/com/hbm/main/MainRegistry.java +++ b/src/main/java/com/hbm/main/MainRegistry.java @@ -38,15 +38,7 @@ import org.apache.logging.log4j.Logger; import com.google.common.collect.ImmutableList; import com.hbm.blocks.ModBlocks; -import com.hbm.config.BombConfig; -import com.hbm.config.GeneralConfig; -import com.hbm.config.MachineConfig; -import com.hbm.config.MobConfig; -import com.hbm.config.PotionConfig; -import com.hbm.config.RadiationConfig; -import com.hbm.config.ToolConfig; -import com.hbm.config.WeaponConfig; -import com.hbm.config.WorldConfig; +import com.hbm.config.*; import com.hbm.creativetabs.*; import com.hbm.entity.effect.*; import com.hbm.entity.grenade.*; @@ -54,17 +46,13 @@ import com.hbm.entity.item.*; import com.hbm.entity.logic.*; import com.hbm.entity.missile.*; import com.hbm.entity.mob.*; -import com.hbm.entity.mob.botprime.EntityBOTPrimeBody; -import com.hbm.entity.mob.botprime.EntityBOTPrimeHead; -import com.hbm.entity.mob.siege.EntitySiegeZombie; -import com.hbm.entity.mob.siege.SiegeTier; +import com.hbm.entity.mob.botprime.*; +import com.hbm.entity.mob.siege.*; import com.hbm.entity.particle.*; import com.hbm.entity.projectile.*; import com.hbm.entity.qic.EntitySPV; import com.hbm.handler.*; -import com.hbm.handler.imc.IMCCentrifuge; -import com.hbm.handler.imc.IMCCrystallizer; -import com.hbm.handler.imc.IMCHandler; +import com.hbm.handler.imc.*; import com.hbm.handler.radiation.ChunkRadiationManager; import com.hbm.hazard.HazardRegistry; import com.hbm.inventory.*; @@ -80,8 +68,7 @@ import com.hbm.potion.HbmPotion; import com.hbm.saveddata.satellites.Satellite; import com.hbm.tileentity.TileMappings; import com.hbm.tileentity.bomb.TileEntityNukeCustom; -import com.hbm.tileentity.machine.TileEntityMachineReactorLarge; -import com.hbm.tileentity.machine.TileEntityNukeFurnace; +import com.hbm.tileentity.machine.*; import com.hbm.tileentity.machine.rbmk.RBMKDials; import com.hbm.util.ArmorUtil; import com.hbm.world.feature.SchistStratum; @@ -997,7 +984,9 @@ public class MainRegistry { //yes kids, this is where we would usually register commands @EventHandler public void serverStart(FMLServerStartingEvent event) { - RBMKDials.createDials(event.getServer().getEntityWorld()); + World world = event.getServer().getEntityWorld(); + RBMKDials.createDials(world); + SiegeOrchestrator.createGameRules(world); } private void loadConfig(FMLPreInitializationEvent event) { diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java index b0cb89638..c632fc364 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/RBMKDials.java @@ -1,6 +1,7 @@ package com.hbm.tileentity.machine.rbmk; import com.hbm.config.GeneralConfig; +import com.hbm.util.GameRuleHelper; import net.minecraft.util.MathHelper; import net.minecraft.world.GameRules; @@ -59,7 +60,7 @@ public class RBMKDials { * @return >0 */ public static double getPassiveCooling(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_PASSIVE_COOLING), 5.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_PASSIVE_COOLING), 5.0D), 0.0D); } /** @@ -68,7 +69,7 @@ public class RBMKDials { * @return [0;1] */ public static double getColumnHeatFlow(World world) { - return MathHelper.clamp_double(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_COLUMN_HEAT_FLOW), 5.0D), 0.0D, 1.0D); + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_COLUMN_HEAT_FLOW), 5.0D), 0.0D, 1.0D); } /** @@ -77,7 +78,7 @@ public class RBMKDials { * @return >0 */ public static double getFuelDiffusionMod(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_FUEL_DIFFUSION_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_FUEL_DIFFUSION_MOD), 1.0D), 0.0D); } /** @@ -86,7 +87,7 @@ public class RBMKDials { * @return [0;1] */ public static double getFuelHeatProvision(World world) { - return MathHelper.clamp_double(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_HEAT_PROVISION), 0.2D), 0.0D, 1.0D); + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_HEAT_PROVISION), 0.2D), 0.0D, 1.0D); } /** @@ -95,7 +96,7 @@ public class RBMKDials { * @return [0;15] */ public static int getColumnHeight(World world) { - return MathHelper.clamp_int(shittyWorkaroundParseInt(world.getGameRules().getGameRuleStringValue(KEY_COLUMN_HEIGHT), 4), 2, 16) - 1; + return MathHelper.clamp_int(GameRuleHelper.parseInt(world.getGameRules().getGameRuleStringValue(KEY_COLUMN_HEIGHT), 4), 2, 16) - 1; } /** @@ -113,7 +114,7 @@ public class RBMKDials { * @return >0 */ public static double getBoilerHeatConsumption(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_BOILER_HEAT_CONSUMPTION), 0.1D), 0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_BOILER_HEAT_CONSUMPTION), 0.1D), 0D); } /** @@ -122,7 +123,7 @@ public class RBMKDials { * @return >0 */ public static double getControlSpeed(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_CONTROL_SPEED_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_CONTROL_SPEED_MOD), 1.0D), 0.0D); } /** @@ -131,7 +132,7 @@ public class RBMKDials { * @return >0 */ public static double getReactivityMod(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_REACTIVITY_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_REACTIVITY_MOD), 1.0D), 0.0D); } /** @@ -140,7 +141,7 @@ public class RBMKDials { * @return >0 */ public static double getOutgasserMod(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_OUTGASSER_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_OUTGASSER_MOD), 1.0D), 0.0D); } /** @@ -149,7 +150,7 @@ public class RBMKDials { * @return >0 */ public static double getSurgeMod(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_SURGE_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_SURGE_MOD), 1.0D), 0.0D); } /** @@ -158,7 +159,7 @@ public class RBMKDials { * @return [1;100] */ public static int getFluxRange(World world) { - return MathHelper.clamp_int(shittyWorkaroundParseInt(world.getGameRules().getGameRuleStringValue(KEY_FLUX_RANGE), 5), 1, 100); + return MathHelper.clamp_int(GameRuleHelper.parseInt(world.getGameRules().getGameRuleStringValue(KEY_FLUX_RANGE), 5), 1, 100); } /** @@ -167,7 +168,7 @@ public class RBMKDials { * @return [1;100] */ public static int getReaSimRange(World world) { - return MathHelper.clamp_int(shittyWorkaroundParseInt(world.getGameRules().getGameRuleStringValue(KEY_REASIM_RANGE), 10), 1, 100); + return MathHelper.clamp_int(GameRuleHelper.parseInt(world.getGameRules().getGameRuleStringValue(KEY_REASIM_RANGE), 10), 1, 100); } /** @@ -176,7 +177,7 @@ public class RBMKDials { * @return [1;24] */ public static int getReaSimCount(World world) { - return MathHelper.clamp_int(shittyWorkaroundParseInt(world.getGameRules().getGameRuleStringValue(KEY_REASIM_COUNT), 6), 1, 24); + return MathHelper.clamp_int(GameRuleHelper.parseInt(world.getGameRules().getGameRuleStringValue(KEY_REASIM_COUNT), 6), 1, 24); } /** @@ -185,7 +186,7 @@ public class RBMKDials { * @return >0 */ public static double getReaSimOutputMod(World world) { - return Math.max(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_REASIM_MOD), 1.0D), 0.0D); + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_REASIM_MOD), 1.0D), 0.0D); } /** @@ -203,24 +204,6 @@ public class RBMKDials { * @return [0;1] */ public static double getReaSimBoilerSpeed(World world) { - return MathHelper.clamp_double(shittyWorkaroundParseDouble(world.getGameRules().getGameRuleStringValue(KEY_REASIM_BOILER_SPEED), 0.05D), 0.0D, 1.0D); - } - - //why make the double representation accessible in a game rule when you can just force me to add a second pointless parsing operation? - public static double shittyWorkaroundParseDouble(String s, double def) { - - try { - return Double.parseDouble(s); - } catch(Exception ex) { } - - return def; - } - public static int shittyWorkaroundParseInt(String s, int def) { - - try { - return Integer.parseInt(s); - } catch(Exception ex) { } - - return def; + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(KEY_REASIM_BOILER_SPEED), 0.05D), 0.0D, 1.0D); } } diff --git a/src/main/java/com/hbm/util/GameRuleHelper.java b/src/main/java/com/hbm/util/GameRuleHelper.java new file mode 100644 index 000000000..0811aa2a1 --- /dev/null +++ b/src/main/java/com/hbm/util/GameRuleHelper.java @@ -0,0 +1,38 @@ +package com.hbm.util; + +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +public class GameRuleHelper { + + public static double getClampedDouble(World world, String rule, double def, double min, double max) { + return MathHelper.clamp_double(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(rule), def), min, max); + } + + public static double getDoubleMinimum(World world, String rule, double def, double min) { + return Math.max(GameRuleHelper.parseDouble(world.getGameRules().getGameRuleStringValue(rule), def), min); + } + + public static int getIntegerMinimum(World world, String rule, int def, int min) { + return Math.max(GameRuleHelper.parseInt(world.getGameRules().getGameRuleStringValue(rule), def), min); + } + + public static double parseDouble(String s, double def) { + + try { + return Double.parseDouble(s); + } catch(Exception ex) { } + + return def; + } + + public static int parseInt(String s, int def) { + + try { + return Integer.parseInt(s); + } catch(Exception ex) { } + + return def; + } + +}