From 1d249f233fe38e5d83803e7ec41bf249217f5b4f Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 1 May 2022 23:50:49 -0400 Subject: [PATCH] UnitType docs --- .../sprites/units/obviate-preview.png | Bin 2872 -> 2880 bytes core/src/mindustry/ai/types/MinerAI.java | 6 +- core/src/mindustry/content/UnitTypes.java | 180 +++---- core/src/mindustry/core/Logic.java | 2 +- .../abilities/MoveLightningAbility.java | 14 +- .../src/mindustry/entities/comp/LegsComp.java | 20 +- .../src/mindustry/entities/comp/MechComp.java | 4 +- .../mindustry/entities/comp/MinerComp.java | 2 +- .../src/mindustry/entities/comp/UnitComp.java | 12 +- .../entities/comp/WaterMoveComp.java | 6 +- .../entities/units/AIController.java | 2 +- core/src/mindustry/input/DesktopInput.java | 4 +- core/src/mindustry/input/MobileInput.java | 2 +- core/src/mindustry/type/UnitType.java | 480 ++++++++++++------ .../mindustry/type/unit/MissileUnitType.java | 2 +- .../mindustry/type/unit/NeoplasmUnitType.java | 2 +- 16 files changed, 456 insertions(+), 282 deletions(-) diff --git a/core/assets-raw/sprites/units/obviate-preview.png b/core/assets-raw/sprites/units/obviate-preview.png index aac82cee84761d32242942741833c5df6f1602d0..4a7553fffde20c4348c72bb858c759061a532a68 100644 GIT binary patch delta 2646 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 delta 2622 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 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