diff --git a/core/assets/maps/erekirwavemap.msav b/core/assets/maps/erekirwavemap.msav index a9ed758571..1b1a228980 100644 Binary files a/core/assets/maps/erekirwavemap.msav and b/core/assets/maps/erekirwavemap.msav differ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index f4dea45557..95a7129d2b 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -3763,14 +3763,14 @@ public class Blocks{ requirements(Category.turret, with(Items.beryllium, 150, Items.silicon, 200, Items.graphite, 200, Items.tungsten, 50)); ammo( - Items.graphite, new BasicBulletType(8f, 35){{ - knockback = 6f; + Items.graphite, new BasicBulletType(8f, 40){{ + knockback = 4f; width = 25f; hitSize = 7f; height = 20f; shootEffect = Fx.shootBigColor; smokeEffect = Fx.shootSmokeSquareSparse; - ammoMultiplier = 4; + ammoMultiplier = 1; hitColor = backColor = trailColor = Color.valueOf("ea8878"); frontColor = Color.valueOf("feb380"); trailWidth = 6f; @@ -3787,10 +3787,13 @@ public class Blocks{ coolantMultiplier = 6f; + inaccuracy = 0.2f; velocityRnd = 0.17f; shootShake = 1f; - ammoPerShot = 1; + ammoPerShot = 3; maxAmmo = 50; + consumeAmmoOnce = true; + drawer = new DrawTurret("reinforced-"){{ parts.add(new RegionPart("-front"){{ progress = PartProgress.warmup; @@ -3807,7 +3810,7 @@ public class Blocks{ reload = 30f; recoilAmount = 2f; restitution = 0.03f; - range = 110; + range = 125; shootCone = 50f; scaledHealth = 210; rotateSpeed = 3f; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index a6d95d17f1..749dcf4366 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -49,7 +49,7 @@ public class UnitTypes{ //air public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra, - evoke, avert, obviate; + avert, obviate; //air, legacy public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono; @@ -59,7 +59,7 @@ public class UnitTypes{ //air + payload public static @EntityDef({Unitc.class, Payloadc.class}) UnitType mega, - incite, emanate, quell, disrupt; + evoke, incite, emanate, quell, disrupt; //air + payload, legacy public static @EntityDef(value = {Unitc.class, Payloadc.class}, legacy = true) UnitType quad; @@ -986,7 +986,7 @@ public class UnitTypes{ //TODO balance //targetAir = false; targetFlags = new BlockFlag[]{BlockFlag.generator, null}; - hitSize = 7; + hitSize = 9; itemCapacity = 10; weapons.add(new Weapon(){{ @@ -3485,7 +3485,7 @@ public class UnitTypes{ accel = 0.09f; health = 600f; armor = 3f; - hitSize = 7f; + hitSize = 11f; engineOffset = 7f; engineSize = 2f; itemCapacity = 0; @@ -3549,7 +3549,7 @@ public class UnitTypes{ speed = 2f; rotateSpeed = 4f; accel = 0.09f; - health = 1000f; + health = 1100f; armor = 3f; hitSize = 12f; engineSize = 0; @@ -3574,7 +3574,7 @@ public class UnitTypes{ shoot = new ShootHelix(); //TODO cooler + balancing - bullet = new BasicBulletType(5f, 30){{ + bullet = new BasicBulletType(5f, 34){{ width = 7f; height = 12f; lifetime = 25f; @@ -3597,7 +3597,7 @@ public class UnitTypes{ accel = 0.09f; health = 2300f; armor = 6f; - hitSize = 18f; + hitSize = 25f; engineSize = 4.3f; engineOffset = 54f / 4f; fogRadius = 25; @@ -3968,6 +3968,8 @@ public class UnitTypes{ armor = 1f; hitSize = 9f; engineSize = 0; + payloadCapacity = 2f * 2f * tilesize * tilesize; + pickupUnits = false; fogRadius = 0f; targetable = false; @@ -4028,6 +4030,8 @@ public class UnitTypes{ health = 500f; armor = 2f; hitSize = 11f; + payloadCapacity = 2f * 2f * tilesize * tilesize; + pickupUnits = false; fogRadius = 0f; targetable = false; @@ -4103,6 +4107,8 @@ public class UnitTypes{ armor = 3f; hitSize = 12f; buildBeamOffset = 8f; + payloadCapacity = 2f * 2f * tilesize * tilesize; + pickupUnits = false; fogRadius = 0f; targetable = false; diff --git a/core/src/mindustry/entities/Damage.java b/core/src/mindustry/entities/Damage.java index 5f167a94cd..ce5a51e1d8 100644 --- a/core/src/mindustry/entities/Damage.java +++ b/core/src/mindustry/entities/Damage.java @@ -169,7 +169,7 @@ public class Damage{ }); Units.nearbyEnemies(b.team, rect, u -> { - if(u.checkTarget(b.type.collidesAir, b.type.collidesGround) && u.type.hittable){ + if(u.checkTarget(b.type.collidesAir, b.type.collidesGround) && u.hittable()){ distances.add(u.dst(b)); } }); @@ -269,7 +269,7 @@ public class Damage{ float x2 = vec.x + x, y2 = vec.y + y; Cons cons = e -> { - if(!e.type.hittable) return; + if(!e.hittable()) return; //the peirce cap works for units, but really terribly, I'm just disabling it for now. //if(pierceCap > 0 && pierceCount > pierceCap) return; @@ -369,7 +369,7 @@ public class Damage{ /** Damages all entities and blocks in a radius that are enemies of the team. */ public static void damageUnits(Team team, float x, float y, float size, float damage, Boolf predicate, Cons acceptor){ Cons cons = entity -> { - if(!predicate.get(entity) || !entity.type.hittable) return; + if(!predicate.get(entity) || !entity.hittable()) return; entity.hitbox(hitrect); if(!hitrect.overlaps(rect)){ @@ -433,7 +433,7 @@ public class Damage{ /** Damages all entities and blocks in a radius that are enemies of the team. */ public static void damage(Team team, float x, float y, float radius, float damage, boolean complete, boolean air, boolean ground, boolean scaled, Bullet source){ Cons cons = entity -> { - if(entity.team == team || !entity.type.hittable || !entity.within(x, y, radius + (scaled ? entity.hitSize / 2f : 0f)) || (entity.isFlying() && !air) || (entity.isGrounded() && !ground)){ + if(entity.team == team || !entity.hittable() || !entity.within(x, y, radius + (scaled ? entity.hitSize / 2f : 0f)) || (entity.isFlying() && !air) || (entity.isGrounded() && !ground)){ return; } diff --git a/core/src/mindustry/entities/Units.java b/core/src/mindustry/entities/Units.java index 86a65b3cf9..8fa5e6a975 100644 --- a/core/src/mindustry/entities/Units.java +++ b/core/src/mindustry/entities/Units.java @@ -129,7 +129,7 @@ public class Units{ (range != Float.MAX_VALUE && !target.within(x, y, range + (target instanceof Sized hb ? hb.hitSize()/2f : 0f))) || (target instanceof Teamc t && t.team() == team) || (target instanceof Healthc h && !h.isValid()) || - (target instanceof Unit u && !u.type.targetable); + (target instanceof Unit u && !u.targetable()); } /** See {@link #invalidateTarget(Posc, Team, float, float, float)} */ @@ -274,7 +274,7 @@ public class Units{ cpriority = -99999f; nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> { - if(e.dead() || !predicate.get(e) || e.team == Team.derelict || !e.type.targetable) return; + if(e.dead() || !predicate.get(e) || e.team == Team.derelict || !e.targetable()) return; float dst2 = e.dst2(x, y) - (e.hitSize * e.hitSize); if(dst2 < range*range && (result == null || dst2 < cdist || e.type.targetPriority > cpriority) && e.type.targetPriority >= cpriority){ @@ -296,7 +296,7 @@ public class Units{ cpriority = -99999f; nearbyEnemies(team, x - range, y - range, range*2f, range*2f, e -> { - if(e.dead() || !predicate.get(e) || e.team == Team.derelict || !e.within(x, y, range + e.hitSize/2f) || !e.type.targetable) return; + if(e.dead() || !predicate.get(e) || e.team == Team.derelict || !e.within(x, y, range + e.hitSize/2f) || !e.targetable()) return; float cost = sort.cost(e, x, y); if((result == null || cost < cdist || e.type.targetPriority > cpriority) && e.type.targetPriority >= cpriority){ diff --git a/core/src/mindustry/entities/comp/PayloadComp.java b/core/src/mindustry/entities/comp/PayloadComp.java index 40ab0200c6..7a622e646b 100644 --- a/core/src/mindustry/entities/comp/PayloadComp.java +++ b/core/src/mindustry/entities/comp/PayloadComp.java @@ -27,10 +27,6 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{ Seq payloads = new Seq<>(); - //uncomment for insanity - - - private transient @Nullable PowerGraph payloadPower; @Override @@ -65,12 +61,24 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{ } } + @Override + @Replace + public boolean targetable(){ + return type.targetable || (type.vulnerableWithPayloads && hasPayload()); + } + + @Override + @Replace + public boolean hittable(){ + return type.hittable || (type.vulnerableWithPayloads && hasPayload()); + } + float payloadUsed(){ return payloads.sumf(p -> p.size() * p.size()); } boolean canPickup(Unit unit){ - return payloadUsed() + unit.hitSize * unit.hitSize <= type.payloadCapacity + 0.001f && unit.team == team() && unit.isAI(); + return unit.type.pickupUnits && payloadUsed() + unit.hitSize * unit.hitSize <= type.payloadCapacity + 0.001f && unit.team == team() && unit.isAI(); } boolean canPickup(Building build){ diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index c91318f468..026c8d2d9e 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -260,7 +260,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Override @Replace public boolean collides(Hitboxc other){ - return type.hittable; + return hittable(); } @Override @@ -355,6 +355,14 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I } } + public boolean targetable(){ + return type.targetable; + } + + public boolean hittable(){ + return type.hittable; + } + @Override public void afterSync(){ //set up type info after reading diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index aceea51d39..e155df1a18 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -776,7 +776,7 @@ public class LExecutor{ void find(Ranged b, float range, int sortDir, Team team){ Units.nearby(team, b.x(), b.y(), range, u -> { - if(!u.within(b, range) || !u.type.targetable) return; + if(!u.within(b, range) || !u.targetable()) return; boolean valid = target1.func.get(b.team(), u) && diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index c6f7ec3638..88a5d8d0f9 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -100,7 +100,7 @@ public class UnitType extends UnlockableContent{ /** for ground units, the layer upon which this unit is drawn */ groundLayer = Layer.groundUnit, - /** Payload capacity of this unit in blocks^2 */ + /** Payload capacity of this unit in world units^2 */ payloadCapacity = 8, /** building speed multiplier; <0 to disable. */ buildSpeed = -1f, @@ -160,6 +160,10 @@ public class UnitType extends UnlockableContent{ killable = true, /** if false, this unit is not targeted by anything. */ targetable = true, + /** if true, this unit can be hit/targeted when it has payloads (assuming hittable/targetable is false) */ + vulnerableWithPayloads = false, + /** if true, this payload unit can pick up units */ + pickupUnits = true, /** if false, this unit does not physically collide with others. */ physics = true, /** if true, this ground unit will drown in deep liquids. */ @@ -188,7 +192,6 @@ public class UnitType extends UnlockableContent{ rotateMoveFirst = false, /** if true, this unit flashes when being healed */ healFlash = true, - /** whether the unit can heal blocks. Initialized in init() */ canHeal = false, /** if true, all weapons will attack the same target. */ @@ -310,7 +313,7 @@ public class UnitType extends UnlockableContent{ public float legLength = 10f, /** how fast individual legs move towards their destination (non-linear) */ legSpeed = 0.1f, - /** scale for how far in front (relative to unit velocity) legs try to place themselves */ + /** scale for how far in front (relative to unit velocity) legs try to place themselves; if legs lag behind a unit, increase this number */ legForwardScl = 1f, /** leg offset from the center of the unit */ legBaseOffset = 0f, diff --git a/core/src/mindustry/world/blocks/defense/turrets/Turret.java b/core/src/mindustry/world/blocks/defense/turrets/Turret.java index 15a9c6348f..e96f7f3e31 100644 --- a/core/src/mindustry/world/blocks/defense/turrets/Turret.java +++ b/core/src/mindustry/world/blocks/defense/turrets/Turret.java @@ -56,6 +56,8 @@ public class Turret extends ReloadTurret{ public int maxAmmo = 30; public int ammoPerShot = 1; + /** If true, ammo is only consumed once per shot regardless of bullet count. */ + public boolean consumeAmmoOnce = false; public float heatRequirement = -1f; public float maxHeatEfficiency = 3f; @@ -488,12 +490,16 @@ public class Turret extends ReloadTurret{ } totalShots ++; }); + + if(consumeAmmoOnce){ + useAmmo(); + } } protected void bullet(BulletType type, float xOffset, float yOffset, float angleOffset, Mover mover){ queuedBullets --; - if(dead || !hasAmmo()) return; + if(dead || (!consumeAmmoOnce && !hasAmmo())) return; float bulletX = x + Angles.trnsx(rotation - 90, shootX + xOffset, shootY + yOffset), @@ -522,7 +528,9 @@ public class Turret extends ReloadTurret{ recoil = recoilAmount; heat = 1f; - useAmmo(); + if(!consumeAmmoOnce){ + useAmmo(); + } } protected void handleBullet(@Nullable Bullet bullet, float offsetX, float offsetY, float angleOffset){