diff --git a/core/assets-raw/sprites/units/obviate-preview.png b/core/assets-raw/sprites/units/obviate-preview.png index aac82cee84..4a7553fffd 100644 Binary files a/core/assets-raw/sprites/units/obviate-preview.png and b/core/assets-raw/sprites/units/obviate-preview.png differ diff --git a/core/src/mindustry/ai/types/MinerAI.java b/core/src/mindustry/ai/types/MinerAI.java index bc9b1a9da9..0c71d98cdc 100644 --- a/core/src/mindustry/ai/types/MinerAI.java +++ b/core/src/mindustry/ai/types/MinerAI.java @@ -19,7 +19,7 @@ public class MinerAI extends AIController{ if(!(unit.canMine()) || core == null) return; - if(unit.mineTile != null && !unit.mineTile.within(unit, unit.type.miningRange)){ + if(unit.mineTile != null && !unit.mineTile.within(unit, unit.type.mineRange)){ unit.mineTile(null); } @@ -44,9 +44,9 @@ public class MinerAI extends AIController{ } if(ore != null){ - moveTo(ore, unit.type.miningRange / 2f, 20f); + moveTo(ore, unit.type.mineRange / 2f, 20f); - if(ore.block() == Blocks.air && unit.within(ore, unit.type.miningRange)){ + if(ore.block() == Blocks.air && unit.within(ore, unit.type.mineRange)){ unit.mineTile = ore; } diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index ccf9cbab6d..c9accc663e 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -192,7 +192,7 @@ public class UnitTypes{ ammoType = new ItemAmmoType(Items.thorium); mechStepParticles = true; - mechStepShake = 0.15f; + stepShake = 0.15f; singleTarget = true; drownTimeMultiplier = 4f; @@ -257,7 +257,7 @@ public class UnitTypes{ health = 24000; armor = 14f; mechStepParticles = true; - mechStepShake = 0.75f; + stepShake = 0.75f; drownTimeMultiplier = 6f; mechFrontSway = 1.9f; mechSideSway = 0.6f; @@ -408,7 +408,7 @@ public class UnitTypes{ buildSpeed = 1.7f; canBoost = true; armor = 9f; - landShake = 2f; + mechLandShake = 2f; riseSpeed = 0.05f; mechFrontSway = 0.55f; @@ -453,7 +453,7 @@ public class UnitTypes{ buildSpeed = 3f; mechStepParticles = true; - mechStepShake = 0.15f; + stepShake = 0.15f; ammoType = new PowerAmmoType(2500); drownTimeMultiplier = 4f; @@ -467,7 +467,7 @@ public class UnitTypes{ health = 8200f; armor = 9f; canBoost = true; - landShake = 4f; + mechLandShake = 4f; immunities = ObjectSet.with(StatusEffects.burning); singleTarget = true; @@ -533,7 +533,7 @@ public class UnitTypes{ hitSize = 29f; health = 18000f; armor = 9f; - landShake = 1.5f; + stepShake = 1.5f; rotateSpeed = 1.5f; drownTimeMultiplier = 6f; @@ -541,9 +541,9 @@ public class UnitTypes{ legLength = 14f; legBaseOffset = 11f; legMoveSpace = 1.5f; - legTrns = 0.58f; + legForwardScl = 0.58f; hovering = true; - visualElevation = 0.2f; + shadowElevation = 0.2f; ammoType = new PowerAmmoType(4000); groundLayer = Layer.legUnit; @@ -649,13 +649,13 @@ public class UnitTypes{ legCount = 4; legLength = 9f; - legTrns = 0.6f; + legForwardScl = 0.6f; legMoveSpace = 1.4f; hovering = true; armor = 3f; ammoType = new ItemAmmoType(Items.coal); - visualElevation = 0.2f; + shadowElevation = 0.2f; groundLayer = Layer.legUnit - 1f; weapons.add(new Weapon("atrax-weapon"){{ @@ -687,14 +687,14 @@ public class UnitTypes{ immunities = ObjectSet.with(StatusEffects.burning, StatusEffects.melting); legCount = 6; legLength = 13f; - legTrns = 0.8f; + legForwardScl = 0.8f; legMoveSpace = 1.4f; legBaseOffset = 2f; hovering = true; armor = 5f; ammoType = new PowerAmmoType(1000); - visualElevation = 0.3f; + shadowElevation = 0.3f; groundLayer = Layer.legUnit; weapons.add(new Weapon("spiroct-weapon"){{ @@ -757,7 +757,7 @@ public class UnitTypes{ legLength = 30f; legExtension = -15; legBaseOffset = 10f; - landShake = 1f; + stepShake = 1f; legLengthScl = 0.96f; rippleScale = 2f; legSpeed = 0.2f; @@ -768,7 +768,7 @@ public class UnitTypes{ drownTimeMultiplier = 2f; hovering = true; - visualElevation = 0.65f; + shadowElevation = 0.65f; groundLayer = Layer.legUnit; BulletType sapper = new SapBulletType(){{ @@ -860,7 +860,7 @@ public class UnitTypes{ legLength = 75f; legExtension = -20; legBaseOffset = 8f; - landShake = 1f; + stepShake = 1f; legLengthScl = 0.93f; rippleScale = 3f; legSpeed = 0.19f; @@ -870,7 +870,7 @@ public class UnitTypes{ legSplashRange = 60; hovering = true; - visualElevation = 0.95f; + shadowElevation = 0.95f; groundLayer = Layer.legUnit; weapons.add( @@ -1181,7 +1181,6 @@ public class UnitTypes{ engineOffset = 38; engineSize = 7.3f; hitSize = 58f; - destructibleWreck = false; armor = 13f; targetFlags = new BlockFlag[]{BlockFlag.reactor, BlockFlag.battery, BlockFlag.core, null}; ammoType = new ItemAmmoType(Items.thorium); @@ -1263,7 +1262,7 @@ public class UnitTypes{ engineSize = 1.8f; engineOffset = 5.7f; range = 50f; - isCounted = false; + isEnemy = false; ammoType = new PowerAmmoType(500); @@ -1339,12 +1338,12 @@ public class UnitTypes{ lowAltitude = true; flying = true; engineOffset = 10.5f; - rotateShooting = false; + faceTarget = false; hitSize = 16.05f; engineSize = 3f; payloadCapacity = (2 * 2) * tilePayload; buildSpeed = 2.6f; - isCounted = false; + isEnemy = false; ammoType = new PowerAmmoType(1100); @@ -1391,7 +1390,7 @@ public class UnitTypes{ circleTarget = true; engineOffset = 13f; engineSize = 7f; - rotateShooting = false; + faceTarget = false; hitSize = 36f; payloadCapacity = (3 * 3) * tilePayload; buildSpeed = 2.5f; @@ -1462,7 +1461,7 @@ public class UnitTypes{ flying = true; engineOffset = 46f; engineSize = 7.8f; - rotateShooting = false; + faceTarget = false; hitSize = 66f; payloadCapacity = (5.5f * 5.5f) * tilePayload; buildSpeed = 4f; @@ -1484,7 +1483,7 @@ public class UnitTypes{ health = 280; accel = 0.4f; rotateSpeed = 3.3f; - rotateShooting = false; + faceTarget = false; armor = 2f; @@ -1540,13 +1539,13 @@ public class UnitTypes{ armor = 4f; accel = 0.3f; rotateSpeed = 2.6f; - rotateShooting = false; + faceTarget = false; ammoType = new ItemAmmoType(Items.graphite); trailLength = 20; - trailX = 5.5f; - trailY = -4f; - trailScl = 1.9f; + waveTrailX = 5.5f; + waveTrailY = -4f; + tailScl = 1.9f; weapons.add(new Weapon("mount-weapon"){{ reload = 10f; @@ -1599,13 +1598,13 @@ public class UnitTypes{ drag = 0.17f; hitSize = 20f; armor = 7f; - rotateShooting = false; + faceTarget = false; ammoType = new ItemAmmoType(Items.graphite); trailLength = 22; - trailX = 7f; - trailY = -9f; - trailScl = 1.5f; + waveTrailX = 7f; + waveTrailY = -9f; + tailScl = 1.5f; abilities.add(new ShieldRegenFieldAbility(20f, 40f, 60f * 4, 60f)); @@ -1696,13 +1695,13 @@ public class UnitTypes{ hitSize = 39f; accel = 0.2f; rotateSpeed = 1.3f; - rotateShooting = false; + faceTarget = false; ammoType = new ItemAmmoType(Items.thorium); trailLength = 50; - trailX = 18f; - trailY = -21f; - trailScl = 3f; + waveTrailX = 18f; + waveTrailY = -21f; + tailScl = 3f; weapons.add(new Weapon("sei-launcher"){{ @@ -1786,7 +1785,7 @@ public class UnitTypes{ armor = 16f; accel = 0.19f; rotateSpeed = 0.9f; - rotateShooting = false; + faceTarget = false; ammoType = new PowerAmmoType(4000); float spawnTime = 60f * 15f; @@ -1794,9 +1793,9 @@ public class UnitTypes{ abilities.add(new UnitSpawnAbility(flare, spawnTime, 19.25f, -31.75f), new UnitSpawnAbility(flare, spawnTime, -19.25f, -31.75f)); trailLength = 70; - trailX = 23f; - trailY = -32f; - trailScl = 3.5f; + waveTrailX = 23f; + waveTrailY = -32f; + tailScl = 3.5f; weapons.add(new Weapon("omura-cannon"){{ reload = 110f; @@ -1839,9 +1838,9 @@ public class UnitTypes{ accel = 0.4f; rotateSpeed = 5f; trailLength = 20; - trailX = 5f; - trailScl = 1.3f; - rotateShooting = false; + waveTrailX = 5f; + tailScl = 1.3f; + faceTarget = false; range = 100f; ammoType = new PowerAmmoType(900); armor = 3f; @@ -1926,12 +1925,12 @@ public class UnitTypes{ armor = 4f; accel = 0.4f; rotateSpeed = 4f; - rotateShooting = false; + faceTarget = false; trailLength = 22; - trailX = 5.5f; - trailY = -4f; - trailScl = 1.9f; + waveTrailX = 5.5f; + waveTrailY = -4f; + tailScl = 1.9f; ammoType = new ItemAmmoType(Items.coal); abilities.add(new StatusFieldAbility(StatusEffects.overclock, 60f * 6, 60f * 6f, 60f)); @@ -2002,13 +2001,13 @@ public class UnitTypes{ drag = 0.16f; hitSize = 20f; armor = 6f; - rotateShooting = false; + faceTarget = false; ammoType = new ItemAmmoType(Items.graphite); trailLength = 23; - trailX = 9f; - trailY = -9f; - trailScl = 2f; + waveTrailX = 9f; + waveTrailY = -9f; + tailScl = 2f; buildSpeed = 2f; @@ -2139,7 +2138,7 @@ public class UnitTypes{ hitSize = 44f; accel = 0.2f; rotateSpeed = 1.4f; - rotateShooting = false; + faceTarget = false; ammoType = new PowerAmmoType(3500); ammoCapacity = 40; @@ -2147,9 +2146,9 @@ public class UnitTypes{ clipSize = 250f; trailLength = 50; - trailX = 18f; - trailY = -17f; - trailScl = 3.2f; + waveTrailX = 18f; + waveTrailY = -17f; + tailScl = 3.2f; buildSpeed = 3f; @@ -2184,13 +2183,13 @@ public class UnitTypes{ armor = 16f; accel = 0.2f; rotateSpeed = 1.1f; - rotateShooting = false; + faceTarget = false; ammoType = new PowerAmmoType(4500); trailLength = 70; - trailX = 23f; - trailY = -32f; - trailScl = 3.5f; + waveTrailX = 23f; + waveTrailY = -32f; + tailScl = 3.5f; buildSpeed = 3.5f; @@ -2335,7 +2334,7 @@ public class UnitTypes{ alpha = new UnitType("alpha"){{ aiController = BuilderAI::new; - isCounted = false; + isEnemy = false; lowAltitude = true; flying = true; @@ -2372,7 +2371,7 @@ public class UnitTypes{ beta = new UnitType("beta"){{ aiController = BuilderAI::new; - isCounted = false; + isEnemy = false; flying = true; mineSpeed = 7f; @@ -2386,7 +2385,7 @@ public class UnitTypes{ health = 170f; engineOffset = 6f; hitSize = 9f; - rotateShooting = false; + faceTarget = false; lowAltitude = true; weapons.add(new Weapon("small-mount-weapon"){{ @@ -2412,7 +2411,7 @@ public class UnitTypes{ gamma = new UnitType("gamma"){{ aiController = BuilderAI::new; - isCounted = false; + isEnemy = false; lowAltitude = true; flying = true; @@ -2840,6 +2839,7 @@ public class UnitTypes{ health = 680; armor = 4f; legStraightness = 0.3f; + stepShake = 0f; legCount = 6; legLength = 8f; @@ -2847,17 +2847,17 @@ public class UnitTypes{ legContinuousMove = true; legExtension = -2f; legBaseOffset = 3f; - maxStretch = 1.1f; - maxCompress = 0.2f; + legMaxLength = 1.1f; + legMinLength = 0.2f; legLengthScl = 0.96f; - legTrns = 1.1f; + legForwardScl = 1.1f; legGroupSize = 3; rippleScale = 0.2f; legMoveSpace = 1f; hovering = true; - visualElevation = 0.1f; + shadowElevation = 0.1f; groundLayer = Layer.legUnit - 1f; targetAir = false; @@ -2918,6 +2918,7 @@ public class UnitTypes{ rotateSpeed = 3f; health = 1100; armor = 5f; + stepShake = 0f; legCount = 4; legLength = 14f; @@ -2925,15 +2926,15 @@ public class UnitTypes{ legContinuousMove = true; legExtension = -3f; legBaseOffset = 5f; - maxStretch = 1.1f; - maxCompress = 0.2f; + legMaxLength = 1.1f; + legMinLength = 0.2f; legLengthScl = 0.95f; - legTrns = 0.7f; + legForwardScl = 0.7f; legMoveSpace = 1f; hovering = true; - visualElevation = 0.2f; + shadowElevation = 0.2f; groundLayer = Layer.legUnit - 1f; for(int i = 0; i < 5; i++){ @@ -3023,6 +3024,7 @@ public class UnitTypes{ health = 2600; armor = 7f; fogRadius = 40f; + stepShake = 0f; legCount = 6; legLength = 18f; @@ -3031,15 +3033,15 @@ public class UnitTypes{ legContinuousMove = true; legExtension = -3f; legBaseOffset = 7f; - maxStretch = 1.1f; - maxCompress = 0.2f; + legMaxLength = 1.1f; + legMinLength = 0.2f; legLengthScl = 0.95f; - legTrns = 0.9f; + legForwardScl = 0.9f; legMoveSpace = 1f; hovering = true; - visualElevation = 0.2f; + shadowElevation = 0.2f; groundLayer = Layer.legUnit - 1f; for(int j = 0; j < 3; j++){ @@ -3176,7 +3178,7 @@ public class UnitTypes{ legGroupSize = 3; legStraightness = 0.4f; baseLegStraightness = 0.5f; - maxStretch = 1.3f; + legMaxLength = 1.3f; abilities.add(new ShieldArcAbility(){{ region = "bulwark-shield"; @@ -3193,10 +3195,10 @@ public class UnitTypes{ legCount = 6; legLength = 15f; - legTrns = 0.45f; + legForwardScl = 0.45f; legMoveSpace = 1.4f; rippleScale = 2f; - landShake = 0.5f; + stepShake = 0.5f; legExtension = -5f; legBaseOffset = 5f; @@ -3207,7 +3209,7 @@ public class UnitTypes{ drownTimeMultiplier = 2f; hovering = true; - visualElevation = 0.4f; + shadowElevation = 0.4f; groundLayer = Layer.legUnit; weapons.add(new Weapon("bulwark-weapon"){{ @@ -3280,15 +3282,15 @@ public class UnitTypes{ legCount = 8; legLength = 30f; - legTrns = 2.1f; + legForwardScl = 2.1f; legMoveSpace = 1.05f; rippleScale = 1.2f; - landShake = 0.5f; + stepShake = 0.5f; legGroupSize = 2; legExtension = -6f; legBaseOffset = 19f; legStraightLength = 0.9f; - maxStretch = 1.2f; + legMaxLength = 1.2f; ammoType = new PowerAmmoType(2000); @@ -3297,7 +3299,7 @@ public class UnitTypes{ drownTimeMultiplier = 2f; hovering = true; - visualElevation = 0.4f; + shadowElevation = 0.4f; groundLayer = Layer.legUnit; weapons.add(new Weapon("krepost-weapon"){{ @@ -3384,7 +3386,7 @@ public class UnitTypes{ osc = new ErekirUnitType("osc"){{ hovering = true; - visualElevation = 0.1f; + shadowElevation = 0.1f; drag = 0.07f; speed = 2f; @@ -3855,7 +3857,7 @@ public class UnitTypes{ evoke = new ErekirUnitType("evoke"){{ coreUnitDock = true; controller = u -> new BuilderAI(true, coreFleeRange); - isCounted = false; + isEnemy = false; envDisabled = 0; targetPriority = -2; @@ -3916,7 +3918,7 @@ public class UnitTypes{ incite = new ErekirUnitType("incite"){{ coreUnitDock = true; controller = u -> new BuilderAI(true, coreFleeRange); - isCounted = false; + isEnemy = false; envDisabled = 0; targetPriority = -2; @@ -3990,7 +3992,7 @@ public class UnitTypes{ emanate = new ErekirUnitType("emanate"){{ coreUnitDock = true; controller = u -> new BuilderAI(true, coreFleeRange); - isCounted = false; + isEnemy = false; envDisabled = 0; targetPriority = -2; @@ -4067,7 +4069,7 @@ public class UnitTypes{ manifold = new ErekirUnitType("manifold"){{ aiController = CargoAI::new; - isCounted = false; + isEnemy = false; allowedInPayloads = false; logicControllable = false; playerControllable = false; @@ -4106,7 +4108,7 @@ public class UnitTypes{ targetable = false; outlineColor = Pal.darkOutline; - isCounted = false; + isEnemy = false; hidden = true; useUnitCap = false; logicControllable = false; @@ -4122,7 +4124,7 @@ public class UnitTypes{ drag = 0.08f; speed = 3f; drawCell = false; - logicControllable = playerControllable = allowedInPayloads = isCounted = false; + logicControllable = playerControllable = allowedInPayloads = isEnemy = false; hidden = true; engineSize = 0f; diff --git a/core/src/mindustry/core/Logic.java b/core/src/mindustry/core/Logic.java index 5a415c6b3a..ce0ff2d460 100644 --- a/core/src/mindustry/core/Logic.java +++ b/core/src/mindustry/core/Logic.java @@ -476,7 +476,7 @@ public class Logic implements ApplicationListener{ if(state.isGame()){ if(!net.client()){ - state.enemies = Groups.unit.count(u -> u.team() == state.rules.waveTeam && u.isCounted()); + state.enemies = Groups.unit.count(u -> u.team() == state.rules.waveTeam && u.isEnemy()); } if(!state.isPaused()){ diff --git a/core/src/mindustry/entities/abilities/MoveLightningAbility.java b/core/src/mindustry/entities/abilities/MoveLightningAbility.java index 5b74b73570..ab70313df4 100644 --- a/core/src/mindustry/entities/abilities/MoveLightningAbility.java +++ b/core/src/mindustry/entities/abilities/MoveLightningAbility.java @@ -23,9 +23,9 @@ public class MoveLightningAbility extends Ability{ /** Lightning color */ public Color color = Color.valueOf("a9d8ff"); /** Shifts where the lightning spawns along the Y axis */ - public float offset = 0f; + public float y = 0f; /** Offset along the X axis */ - public float width = 0f; + public float x = 0f; /** Whether the spawn side alternates */ public boolean alternate = true; /** Jittering heat sprite like the shield on v5 Javelin */ @@ -43,22 +43,22 @@ public class MoveLightningAbility extends Ability{ MoveLightningAbility(){} - public MoveLightningAbility(float damage, int length, float chance, float offset, float minSpeed, float maxSpeed, Color color, String heatRegion){ + public MoveLightningAbility(float damage, int length, float chance, float y, float minSpeed, float maxSpeed, Color color, String heatRegion){ this.damage = damage; this.length = length; this.chance = chance; - this.offset = offset; + this.y = y; this.minSpeed = minSpeed; this.maxSpeed = maxSpeed; this.color = color; this.heatRegion = heatRegion; } - public MoveLightningAbility(float damage, int length, float chance, float offset, float minSpeed, float maxSpeed, Color color){ + public MoveLightningAbility(float damage, int length, float chance, float y, float minSpeed, float maxSpeed, Color color){ this.damage = damage; this.length = length; this.chance = chance; - this.offset = offset; + this.y = y; this.minSpeed = minSpeed; this.maxSpeed = maxSpeed; this.color = color; @@ -68,7 +68,7 @@ public class MoveLightningAbility extends Ability{ public void update(Unit unit){ float scl = Mathf.clamp((unit.vel().len() - minSpeed) / (maxSpeed - minSpeed)); if(Mathf.chance(Time.delta * chance * scl)){ - float x = unit.x + Angles.trnsx(unit.rotation, offset, width * side), y = unit.y + Angles.trnsy(unit.rotation, offset, width * side); + float x = unit.x + Angles.trnsx(unit.rotation, this.y, this.x * side), y = unit.y + Angles.trnsy(unit.rotation, this.y, this.x * side); shootEffect.at(x, y, unit.rotation, color, parentizeEffects ? unit : null); shootSound.at(x, y); diff --git a/core/src/mindustry/entities/comp/LegsComp.java b/core/src/mindustry/entities/comp/LegsComp.java index 99576f666e..5d170264a4 100644 --- a/core/src/mindustry/entities/comp/LegsComp.java +++ b/core/src/mindustry/entities/comp/LegsComp.java @@ -89,6 +89,7 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ resetLegs(type.legLength); } + //TODO clearly broken for many units public void resetLegs(float legLength){ int count = type.legCount; @@ -130,7 +131,7 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ //TODO should move legs even when still, based on speed. also, to prevent "slipping", make sure legs move when they are too far from their destination totalLength += type.legContinuousMove ? type.speed * speedMultiplier : Mathf.dst(deltaX(), deltaY()); - float trns = moveSpace * 0.85f * type.legTrns; + float trns = moveSpace * 0.85f * type.legForwardScl; //rotation + offset vector boolean moving = moving(); @@ -147,8 +148,8 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ Leg l = legs[i]; //TODO is limiting twice necessary? - l.joint.sub(baseOffset).clampLength(type.maxCompress * legLength/2f, type.maxStretch * legLength/2f).add(baseOffset); - l.base.sub(baseOffset).clampLength(type.maxCompress * legLength, type.maxStretch * legLength).add(baseOffset); + l.joint.sub(baseOffset).clampLength(type.legMinLength * legLength/2f, type.legMaxLength * legLength/2f).add(baseOffset); + l.base.sub(baseOffset).clampLength(type.legMinLength * legLength, type.legMaxLength * legLength).add(baseOffset); float stageF = (totalLength + i*type.legPairOffset) / moveSpace; int stage = (int)stageF; @@ -182,8 +183,8 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ } //shake when legs contact ground - if(type.landShake > 0){ - Effect.shake(type.landShake, type.landShake, l.base); + if(type.stepShake > 0){ + Effect.shake(type.stepShake, type.stepShake, l.base); } } @@ -201,8 +202,9 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ Vec2 jointDest = Tmp.v2;//.trns(rot2, legLength / 2f + type.legBaseOffset).add(moveOffset); InverseKinematics.solve(legLength/2f, legLength/2f, Tmp.v6.set(l.base).sub(baseOffset), side, jointDest); jointDest.add(baseOffset); - //lerp between kinematic and linear - jointDest.lerp(Tmp.v6.set(baseOffset).lerp(l.base, 0.5f), 1f - type.kinematicScl); + Tmp.v6.set(baseOffset).lerp(l.base, 0.5f); + //lerp between kinematic and linear? + //jointDest.lerp(Tmp.v6.set(baseOffset).lerp(l.base, 0.5f), 1f - type.kinematicScl); if(move){ float moveFract = stageF % 1f; @@ -214,8 +216,8 @@ abstract class LegsComp implements Posc, Rotc, Hitboxc, Flyingc, Unitc{ l.joint.lerpDelta(jointDest, moveSpeed / 4f); //limit again after updating - l.joint.sub(baseOffset).clampLength(type.maxCompress * legLength/2f, type.maxStretch * legLength/2f).add(baseOffset); - l.base.sub(baseOffset).clampLength(type.maxCompress * legLength, type.maxStretch * legLength).add(baseOffset); + l.joint.sub(baseOffset).clampLength(type.legMinLength * legLength/2f, type.legMaxLength * legLength/2f).add(baseOffset); + l.base.sub(baseOffset).clampLength(type.legMinLength * legLength, type.legMaxLength * legLength).add(baseOffset); } //when at least 1 leg is touching land, it can't drown diff --git a/core/src/mindustry/entities/comp/MechComp.java b/core/src/mindustry/entities/comp/MechComp.java index 41f217dd63..9d599b9bdd 100644 --- a/core/src/mindustry/entities/comp/MechComp.java +++ b/core/src/mindustry/entities/comp/MechComp.java @@ -44,8 +44,8 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati float cx = x + Angles.trnsx(baseRotation, length, width), cy = y + Angles.trnsy(baseRotation, length, width); - if(type.mechStepShake > 0){ - Effect.shake(type.mechStepShake, type.mechStepShake, cx, cy); + if(type.stepShake > 0){ + Effect.shake(type.stepShake, type.stepShake, cx, cy); } if(type.mechStepParticles){ diff --git a/core/src/mindustry/entities/comp/MinerComp.java b/core/src/mindustry/entities/comp/MinerComp.java index fbb1ae1c20..0e1caeb728 100644 --- a/core/src/mindustry/entities/comp/MinerComp.java +++ b/core/src/mindustry/entities/comp/MinerComp.java @@ -53,7 +53,7 @@ abstract class MinerComp implements Itemsc, Posc, Teamc, Rotc, Drawc{ public boolean validMine(Tile tile, boolean checkDst){ if(tile == null) return false; - if(checkDst && !within(tile.worldx(), tile.worldy(), type.miningRange)){ + if(checkDst && !within(tile.worldx(), tile.worldy(), type.mineRange)){ return false; } diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index 1e6823cf84..c91318f468 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -178,7 +178,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I return state.rules.infiniteResources ? Float.MAX_VALUE : Math.max(type.clipSize, type.region.width) + type.buildRange + tilesize*4f; } if(mining()){ - return type.clipSize + type.miningRange; + return type.clipSize + type.mineRange; } return type.clipSize; } @@ -253,8 +253,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I return !disarmed && !(type.canBoost && isFlying()); } - public boolean isCounted(){ - return type.isCounted; + public boolean isEnemy(){ + return type.isEnemy; } @Override @@ -396,8 +396,8 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I @Override public void landed(){ - if(type.landShake > 0f){ - Effect.shake(type.landShake, type.landShake, this); + if(type.mechLandShake > 0f){ + Effect.shake(type.mechLandShake, type.mechLandShake, this); } type.landed(self()); @@ -478,7 +478,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I if(Mathf.chanceDelta(0.2)){ float offset = type.engineOffset/2f + type.engineOffset/2f * elevation; float range = Mathf.range(type.engineSize); - type.fallThrusterEffect.at( + type.fallEngineEffect.at( x + Angles.trnsx(rotation + 180, offset) + Mathf.range(range), y + Angles.trnsy(rotation + 180, offset) + Mathf.range(range), Mathf.random() diff --git a/core/src/mindustry/entities/comp/WaterMoveComp.java b/core/src/mindustry/entities/comp/WaterMoveComp.java index b1e223df62..0bc68d02b1 100644 --- a/core/src/mindustry/entities/comp/WaterMoveComp.java +++ b/core/src/mindustry/entities/comp/WaterMoveComp.java @@ -33,7 +33,7 @@ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{ t.length = type.trailLength; int sign = i == 0 ? -1 : 1; - float cx = Angles.trnsx(rotation - 90, type.trailX * sign, type.trailY) + x, cy = Angles.trnsy(rotation - 90, type.trailX * sign, type.trailY) + y; + float cx = Angles.trnsx(rotation - 90, type.waveTrailX * sign, type.waveTrailY) + x, cy = Angles.trnsy(rotation - 90, type.waveTrailX * sign, type.waveTrailY) + y; t.update(cx, cy, world.floorWorld(cx, cy).isLiquid && !flying ? 1 : 0); } } @@ -67,8 +67,8 @@ abstract class WaterMoveComp implements Posc, Velc, Hitboxc, Flyingc, Unitc{ Color color = Tmp.c1.set(floor.mapColor.equals(Color.black) ? Blocks.water.mapColor : floor.mapColor).mul(1.5f); trailColor.lerp(color, Mathf.clamp(Time.delta * 0.04f)); - tleft.draw(trailColor, type.trailScl); - tright.draw(trailColor, type.trailScl); + tleft.draw(trailColor, type.tailScl); + tright.draw(trailColor, type.tailScl); Draw.z(z); } diff --git a/core/src/mindustry/entities/units/AIController.java b/core/src/mindustry/entities/units/AIController.java index 68b1ac82fe..6966f9c17e 100644 --- a/core/src/mindustry/entities/units/AIController.java +++ b/core/src/mindustry/entities/units/AIController.java @@ -92,7 +92,7 @@ public class AIController implements UnitController{ /** For ground units: Looks at the target, or the movement position. Does not apply to non-omni units. */ public void faceTarget(){ if(unit.type.omniMovement || unit instanceof Mechc){ - if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting && unit.type.hasWeapons()){ + if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.faceTarget && unit.type.hasWeapons()){ unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed)); }else if(unit.moving()){ unit.lookAt(unit.vel().angle()); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index cb7dd4bc96..120f04f504 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -826,7 +826,7 @@ public class DesktopInput extends InputHandler{ } float mouseAngle = Angles.mouseAngle(unit.x, unit.y); - boolean aimCursor = omni && player.shooting && unit.type.hasWeapons() && unit.type.faceTarget && !boosted && unit.type.rotateShooting; + boolean aimCursor = omni && player.shooting && unit.type.hasWeapons() && unit.type.faceTarget && !boosted; if(aimCursor){ unit.lookAt(mouseAngle); @@ -836,7 +836,7 @@ public class DesktopInput extends InputHandler{ unit.movePref(movement); - unit.aim(unit.type.faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y)); + unit.aim(Core.input.mouseWorld()); unit.controlWeapons(true, player.shooting && !boosted); player.boosting = Core.input.keyDown(Binding.boost); diff --git a/core/src/mindustry/input/MobileInput.java b/core/src/mindustry/input/MobileInput.java index a69794d890..588fc3db68 100644 --- a/core/src/mindustry/input/MobileInput.java +++ b/core/src/mindustry/input/MobileInput.java @@ -886,7 +886,7 @@ public class MobileInput extends InputHandler implements GestureListener{ float range = unit.hasWeapons() ? unit.range() : 0f; float bulletSpeed = unit.hasWeapons() ? type.weapons.first().bullet.speed : 0f; float mouseAngle = unit.angleTo(unit.aimX(), unit.aimY()); - boolean aimCursor = omni && player.shooting && type.hasWeapons() && type.faceTarget && !boosted && type.rotateShooting; + boolean aimCursor = omni && player.shooting && type.hasWeapons() && !boosted && type.faceTarget; if(aimCursor){ unit.lookAt(mouseAngle); diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 49be96dae7..b89af108dd 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -40,16 +40,9 @@ import mindustry.world.meta.*; import static arc.graphics.g2d.Draw.*; import static mindustry.Vars.*; -//TODO document public class UnitType extends UnlockableContent{ public static final float shadowTX = -12, shadowTY = -13; private static final Vec2 legOffset = new Vec2(); - private static TextureRegion itemCircleRegion; - - /** If true, the unit is always at elevation 1. */ - public boolean flying; - /** Creates a new instance of this unit class. */ - public Prov constructor; /** Environmental flags that are *all* required for this unit to function. 0 = any environment */ public int envRequired = 0; @@ -58,161 +51,340 @@ public class UnitType extends UnlockableContent{ /** The environment flags that this unit *cannot* function in. If the env matches any of these, it will explode or be disabled. */ public int envDisabled = Env.scorching; - public float speed = 1.1f, boostMultiplier = 1f, rotateSpeed = 5f, baseRotateSpeed = 5f; - public float drag = 0.3f, accel = 0.5f, landShake = 0f, rippleScale = 1f, riseSpeed = 0.08f, fallSpeed = 0.018f; - public float health = 200f, range = -1, miningRange = 70f, armor = 0f, maxRange = -1f, buildRange = Vars.buildingRange; - public float crashDamageMultiplier = 1f; - public boolean targetAir = true, targetGround = true; - public boolean faceTarget = true, rotateShooting = true, isCounted = true, lowAltitude = false, circleTarget = false; - public boolean canBoost = false; - public boolean logicControllable = true; - public boolean playerControllable = true; - public boolean allowedInPayloads = true; - /** If false, this unit does not take damage and cannot be kill() / destroy()-ed. */ - public boolean killable = true; - /** If true, this core unit will "dock" to other units, making it re-appear when "undocking". */ - public boolean coreUnitDock = false; - public boolean createWreck = true; - public boolean createScorch = true; - public boolean useUnitCap = true; - public boolean destructibleWreck = true; - /** If true, this modded unit always has a -outline region generated for its base. Normally, outlines are ignored if there are no top = false weapons. */ - public boolean alwaysCreateOutline = false; - /** If true, this unit has a square shadow. */ - public boolean squareShape = false; - public float groundLayer = Layer.groundUnit; - public float payloadCapacity = 8; - public float aimDst = -1f; - public float buildBeamOffset = 3.8f; + /** movement speed (world units/t) */ + public float speed = 1.1f, + /** multiplier for speed when boosting */ + boostMultiplier = 1f, + /** body rotation speed in degrees/t */ + rotateSpeed = 5f, + /** mech base rotation speed in degrees/t*/ + baseRotateSpeed = 5f, + /** movement drag as fraction */ + drag = 0.3f, + /** acceleration as fraction of speed */ + accel = 0.5f, + /** size of one side of the hitbox square */ + hitSize = 6f, + /** shake on each step for leg/mech units */ + stepShake = -1f, + /** ripple / dust size for legged units */ + rippleScale = 1f, + /** boosting rise speed as fraction */ + riseSpeed = 0.08f, + /** how fast this unit falls when not boosting */ + fallSpeed = 0.018f, + /** raw health amount */ + health = 200f, + /** incoming damage is reduced by this amount */ + armor = 0f, + /** minimum range of any weapon; used for approaching targets. can be overridden by setting a value > 0. */ + range = -1, + /** maximum range of any weapon */ + maxRange = -1f, + /** range at which this unit can mine ores */ + mineRange = 70f, + /** range at which this unit can build */ + buildRange = Vars.buildingRange, + /** multiplier for damage this (flying) unit deals when crashing on enemy things */ + crashDamageMultiplier = 1f, + /** a VERY ROUGH estimate of unit DPS; initialized in init() */ + dpsEstimate = -1, + /** graphics clipping size; <0 to calculate automatically */ + clipSize = -1, + /** multiplier for how slowly this unit drowns - higher numbers, slower drowning. */ + drownTimeMultiplier = 1f, + /** fractional movement speed penalty for this unit when it is moving in the opposite direction that it is facing */ + strafePenalty = 0.5f, + /** multiplier for cost of research in tech tree */ + researchCostMultiplier = 50, + + /** for ground units, the layer upon which this unit is drawn */ + groundLayer = Layer.groundUnit, + /** Payload capacity of this unit in blocks^2 */ + payloadCapacity = 8, + /** building speed multiplier; <0 to disable. */ + buildSpeed = -1f, + /** Minimum distance from this unit that weapons can target. Prevents units from firing "inside" the unit. */ + aimDst = -1f, + /** Visual offset of build beam from front. */ + buildBeamOffset = 3.8f, /** WIP: Units of low priority will always be ignored in favor of those with higher priority, regardless of distance. */ - public float targetPriority = 0f; - /** If false, this unit is not targeted by anything. */ - public boolean targetable = true; - /** If true, this unit can be hit with bullets/splash damage. */ - public boolean hittable = true; - public boolean drawBuildBeam = true; - public boolean rotateToBuilding = true; - public float commandRadius = 150f; - public float visualElevation = -1f; - /** If true and this is a legged unit, this unit can walk over blocks. */ - public boolean allowLegStep = false; - /** If true, this unit cannot drown, and will not be affected by the floor under it. */ - public boolean hovering = false; - public boolean omniMovement = true; - /** If true, the unit faces its moving direction before actually moving. */ - public boolean rotateMoveFirst = false; - public boolean showHeal = true; - public Color healColor = Pal.heal; - public Effect fallEffect = Fx.fallSmoke; - public Effect fallThrusterEffect = Fx.fallSmoke; - public Effect deathExplosionEffect = Fx.dynamicExplosion; - public @Nullable Effect treadEffect; - /** Extra (usually animated) parts */ - public Seq parts = new Seq<>(DrawPart.class); - public Seq abilities = new Seq<>(); - /** Flags to target based on priority. Null indicates that the closest target should be found. The closest enemy core is used as a fallback. */ - public BlockFlag[] targetFlags = {null}; - /** Target items to mine. Used in MinerAI */ - public Seq mineItems = Seq.with(Items.copper, Items.lead, Items.titanium, Items.thorium); + targetPriority = 0f, + /** Elevation of shadow drawn under this (ground) unit. Visual only. */ + shadowElevation = -1f, + /** backwards engine offset from center of unit */ + engineOffset = 5f, + /** main engine radius */ + engineSize = 2.5f, + /** layer of all engines (<0 for default) */ + engineLayer = -1f, + /** visual backwards offset of items on unit */ + itemOffsetY = 3f, + /** radius of light emitted, <0 for default */ + lightRadius = -1f, + /** light color opacity*/ + lightOpacity = 0.6f, + /** fog view radius in tiles. <0 for automatic radius. */ + fogRadius = -1f, + + /** horizontal offset of wave trail in naval units */ + waveTrailX = 4f, + /** vertical offset of wave trail in naval units */ + waveTrailY = -3f, + /** width of all trails (including naval ones) */ + tailScl = 1f; + + /** if true, this unit counts as an enemy in the wave counter (usually false for support-only units) */ + public boolean isEnemy = true, + /** If true, the unit is always at elevation 1. */ + flying = false, + /** whether this unit tries to attack air units */ + targetAir = true, + /** whether this unit tries to attack ground units */ + targetGround = true, + /** if true, this unit will attempt to face its target when shooting/aiming at it */ + faceTarget = true, + /** AI flag: if true, this flying unit circles around its target like a bomber */ + circleTarget = false, + /** if true, this unit can boost into the air if a player/processors controls it*/ + canBoost = false, + /** if false, logic processors cannot control this unit */ + logicControllable = true, + /** if false, players cannot control this unit */ + playerControllable = true, + /** if false, this unit cannot be moved into payloads */ + allowedInPayloads = true, + /** if false, this unit cannot be hit by bullets or explosions*/ + hittable = true, + /** if false, this unit does not take damage and cannot be kill() / destroy()-ed. */ + killable = true, + /** if false, this unit is not targeted by anything. */ + targetable = true, + /** if false, this unit does not physically collide with others. */ + physics = true, + /** if true, this ground unit will drown in deep liquids. */ + canDrown = true, + /** if false, this unit ignores the unit cap and can be spawned infinitely */ + useUnitCap = true, + /** if true, this core unit will "dock" to other units, making it re-appear when "undocking". */ + coreUnitDock = false, + /** if false, no falling "corpse" is created when this unit dies. */ + createWreck = true, + /** if false, no scorch marks are created when this unit dies */ + createScorch = true, + /** if true, this unit will be drawn under effects/bullets; this is a visual change only. */ + lowAltitude = false, + /** if true, this unit will look at whatever it is building */ + rotateToBuilding = true, + /** if true and this is a legged unit, this unit can walk over blocks. */ + allowLegStep = false, + /** if true, this unit cannot drown, and will not be affected by the floor under it. */ + hovering = false, + /** if true, this unit can move in any direction regardless of rotation. if false, this unit can only move in the direction it is facing. */ + omniMovement = true, + /** if true, the unit faces its moving direction before actually moving. */ + 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. */ + singleTarget = false, + /** if true, this unit will be able to have multiple targets, even if it only has one mirrored weapon. */ + forceMultiTarget = false, + /** if false, this unit has no weapons that can attack. */ + canAttack = true, + /** if true, this unit won't show up in the database or various other UIs. */ + hidden = false, + /** if true, this unit is for internal use only and does not have a sprite generated. */ + internal = false, + /** if true, this unit is detected as naval - do NOT assign this manually! Initialized in init() */ + naval = false, + + /** if true, this modded unit always has a -outline region generated for its base. Normally, outlines are ignored if there are no top = false weapons. */ + alwaysCreateOutline = false, + /** if true, this unit has a square shadow. */ + squareShape = false, + /** if true, this unit will draw its building beam towards blocks. */ + drawBuildBeam = true, + /** if false, the team indicator/cell is not drawn. */ + drawCell = true, + /** if false, carried items are not drawn. */ + drawItems = true, + /** if false, the unit shield (usually seen in waves) is not drawn. */ + drawShields = true, + /** if false, the unit body is not drawn. */ + drawBody = true; - //TODO different names for these fields. /** The default AI controller to assign on creation. */ public Prov aiController = () -> !flying ? new GroundAI() : new FlyingAI(); /** Function that chooses AI controller based on unit entity. */ public Func controller = u -> !playerControllable || (u.team.isAI() && !u.team.rules().rtsAi) ? aiController.get() : new CommandAI(); + /** Creates a new instance of this unit class. */ + public Prov constructor; - public Color outlineColor = Pal.darkerMetal; - public int outlineRadius = 3; - public boolean outlines = true; + /** list of "abilities", which are various behaviors that update each frame */ + public Seq abilities = new Seq<>(); + /** All weapons that this unit will shoot with. */ + public Seq weapons = new Seq<>(); + /** None of the status effects in this set can be applied to this unit. */ + public ObjectSet immunities = new ObjectSet<>(); - public int legCount = 4, legGroupSize = 2; - public float legLength = 10f, legSpeed = 0.1f, legTrns = 1f, legBaseOffset = 0f, legMoveSpace = 1f, legExtension = 0, legPairOffset = 0, legLengthScl = 1f, kinematicScl = 1f, maxStretch = 1.75f, maxCompress = 0f; - public float legSplashDamage = 0f, legSplashRange = 5; - public float legStraightLength = 1f; - /** If true, legs are locked to the base of the unit instead of being on an implicit rotating "mount". */ - public boolean lockLegBase = false, legContinuousMove; - public float baseLegStraightness, legStraightness; - /** TODO neither of these appear to do much */ - public boolean flipBackLegs = true, flipLegSide = false; - - public float mechSideSway = 0.54f, mechFrontSway = 0.1f; - public float mechStride = -1f; - public float mechStepShake = -1f; - public boolean mechStepParticles = false; - public Color mechLegColor = Pal.darkMetal; - - public Rect[] treadRects = {}; - public int treadFrames = 18; - public int treadPullOffset = 0; - - public int itemCapacity = -1; - public int ammoCapacity = -1; - public AmmoType ammoType = new ItemAmmoType(Items.copper); - public int mineTier = -1; - public boolean mineWalls = false, mineFloor = true; - public boolean mineHardnessScaling = true; - public float buildSpeed = -1f, mineSpeed = 1f; - public Sound mineSound = Sounds.minebeam; - public float mineSoundVolume = 0.6f; - - //missiles only! - public float lifetime = 60f * 5f; - public float homingDelay = 10f; - - /** This is a VERY ROUGH estimate of unit DPS. */ - public float dpsEstimate = -1; - public float clipSize = -1; - public boolean canDrown = true, naval = false; - public float drownTimeMultiplier = 1f; - public float engineOffset = 5f, engineSize = 2.5f; - public boolean useEngineElevation = true; - public @Nullable Color engineColor = null; - public @Nullable Color trailColor; - public Color engineColorInner = Color.white; - public float engineLayer = -1f; - public Seq engines = new Seq<>(); - public float strafePenalty = 0.5f; - /** If false, this unit does not physically collide with others. */ - public boolean physics = true; - public float hitSize = 6f; - public float itemOffsetY = 3f; - public float lightRadius = -1f, lightOpacity = 0.6f; - /** Fog view radius in tiles. <0 for automatic radius. */ - public float fogRadius = -1f; + /** color that this unit flashes when getting healed (if healFlash is true) */ + public Color healColor = Pal.heal; + /** Color of light that this unit produces when lighting is enabled in the map. */ public Color lightColor = Pal.powerLight; - public boolean drawCell = true, drawItems = true, drawShields = true, drawBody = true; + /** sound played when this unit explodes (*not* when it is shot down) */ + public Sound deathSound = Sounds.bang; + /** effect that this unit emits when falling */ + public Effect fallEffect = Fx.fallSmoke; + /** effect created at engine when unit falls. */ + public Effect fallEngineEffect = Fx.fallSmoke; + /** effect created when this unit dies */ + public Effect deathExplosionEffect = Fx.dynamicExplosion; + /** optional effect created when this tank moves */ + public @Nullable Effect treadEffect; + /** extra (usually animated) visual parts */ + public Seq parts = new Seq<>(DrawPart.class); + /** list of engines, or "thrusters" */ + public Seq engines = new Seq<>(); + /** if false, the thruster is always displayed at its normal size regardless of elevation */ + public boolean useEngineElevation = true; + /** override for all engine colors */ + public @Nullable Color engineColor = null; + /** color for inner portions of engines */ + public Color engineColorInner = Color.white; + /** length of engine trail (if flying) or wave trail (if naval) */ public int trailLength = 0; - public float researchCostMultiplier = 50; - public float trailX = 4f, trailY = -3f, trailScl = 1f; - /** Whether the unit can heal blocks. Initialized in init() */ - public boolean canHeal = false; - /** If true, all weapons will attack the same target. */ - public boolean singleTarget = false; - public boolean forceMultiTarget = false; - /** If false, this unit has no weapons that can attack. */ - public boolean canAttack = true; - public boolean hidden = false; - public boolean internal = false; + /** override for engine trail color */ + public @Nullable Color trailColor; + /** Function used for calculating cost of moving with ControlPathfinder. Does not affect "normal" flow field pathfinding. */ public @Nullable PathCost pathCost; /** A sample of the unit that this type creates. Do not modify! */ public @Nullable Unit sample; + /** Flags to target based on priority. Null indicates that the closest target should be found. The closest enemy core is used as a fallback. */ + public BlockFlag[] targetFlags = {null}; + + /** color for outline generated around sprites */ + public Color outlineColor = Pal.darkerMetal; + /** thickness for sprite outline */ + public int outlineRadius = 3; + /** if false, no sprite outlines are generated */ + public boolean outlines = true; + + /** amount of items this unit can carry; <0 to determine based on hitSize. */ + public int itemCapacity = -1; + /** amount of ammo this unit can hold (if the rule is enabled); <0 to determine based on weapon fire rate. */ + public int ammoCapacity = -1; + /** ammo this unit uses, if that system is enabled. */ + public AmmoType ammoType = new ItemAmmoType(Items.copper); + + /** max hardness of ore that this unit can mine (<0 to disable) */ + public int mineTier = -1; + /** mining speed in weird arbitrary units */ + public float mineSpeed = 1f; + /** whether this unit can mine ores from floors/walls, respectively */ + public boolean mineWalls = false, mineFloor = true; + /** if true, harder materials will take longer to mine */ + public boolean mineHardnessScaling = true; + /** continuous sound emitted when mining. */ + public Sound mineSound = Sounds.minebeam; + /** volume of mining sound. */ + public float mineSoundVolume = 0.6f; + /** Target items to mine. Used in MinerAI */ + public Seq mineItems = Seq.with(Items.copper, Items.lead, Items.titanium, Items.thorium); + + //LEG UNITS + + /** number of legs this unit has (must have the correct type to function!) */ + public int legCount = 4; + /** size of groups in which legs move. for example, insects (6 legs) usually move legs in groups of 3. */ + public int legGroupSize = 2; + + /** total length of a leg (both segments) */ + 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 */ + legForwardScl = 1f, + /** leg offset from the center of the unit */ + legBaseOffset = 0f, + /** scaling for space between leg movements */ + legMoveSpace = 1f, + /** for legs without "joints", this is how much the second leg sprite is moved "back" by, so it covers the joint region (it's hard to explain without an image) */ + legExtension = 0, + /** ??? I don't really know what this does or why it's here */ + legPairOffset = 0, + /** scaling for how far away legs *try* to be from the body (not their actual length); e.g. if set to 0.5, legs will appear somewhat folded */ + legLengthScl = 1f, + /** if legStraightness > 0, this is the scale for how far away legs are from the body horizontally */ + legStraightLength = 1f, + /** maximum length of an individual leg as fraction of real length */ + legMaxLength = 1.75f, + /** minimum length of an individual leg as fraction of real length */ + legMinLength = 0f, + /** splash damage dealt when a leg touches the ground */ + legSplashDamage = 0f, + /** splash damage radius of legs */ + legSplashRange = 5, + /** how straight the leg base/origin is (0 = circular, 1 = line) */ + baseLegStraightness = 0f, + /** how straight the leg outward angles are (0 = circular, 1 = horizontal line) */ + legStraightness = 0f; + + /** If true, legs are locked to the base of the unit instead of being on an implicit rotating "mount". */ + public boolean lockLegBase = false; + /** If true, legs always try to move around even when the unit is not moving (leads to more natural behavior) */ + public boolean legContinuousMove; + /** TODO neither of these appear to do much */ + public boolean flipBackLegs = true, flipLegSide = false; + + //MECH UNITS + + /** screen shake amount for when this mech lands after boosting */ + public float mechLandShake = 0f; + /** parameters for mech swaying animation */ + public float mechSideSway = 0.54f, mechFrontSway = 0.1f, mechStride = -1f; + /** whether particles are created when this mech takes a step */ + public boolean mechStepParticles = false; + /** color that legs change to when moving, to simulate depth */ + public Color mechLegColor = Pal.darkMetal; + + //TANK UNITS + + /** list of treads as rectangles in IMAGE COORDINATES. these should match the coordinates you see in an image editor*/ + public Rect[] treadRects = {}; + /** number of frames of movement in a tread */ + public int treadFrames = 18; + /** how much of a top part of a tread sprite is "cut off" relative to the pattern; this is corrected for */ + public int treadPullOffset = 0; + + //SEGMENTED / CRAWL UNITS + //for crawlers public int segments = 0; - public float segmentSpacing = 2f; - public float segmentScl = 4f, segmentPhase = 5f; - public float segmentRotSpeed = 1f, segmentMaxRot = 30f; + public float segmentSpacing = 2f, segmentScl = 4f, segmentPhase = 5f, segmentRotSpeed = 1f, segmentMaxRot = 30f; + /** speed multiplier this unit will have when crawlSlowdownFrac is met. */ public float crawlSlowdown = 0.5f; - /** Damage dealt to blocks under this tank/crawler every frame. */ + /** damage dealt to blocks under this tank/crawler every frame. */ public float crushDamage = 0f; + /** the fraction of solids under this block necessary for it to reach crawlSlowdown. */ public float crawlSlowdownFrac = 0.55f; - public ObjectSet immunities = new ObjectSet<>(); - public Sound deathSound = Sounds.bang; + //MISSILE UNITS - public Seq weapons = new Seq<>(); - public TextureRegion baseRegion, legRegion, region, previewRegion, shadowRegion, cellRegion, + /** lifetime of this missile. */ + public float lifetime = 60f * 5f; + /** ticks that must pass before this missile starts homing. */ + public float homingDelay = 10f; + + //REGIONS + + //(undocumented, you shouldn't need to use these, and if you do just check how they're drawn and copy that) + public TextureRegion baseRegion, legRegion, region, previewRegion, shadowRegion, cellRegion, itemCircleRegion, softShadowRegion, jointRegion, footRegion, legBaseRegion, baseJointRegion, outlineRegion, treadRegion; public TextureRegion[] wreckRegions, segmentRegions, segmentOutlineRegions; public TextureRegion[][] treadRegions; @@ -430,8 +602,8 @@ public class UnitType extends UnlockableContent{ canDrown = false; omniMovement = false; immunities.add(StatusEffects.wet); - if(visualElevation < 0f){ - visualElevation = 0.11f; + if(shadowElevation < 0f){ + shadowElevation = 0.11f; } } @@ -491,7 +663,7 @@ public class UnitType extends UnlockableContent{ } if(weapons.isEmpty()){ - range = maxRange = miningRange; + range = maxRange = mineRange; } if(mechStride < 0){ @@ -502,8 +674,8 @@ public class UnitType extends UnlockableContent{ aimDst = weapons.contains(w -> !w.rotate) ? hitSize * 2f : hitSize / 2f; } - if(mechStepShake < 0){ - mechStepShake = Mathf.round((hitSize - 11f) / 9f); + if(stepShake < 0){ + stepShake = Mathf.round((hitSize - 11f) / 9f); mechStepParticles = hitSize > 15f; } @@ -596,6 +768,8 @@ public class UnitType extends UnlockableContent{ baseJointRegion = Core.atlas.find(name + "-joint-base"); footRegion = Core.atlas.find(name + "-foot"); treadRegion = Core.atlas.find(name + "-treads"); + itemCircleRegion = Core.atlas.find("ring-item"); + if(treadRegion.found()){ treadRegions = new TextureRegion[treadRects.length][treadFrames]; for(int r = 0; r < treadRects.length; r++){ @@ -831,7 +1005,7 @@ public class UnitType extends UnlockableContent{ drawControl(unit); } - if(!isPayload && (unit.isFlying() || visualElevation > 0)){ + if(!isPayload && (unit.isFlying() || shadowElevation > 0)){ Draw.z(Math.min(Layer.darkness, z - 1f)); drawShadow(unit); } @@ -951,7 +1125,7 @@ public class UnitType extends UnlockableContent{ } public void drawShadow(Unit unit){ - float e = Math.max(unit.elevation, visualElevation) * (1f - unit.drownTime); + float e = Math.max(unit.elevation, shadowElevation) * (1f - unit.drownTime); float x = unit.x + shadowTX * e, y = unit.y + shadowTY * e; Floor floor = world.floorWorld(x, y); @@ -994,10 +1168,6 @@ public class UnitType extends UnlockableContent{ size, size, unit.rotation); Draw.mixcol(); - if(itemCircleRegion == null || itemCircleRegion.texture.isDisposed()){ - itemCircleRegion = Core.atlas.find("ring-item"); - } - size = (3f + Mathf.absin(Time.time, 5f, 1f)) * unit.itemTime + 0.5f; Draw.color(Pal.accent); Draw.rect(itemCircleRegion, @@ -1021,7 +1191,7 @@ public class UnitType extends UnlockableContent{ unit.trail = new Trail(trailLength); } Trail trail = unit.trail; - trail.draw(trailColor == null ? unit.team.color : trailColor, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * (useEngineElevation ? unit.elevation : 1f)) * trailScl); + trail.draw(trailColor == null ? unit.team.color : trailColor, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * (useEngineElevation ? unit.elevation : 1f)) * tailScl); } public void drawEngines(Unit unit){ @@ -1166,8 +1336,8 @@ public class UnitType extends UnlockableContent{ Tmp.v1.set(leg.base).sub(leg.joint).inv().setLength(legExtension); - if(footRegion.found() && leg.moving && visualElevation > 0){ - float scl = visualElevation * invDrown; + if(footRegion.found() && leg.moving && shadowElevation > 0){ + float scl = shadowElevation * invDrown; float elev = Mathf.slope(1f - leg.stage) * scl; Draw.color(Pal.shadow); Draw.rect(footRegion, leg.base.x + shadowTX * elev, leg.base.y + shadowTY * elev, position.angleTo(leg.base)); @@ -1285,7 +1455,7 @@ public class UnitType extends UnlockableContent{ public void applyColor(Unit unit){ Draw.color(); - if(showHeal){ + if(healFlash){ Tmp.c1.set(Color.white).lerp(healColor, Mathf.clamp(unit.healTime - unit.hitTime)); } Draw.mixcol(Tmp.c1, Math.max(unit.hitTime, Mathf.clamp(unit.healTime))); diff --git a/core/src/mindustry/type/unit/MissileUnitType.java b/core/src/mindustry/type/unit/MissileUnitType.java index 2a490b7bdc..4e44eb92d9 100644 --- a/core/src/mindustry/type/unit/MissileUnitType.java +++ b/core/src/mindustry/type/unit/MissileUnitType.java @@ -16,7 +16,7 @@ public class MissileUnitType extends UnitType{ createWreck = false; createScorch = false; logicControllable = false; - isCounted = false; + isEnemy = false; useUnitCap = false; allowedInPayloads = false; aiController = MissileAI::new; diff --git a/core/src/mindustry/type/unit/NeoplasmUnitType.java b/core/src/mindustry/type/unit/NeoplasmUnitType.java index fe331ce3b3..445a8056b6 100644 --- a/core/src/mindustry/type/unit/NeoplasmUnitType.java +++ b/core/src/mindustry/type/unit/NeoplasmUnitType.java @@ -29,7 +29,7 @@ public class NeoplasmUnitType extends UnitType{ }}); //green flashing is unnecessary since they always regen - showHeal = false; + healFlash = false; //TODO //- liquid regen ability