diff --git a/annotations/src/main/resources/classids.properties b/annotations/src/main/resources/classids.properties index ed0e1deade..dcecb9b5c5 100644 --- a/annotations/src/main/resources/classids.properties +++ b/annotations/src/main/resources/classids.properties @@ -32,6 +32,7 @@ missile=39 mono=16 nova=17 oct=26 +osc=44 poly=18 pulsar=19 quad=23 diff --git a/annotations/src/main/resources/revisions/osc/0.json b/annotations/src/main/resources/revisions/osc/0.json new file mode 100644 index 0000000000..545bb6c8ae --- /dev/null +++ b/annotations/src/main/resources/revisions/osc/0.json @@ -0,0 +1 @@ +{fields:[{name:abilities,type:"mindustry.entities.abilities.Ability[]"},{name:ammo,type:float},{name:controller,type:mindustry.entities.units.UnitController},{name:elevation,type:float},{name:flag,type:double},{name:health,type:float},{name:isShooting,type:boolean},{name:mineTile,type:mindustry.world.Tile},{name:mounts,type:"mindustry.entities.units.WeaponMount[]"},{name:plans,type:arc.struct.Queue},{name:rotation,type:float},{name:shield,type:float},{name:spawnedByCore,type:boolean},{name:stack,type:mindustry.type.ItemStack},{name:statuses,type:arc.struct.Seq},{name:team,type:mindustry.game.Team},{name:type,type:mindustry.type.UnitType},{name:updateBuilding,type:boolean},{name:vel,type:arc.math.geom.Vec2},{name:x,type:float},{name:y,type:float}]} \ No newline at end of file diff --git a/core/assets-raw/sprites/units/osc.png b/core/assets-raw/sprites/units/osc.png index 0f27bb4678..173a779327 100644 Binary files a/core/assets-raw/sprites/units/osc.png and b/core/assets-raw/sprites/units/osc.png differ diff --git a/core/assets/maps/two.msav b/core/assets/maps/two.msav index 9891414f69..5716684604 100644 Binary files a/core/assets/maps/two.msav and b/core/assets/maps/two.msav differ diff --git a/core/src/mindustry/ai/ControlPathfinder.java b/core/src/mindustry/ai/ControlPathfinder.java index 25d4a55395..24b03bc25b 100644 --- a/core/src/mindustry/ai/ControlPathfinder.java +++ b/core/src/mindustry/ai/ControlPathfinder.java @@ -38,6 +38,15 @@ public class ControlPathfinder{ (PathTile.deep(tile) ? 6000 : 0) + (PathTile.damages(tile) ? 50 : 0), + //same as ground but ignores liquids/deep stuff + costHover = (team, tile) -> + //impassable same-team or neutral block + PathTile.solid(tile) && ((PathTile.team(tile) == team && !PathTile.teamPassable(tile)) || PathTile.team(tile) == 0) ? impassable : + //impassable synthetic enemy block + ((PathTile.team(tile) != team && PathTile.team(tile) != 0) && PathTile.solid(tile) ? wallImpassableCap : 0) + + 1 + + (PathTile.nearSolid(tile) ? 6 : 0), + costLegs = (team, tile) -> PathTile.legSolid(tile) ? impassable : 1 + (PathTile.deep(tile) ? 6000 : 0) + diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index e9dd6d8c18..0e6547c38a 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -44,10 +44,12 @@ public class UnitTypes{ //legs, legacy public static @EntityDef(value = {Unitc.class, Legsc.class}, legacy = true) UnitType spiroct, arkyid, toxopid; + //hover + public static @EntityDef({Unitc.class, ElevationMovec.class}) UnitType osc; + //air public static @EntityDef({Unitc.class}) UnitType flare, eclipse, horizon, zenith, antumbra, - evoke, avert, obviate, - osc; + evoke, avert, obviate; //air, legacy public static @EntityDef(value = {Unitc.class}, legacy = true) UnitType mono; @@ -2831,7 +2833,7 @@ public class UnitTypes{ //region erekir - mech merui = new ErekirUnitType("merui"){{ - speed = 0.7f; + speed = 0.72f; drag = 0.11f; hitSize = 9f; rotateSpeed = 3f; @@ -3381,13 +3383,12 @@ public class UnitTypes{ //region erekir - flying osc = new ErekirUnitType("osc"){{ - //TODO needs hover passability like legs - move into UnitType? hovering = true; visualElevation = 0.1f; - drag = 0.08f; + drag = 0.07f; speed = 2f; - rotateSpeed = 6f; + rotateSpeed = 5f; accel = 0.09f; health = 600f; @@ -3397,6 +3398,21 @@ public class UnitTypes{ engineSize = 2f; itemCapacity = 0; useEngineElevation = false; + trailLength = 5; + trailScl = 1.1f; + + for(float f : new float[]{-3f, 3f}){ + parts.add(new HoverPart(){{ + x = 3.9f; + y = f; + mirror = true; + radius = 6f; + phase = 90f; + stroke = 2f; + layerOffset = -0.001f; + color = Color.valueOf("bf92f9"); + }}); + } }}; avert = new ErekirUnitType("avert"){{ diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index edb7e5a001..1e6823cf84 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -444,7 +444,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I if(trail != null){ trail.length = type.trailLength; - float scale = elevation; + float scale = type.useEngineElevation ? elevation : 1f; float offset = type.engineOffset/2f + type.engineOffset/2f*scale; float cx = x + Angles.trnsx(rotation + 180, offset), cy = y + Angles.trnsy(rotation + 180, offset); diff --git a/core/src/mindustry/entities/part/HoverPart.java b/core/src/mindustry/entities/part/HoverPart.java new file mode 100644 index 0000000000..3d69e4874a --- /dev/null +++ b/core/src/mindustry/entities/part/HoverPart.java @@ -0,0 +1,56 @@ +package mindustry.entities.part; + +import arc.graphics.*; +import arc.graphics.g2d.*; +import arc.util.*; + +public class HoverPart extends DrawPart{ + public float radius = 4f; + public float x, y, rotation, phase = 50f, stroke = 3f, minStroke = 0.12f; + public int circles = 2; + public Color color = Color.white; + public boolean mirror = false; + public float layer = -1f, layerOffset = 0f; + + @Override + public void draw(PartParams params){ + float z = Draw.z(); + if(layer > 0) Draw.z(layer); + if(under && turretShading) Draw.z(z - 0.0001f); + + Draw.z(Draw.z() + layerOffset); + + int len = mirror && params.sideOverride == -1 ? 2 : 1; + + Draw.color(color); + + + for(int c = 0; c < circles; c++){ + float fin = ((Time.time / phase + (float)c / circles) % 1f); + Lines.stroke((1f-fin) * stroke + minStroke); + + for(int s = 0; s < len; s++){ + //use specific side if necessary + int i = params.sideOverride == -1 ? s : params.sideOverride; + + float sign = (i == 0 ? 1 : -1) * params.sideMultiplier; + Tmp.v1.set((x) * sign, y).rotate(params.rotation - 90); + + float + rx = params.x + Tmp.v1.x, + ry = params.y + Tmp.v1.y; + + Lines.square(rx, ry, radius * fin, params.rotation - 45f); + } + } + + Draw.reset(); + + Draw.z(z); + } + + @Override + public void load(String name){ + + } +} diff --git a/core/src/mindustry/type/UnitType.java b/core/src/mindustry/type/UnitType.java index 2e3aed7657..fe5cc51fbd 100644 --- a/core/src/mindustry/type/UnitType.java +++ b/core/src/mindustry/type/UnitType.java @@ -446,6 +446,7 @@ public class UnitType extends UnlockableContent{ pathCost = example instanceof WaterMovec ? ControlPathfinder.costNaval : allowLegStep ? ControlPathfinder.costLegs : + hovering ? ControlPathfinder.costHover : ControlPathfinder.costGround; } @@ -873,7 +874,7 @@ public class UnitType extends UnlockableContent{ if(drawBody) drawOutline(unit); drawWeaponOutlines(unit); if(engineLayer > 0) Draw.z(engineLayer); - if(trailLength > 0 && !naval && unit.isFlying()){ + if(trailLength > 0 && !naval && (unit.isFlying() || !useEngineElevation)){ drawTrail(unit); } if(engines.size > 0) drawEngines(unit); @@ -1019,7 +1020,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) * unit.elevation) * trailScl); + trail.draw(trailColor == null ? unit.team.color : trailColor, (engineSize + Mathf.absin(Time.time, 2f, engineSize / 4f) * (useEngineElevation ? unit.elevation : 1f)) * trailScl); } public void drawEngines(Unit unit){ @@ -1040,7 +1041,7 @@ public class UnitType extends UnlockableContent{ unit.y + ey, (engine.radius + Mathf.absin(Time.time, 2f, engine.radius / 4f)) * scale ); - Draw.color(Color.white); + Draw.color(engineColorInner); Fill.circle( unit.x + ex - Angles.trnsx(rot + engine.rotation, 1f), unit.y + ey - Angles.trnsy(rot + engine.rotation, 1f), diff --git a/core/src/mindustry/world/blocks/payloads/UnitPayload.java b/core/src/mindustry/world/blocks/payloads/UnitPayload.java index a631e8131f..855ceedb29 100644 --- a/core/src/mindustry/world/blocks/payloads/UnitPayload.java +++ b/core/src/mindustry/world/blocks/payloads/UnitPayload.java @@ -142,7 +142,7 @@ public class UnitPayload implements Payload{ if(unit.type == null) return; //TODO this would be more accurate but has all sorts of associated problems (?) - if(true){ + if(false){ float e = unit.elevation; unit.elevation = 0f; //avoids drawing mining or building diff --git a/core/src/mindustry/world/blocks/units/UnitAssembler.java b/core/src/mindustry/world/blocks/units/UnitAssembler.java index a20c3bc3c6..41a10ff51b 100644 --- a/core/src/mindustry/world/blocks/units/UnitAssembler.java +++ b/core/src/mindustry/world/blocks/units/UnitAssembler.java @@ -327,11 +327,12 @@ public class UnitAssembler extends PayloadBlock{ units.clear(); } - powerWarmup = Mathf.lerpDelta(powerWarmup, efficiency > 0.0001f ? 1f : 0f, 0.1f); - droneWarmup = Mathf.lerpDelta(droneWarmup, units.size < dronesCreated ? efficiency : 0f, 0.1f); + float powerStatus = power == null ? 1f : power.status; + powerWarmup = Mathf.lerpDelta(powerStatus, powerStatus > 0.0001f ? 1f : 0f, 0.1f); + droneWarmup = Mathf.lerpDelta(droneWarmup, units.size < dronesCreated ? powerStatus : 0f, 0.1f); totalDroneProgress += droneWarmup * delta(); - if(units.size < dronesCreated && (droneProgress += edelta() / droneConstructTime) >= 1f){ + if(units.size < dronesCreated && (droneProgress += delta() * powerStatus / droneConstructTime) >= 1f){ if(!net.client()){ var unit = droneType.create(team); if(unit instanceof BuildingTetherc bt){