diff --git a/src/hjsonpp/HjsonPlusPlusMod.java b/src/hjsonpp/HjsonPlusPlusMod.java index 672424e..01935cd 100644 --- a/src/hjsonpp/HjsonPlusPlusMod.java +++ b/src/hjsonpp/HjsonPlusPlusMod.java @@ -10,14 +10,12 @@ public HjsonPlusPlusMod(){ ClassMap.classes.put("TileGenerator", hjsonpp.expand.TileGenerator.class); ClassMap.classes.put("AdvancedCoreBlock", hjsonpp.expand.AdvancedCoreBlock.class); ClassMap.classes.put("GeneratorCoreBlock", hjsonpp.expand.GeneratorCoreBlock.class); - ClassMap.classes.put("ShieldCoreBlock", hjsonpp.expand.ShieldCoreBlock.class); ClassMap.classes.put("ColliderCrafter", hjsonpp.expand.ColiderCrafter.class); ClassMap.classes.put("AccelTurret", hjsonpp.expand.AccelTurret.class); - ClassMap.classes.put("OverHeatTurret", hjsonpp.expand.OverHeatTurret.class); - ClassMap.classes.put("RestorableWall", hjsonpp.expand.RestorableWall.class); + ClassMap.classes.put("OverheatTurret", hjsonpp.expand.OverHeatTurret.class); + //ClassMap.classes.put("HealingWall", hjsonpp.expand.HealingWall.class); ClassMap.classes.put("AdjustableShieldWall", hjsonpp.expand.AdjustableShieldWall.class); ClassMap.classes.put("AdjustableBeamNode", hjsonpp.expand.AdjustableBeamNode.class); - ClassMap.classes.put("DrawableBlock", hjsonpp.expand.DrawableBlock.class); ClassMap.classes.put("TiledFloor", hjsonpp.expand.TiledFloor.class); ClassMap.classes.put("DrawTeam", hjsonpp.expand.DrawTeam.class); ClassMap.classes.put("EffectWeapon", hjsonpp.expand.EffectWeapon.class); diff --git a/src/hjsonpp/expand/AccelTurret.java b/src/hjsonpp/expand/AccelTurret.java index e1f8860..8856197 100644 --- a/src/hjsonpp/expand/AccelTurret.java +++ b/src/hjsonpp/expand/AccelTurret.java @@ -1,18 +1,34 @@ package hjsonpp.expand; + import arc.Core; +import arc.graphics.Color; import arc.math.*; import arc.util.*; +import arc.util.io.*; +import hjsonpp.expand.meta.AdditionalStats; +import hjsonpp.util.Utilites; +import mindustry.content.Fx; +import mindustry.entities.Effect; import mindustry.entities.bullet.BulletType; import mindustry.graphics.Pal; import mindustry.ui.Bar; import mindustry.world.blocks.defense.turrets.*; +import mindustry.world.consumers.ConsumeLiquidFilter; +import mindustry.world.meta.Stat; +import mindustry.world.meta.StatUnit; +import static mindustry.Vars.tilesize; -// thanks to Sputnuc for giving me this code public class AccelTurret extends ItemTurret { public float speedUpPerShoot = 2; public float maxAccel = 0.5f; public float cooldownSpeed = 1; + public boolean canOverheat = false; + public float overheatMultiplier = 1f; + public float maxOverheatThreshold = 800f; + public int overheatTime = 60; + public float overheatEffectChance = 0.05f; + public Effect overheatEffect = Fx.none; public AccelTurret(String name){ super(name); @@ -23,40 +39,125 @@ public void setBars(){ super.setBars(); addBar("speedingUp", (AccelTurretBuild entity) -> new Bar( - () -> Core.bundle.format("bar.speedingUp", Strings.autoFixed((entity.speedUp)* 100, 0)), + () -> Core.bundle.format("bar.speedingUp", Strings.autoFixed((entity.speedUp/maxAccel) * 100, 0)), () -> Pal.powerBar, () -> entity.speedUp / maxAccel ) ); + if(canOverheat) addBar("overheat", (AccelTurretBuild entity) -> + new Bar( + () -> Core.bundle.format("bar.overheat", Strings.autoFixed((entity.overheat/maxOverheatThreshold) * 100, 0)), + () -> entity.overheated ? Color.valueOf("f54c4c") : Utilites.lerpColor(Color.valueOf("f0f7c3"), Color.valueOf("eb8e4b"), entity.overheat / maxOverheatThreshold), + () -> entity.overheat / maxOverheatThreshold + ) + ); } + @Override - public void init(){ - super.init(); + public void setStats(){ + super.setStats(); + stats.remove(Stat.reload); + stats.add(AdditionalStats.reloadFrom, reload / 60f, StatUnit.seconds); + stats.add(AdditionalStats.reloadTo, (reload / (maxAccel + 1.0f)) / 60f, StatUnit.seconds); } public class AccelTurretBuild extends ItemTurretBuild { - public float speedUp = 0; + protected float overheat = 0; + protected float speedUp = 0; + protected float coolantSpeedMultiplier; + protected float overheatCoolantSpdMultiplier; + protected boolean overheated = false; @Override public void updateTile() { - //coolDown progress - if (!isShooting() || !hasAmmo()){ - speedUp = Mathf.lerpDelta(speedUp, 0, cooldownSpeed / 20); + //cooldown progress + if (!isShooting() || !hasAmmo() || !isActive() || overheated && canOverheat){ + if(speedUp > 0) { + speedUp -= delta() * cooldownSpeed; + + }else { + speedUp = 0; + } + + if (overheat > 0) { + overheat -= delta() * 0.1f * cooldownSpeed; + overheat -= coolantSpeedMultiplier; + } + + if(overheated && Mathf.chance(overheatEffectChance)) overheatEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f)); + + } + checkOverheat(); + if(!overheated) { + super.updateTile(); + }else { + if(linearWarmup){ + shootWarmup = Mathf.approachDelta(shootWarmup, 0, shootWarmupSpeed); + }else{ + shootWarmup = Mathf.lerpDelta(shootWarmup, 0, shootWarmupSpeed); + } + + unit.tile(this); + unit.rotation(rotation); + unit.team(team); + speedUp = Mathf.approachDelta(speedUp, 0, cooldownSpeed * 2); + curRecoil = Mathf.approachDelta(curRecoil, 0, 1 / recoilTime); + recoilOffset.trns(rotation, -Mathf.pow(curRecoil, recoilPow) * recoil); + reloadCounter = Mathf.lerpDelta(reloadCounter, 0, 0.1f); + if(logicControlTime > 0){ + logicControlTime -= Time.delta; + } + } + } + + protected void updOverheatCooling(){ + if(overheated){ + if (coolant != null && coolant.efficiency(this) > 0 && efficiency > 0) { + coolant.update(this); + overheatCoolantSpdMultiplier = liquids.current() == null ? 0 : liquids.current().heatCapacity * coolantMultiplier; + } else overheatCoolantSpdMultiplier = 0; } - super.updateTile(); + } + + @Override + protected void updateCooling(){ + if(reloadCounter < reload && coolant != null && coolant.efficiency(this) > 0 && efficiency > 0){ + float capacity = coolant instanceof ConsumeLiquidFilter filter ? filter.getConsumed(this).heatCapacity : (coolant.consumes(liquids.current()) ? liquids.current().heatCapacity : 0.4f); + float amount = coolant.amount * coolant.efficiency(this); + coolant.update(this); + coolantSpeedMultiplier = amount * capacity * coolantMultiplier * ammoReloadMultiplier(); + if(Mathf.chance(0.06 * amount)){ + coolEffect.at(x + Mathf.range(size * tilesize / 2f), y + Mathf.range(size * tilesize / 2f)); + } + } + } + + public void checkOverheat(){ + if(overheat >= maxOverheatThreshold && !overheated && canOverheat) overheated = true; + if(overheated) { + overheat -= (delta() / overheatTime); + updOverheatCooling(); + overheat -= overheatCoolantSpdMultiplier; + if(overheat <= 0){ + overheat = 0; + overheated = false; + } + } + if (overheat < 0) overheat = 0; } @Override public void updateShooting(){ //override shooting method if (reloadCounter >= reload) { + if (!overheated || !canOverheat) { + BulletType type = peekAmmo(); - BulletType type = peekAmmo(); - - shoot(type); - reloadCounter = 0; + shoot(type); + reloadCounter = 0; + } } else { - reloadCounter += (1 + speedUp) * Time.delta * peekAmmo().reloadMultiplier * baseReloadSpeed(); + reloadCounter += (1 + speedUp) * edelta() * baseReloadSpeed(); } } @Override @@ -64,10 +165,29 @@ public void shoot(BulletType type){ //speedUp per shoot super.shoot(type); if (speedUp < maxAccel){ - speedUp += speedUpPerShoot * Time.delta; + speedUp += speedUpPerShoot * edelta(); + speedUp += coolantSpeedMultiplier * delta(); + if(speedUp>maxAccel) speedUp = maxAccel; }else { speedUp = maxAccel; } + if(canOverheat) overheat += delta() * speedUpPerShoot * overheatMultiplier; + } + @Override + public void write(Writes write){ + super.write(write); + write.f(speedUp); + write.f(overheat); + write.bool(overheated); + } + + @Override + public void read(Reads read, byte revision){ + super.read(read, revision); + speedUp = read.f(); + overheat = read.f(); + overheated = read.bool(); } } -} \ No newline at end of file +} + diff --git a/src/hjsonpp/expand/DrawableBlock.java b/src/hjsonpp/expand/DrawableBlock.java deleted file mode 100644 index d7552cc..0000000 --- a/src/hjsonpp/expand/DrawableBlock.java +++ /dev/null @@ -1,20 +0,0 @@ -package hjsonpp.expand; - -import arc.util.Nullable; -import mindustry.gen.Building; -import mindustry.world.Block; -import mindustry.world.draw.DrawBlock; - -public class DrawableBlock extends Block{ - public @Nullable DrawBlock drawer; - public DrawableBlock(String name){ - super(name); - } - - public class DrawableBlockBuild extends Building{ - @Override - public void draw(){ - drawer.draw(this); - } - } -} diff --git a/src/hjsonpp/expand/ShieldCoreBlock.java b/src/hjsonpp/expand/ShieldCoreBlock.java deleted file mode 100644 index 33c7994..0000000 --- a/src/hjsonpp/expand/ShieldCoreBlock.java +++ /dev/null @@ -1,322 +0,0 @@ -package hjsonpp.expand; - -import arc.Core; -import arc.Events; -import arc.func.Cons; -import arc.graphics.Blending; -import arc.graphics.Color; -import arc.graphics.g2d.Draw; -import arc.graphics.g2d.Fill; -import arc.graphics.g2d.Lines; -import arc.graphics.g2d.TextureRegion; -import arc.math.Mathf; -import arc.math.geom.Intersector; -import arc.struct.EnumSet; -import arc.struct.Seq; -import arc.util.*; -import arc.util.io.Reads; -import arc.util.io.Writes; -import mindustry.content.Fx; -import mindustry.entities.Effect; -import mindustry.game.EventType; -import mindustry.game.Team; -import mindustry.gen.Building; -import mindustry.gen.Bullet; -import mindustry.gen.Groups; -import mindustry.gen.Sounds; -import mindustry.graphics.Layer; -import mindustry.graphics.Pal; -import mindustry.logic.LAccess; -import mindustry.ui.Bar; -import mindustry.world.consumers.Consume; -import mindustry.world.consumers.ConsumeCoolant; -import mindustry.world.consumers.ConsumeItems; -import mindustry.world.draw.DrawBlock; -import mindustry.world.meta.*; - -import static mindustry.Vars.*; - -public class ShieldCoreBlock extends AdvancedCoreBlock { - public @Nullable DrawBlock drawer; - public TextureRegion topRegion; - - public final int timerUse = timers++; - public float phaseUseTime = 350f; - - public float phaseRadiusBoost = 80f; - public float phaseShieldBoost = 400f; - public float radius = 101.7f; - public int sides = 6; - public float shieldRotation = 0f; - public float shieldHealth = 700f; - public float cooldownNormal = 1.75f; - public float cooldownLiquid = 1.5f; - public float cooldownBrokenBase = 0.35f; - public float coolantConsumption = 0.1f; - public boolean consumeCoolant = true; - public float crashDamageMultiplier = 2f; - public Effect absorbEffect = Fx.absorb; - public Effect shieldBreakEffect = Fx.shieldBreak; - public ShieldCoreBlock(String name){ - super(name); - update = true; - solid = true; - group = BlockGroup.projectors; - hasPower = true; - hasLiquids = true; - hasItems = true; - envEnabled |= Env.space; - ambientSound = Sounds.shield; - ambientSoundVolume = 0.08f; - flags = EnumSet.of(BlockFlag.shield); - - if(consumeCoolant){ - consume(coolantConsumer = new ConsumeCoolant(coolantConsumption)).boost().update(false); - } - } - - @Override - public void load() { - super.load(); - topRegion = Core.atlas.find(name + "-top"); - } - - //Code below is fully yoinked from Anuke :p - - //TODO json support - public @Nullable Consume itemConsumer, coolantConsumer; - - protected static ShieldCoreBlockBuild paramEntity; - protected static Effect paramEffect; - protected static final Cons shieldConsumer = bullet -> { - if(bullet.team != paramEntity.team && bullet.type.absorbable && !bullet.absorbed && Intersector.isInRegularPolygon(((ShieldCoreBlock)(paramEntity.block)).sides, paramEntity.x, paramEntity.y, paramEntity.realRadius(), ((ShieldCoreBlock)(paramEntity.block)).shieldRotation, bullet.x, bullet.y)){ - bullet.absorb(); - paramEffect.at(bullet); - paramEntity.hit = 1f; - paramEntity.buildup += bullet.type.shieldDamage(bullet); - } - }; - - @Override - public void init(){ - updateClipRadius(radius + phaseRadiusBoost + 3f); - super.init(); - } - - @Override - public void setBars(){ - super.setBars(); - addBar("shield", (ShieldCoreBlockBuild entity) -> new Bar("stat.shieldhealth", Pal.accent, () -> entity.broken ? 0f : 1f - entity.buildup / (shieldHealth + phaseShieldBoost * entity.phaseHeat)).blink(Color.white)); - } - - @Override - public void setStats(){ - boolean consItems = itemConsumer != null; - - if(consItems) stats.timePeriod = phaseUseTime; - super.setStats(); - stats.add(Stat.shieldHealth, shieldHealth, StatUnit.none); - stats.add(Stat.cooldownTime, (int) (shieldHealth / cooldownBrokenBase / 60f), StatUnit.seconds); - - if(consItems && itemConsumer instanceof ConsumeItems coni){ - stats.remove(Stat.booster); - stats.add(Stat.booster, StatValues.itemBoosters("+{0} " + StatUnit.shieldHealth.localized(), stats.timePeriod, phaseShieldBoost, phaseRadiusBoost, coni.items)); - stats.add(Stat.booster, StatValues.speedBoosters("", coolantConsumption, Float.MAX_VALUE, true, this::consumesLiquid)); - } - } - - @Override - public void drawPlace(int x, int y, int rotation, boolean valid){ - super.drawPlace(x, y, rotation, valid); - - Draw.color(Pal.gray); - Lines.stroke(3f); - Lines.poly(x * tilesize + offset, y * tilesize + offset, sides, radius, shieldRotation); - Draw.color(player.team().color); - Lines.stroke(1f); - Lines.poly(x * tilesize + offset, y * tilesize + offset, sides, radius, shieldRotation); - Draw.color(); - } - - public class ShieldCoreBlockBuild extends AdvancedCoreBuild{ - public boolean broken = true; - public float buildup, radscl, hit, warmup, phaseHeat; - - public float range(){ - return realRadius(); - } - - @Override - public boolean shouldAmbientSound(){ - return !broken && realRadius() > 1f; - } - - @Override - public void onRemoved(){ - float radius = realRadius(); - if(!broken && radius > 1f) Fx.forceShrink.at(x, y, radius, team.color); - super.onRemoved(); - } - - @Override - public void pickedUp(){ - super.pickedUp(); - radscl = warmup = 0f; - } - - @Override - public boolean inFogTo(Team viewer){ - return false; - } - - @Override - public void updateTile(){ - boolean phaseValid = itemConsumer != null && itemConsumer.efficiency(this) > 0; - - phaseHeat = Mathf.lerpDelta(phaseHeat, Mathf.num(phaseValid), 0.1f); - - if(phaseValid && !broken && timer(timerUse, phaseUseTime) && efficiency > 0){ - consume(); - } - - radscl = Mathf.lerpDelta(radscl, broken ? 0f : warmup, 0.05f); - - if(Mathf.chanceDelta(buildup / shieldHealth * 0.1f)){ - Fx.reactorsmoke.at(x + Mathf.range(tilesize / 2f), y + Mathf.range(tilesize / 2f)); - } - - warmup = Mathf.lerpDelta(warmup, efficiency, 0.1f); - - if(buildup > 0){ - float scale = !broken ? cooldownNormal : cooldownBrokenBase; - - //TODO I hate this system - if(coolantConsumer != null){ - if(coolantConsumer.efficiency(this) > 0){ - coolantConsumer.update(this); - scale *= (cooldownLiquid * (1f + (liquids.current().heatCapacity - 0.4f) * 0.9f)); - } - } - - buildup -= delta() * scale; - } - - if(broken && buildup <= 0){ - broken = false; - } - - if(buildup >= shieldHealth + phaseShieldBoost * phaseHeat && !broken){ - broken = true; - buildup = shieldHealth; - shieldBreakEffect.at(x, y, realRadius(), team.color); - if(team != state.rules.defaultTeam){ - Events.fire(EventType.Trigger.forceProjectorBreak); - } - } - - if(hit > 0f){ - hit -= 1f / 5f * Time.delta; - } - - deflectBullets(); - } - - public void deflectBullets(){ - float realRadius = realRadius(); - - if(realRadius > 0 && !broken){ - paramEntity = this; - paramEffect = absorbEffect; - Groups.bullet.intersect(x - realRadius, y - realRadius, realRadius * 2f, realRadius * 2f, shieldConsumer); - } - } - - public boolean absorbExplosion(float ex, float ey, float damage){ - boolean absorb = !broken && Intersector.isInRegularPolygon(sides, x, y, realRadius(), shieldRotation, ex, ey); - if(absorb){ - absorbEffect.at(ex, ey); - hit = 1f; - buildup += damage * crashDamageMultiplier; - } - return absorb; - } - - public float realRadius(){ - return (radius + phaseHeat * phaseRadiusBoost) * radscl; - } - - @Override - public double sense(LAccess sensor){ - if(sensor == LAccess.heat) return buildup; - if(sensor == LAccess.shield) return broken ? 0f : Math.max(shieldHealth + phaseShieldBoost * phaseHeat - buildup, 0); - return super.sense(sensor); - } - - @Override - public void draw(){ - drawer.draw(this); - - if(buildup > 0f){ - Draw.alpha(buildup / shieldHealth * 0.75f); - Draw.z(Layer.blockAdditive); - Draw.blend(Blending.additive); - Draw.rect(topRegion, x, y); - Draw.blend(); - Draw.z(Layer.block); - Draw.reset(); - } - - drawShield(); - } - - public void drawShield(){ - if(!broken){ - float radius = realRadius(); - - if(radius > 0.001f){ - Draw.color(team.color, Color.white, Mathf.clamp(hit)); - - if(renderer.animateShields){ - Draw.z(Layer.shields + 0.001f * hit); - Fill.poly(x, y, sides, radius, shieldRotation); - }else{ - Draw.z(Layer.shields); - Lines.stroke(1.5f); - Draw.alpha(0.09f + Mathf.clamp(0.08f * hit)); - Fill.poly(x, y, sides, radius, shieldRotation); - Draw.alpha(1f); - Lines.poly(x, y, sides, radius, shieldRotation); - Draw.reset(); - } - } - } - - Draw.reset(); - } - - public void overwrote(Seq previous){ - if(previous.size > 0 && previous.first().block == block && previous.first() instanceof ShieldCoreBlockBuild b){ - broken = b.broken; - buildup = b.buildup; - } - } - - public void write(Writes write){ - super.write(write); - write.bool(broken); - write.f(buildup); - write.f(radscl); - write.f(warmup); - write.f(phaseHeat); - } - - public void read(Reads read, byte revision){ - super.read(read, revision); - broken = read.bool(); - buildup = read.f(); - radscl = read.f(); - warmup = read.f(); - phaseHeat = read.f(); - } - } -} \ No newline at end of file diff --git a/src/hjsonpp/expand/meta/AdditionalStats.java b/src/hjsonpp/expand/meta/AdditionalStats.java index 9c2555f..32bc7f5 100644 --- a/src/hjsonpp/expand/meta/AdditionalStats.java +++ b/src/hjsonpp/expand/meta/AdditionalStats.java @@ -6,5 +6,7 @@ public class AdditionalStats{ public static Stat healPercent = new Stat("heal-percent", StatCat.general), - produceChance = new Stat("produce-chance", StatCat.crafting); + produceChance = new Stat("produce-chance", StatCat.crafting), + reloadFrom = new Stat("expansion-reload-at-start", Stat.reload.category), + reloadTo = new Stat("expansion-reload-at-end", Stat.reload.category); } diff --git a/src/hjsonpp/util/Utilites.java b/src/hjsonpp/util/Utilites.java new file mode 100644 index 0000000..148b072 --- /dev/null +++ b/src/hjsonpp/util/Utilites.java @@ -0,0 +1,19 @@ +package hjsonpp.util; + +import arc.graphics.Color; +import arc.math.Mathf; + +public class Utilites { + public static Color lerpColor(Color color1, Color color2, float progress) { + progress = Mathf.clamp(progress, 0f, 1f); + + Color clr = new Color(); + + clr.r = Mathf.lerp(color1.r, color2.r, progress); + clr.g = Mathf.lerp(color1.g, color2.g, progress); + clr.b = Mathf.lerp(color1.b, color2.b, progress); + clr.a = Mathf.lerp(color1.a, color2.a, progress); + + return clr; + } +}