From c5ed0afb4e5d0bb9ce733cd34630444d18290ca8 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 5 Jun 2018 00:02:07 -0400 Subject: [PATCH] Added (mobile) pickup/dropping of units --- core/src/io/anuke/mindustry/Vars.java | 2 +- .../src/io/anuke/mindustry/content/fx/Fx.java | 9 +++- .../io/anuke/mindustry/content/fx/UnitFx.java | 19 ++++++++- .../src/io/anuke/mindustry/core/Renderer.java | 1 - .../io/anuke/mindustry/entities/Player.java | 42 ++++++++++--------- .../src/io/anuke/mindustry/entities/Unit.java | 8 +++- .../anuke/mindustry/entities/effect/Fire.java | 10 +---- .../entities/effect/GroundEffectEntity.java | 6 +++ .../mindustry/entities/effect/Shield.java | 3 +- .../mindustry/entities/traits/CarryTrait.java | 30 +++++++++++++ .../mindustry/entities/units/BaseUnit.java | 5 --- .../mindustry/entities/units/FlyingUnit.java | 31 +++++++++++++- .../mindustry/entities/units/UnitType.java | 1 + .../anuke/mindustry/input/AndroidInput.java | 25 ++++++++--- 14 files changed, 148 insertions(+), 44 deletions(-) diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index aa7def6b1f..ad4d3acb42 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -25,7 +25,7 @@ import io.anuke.ucore.util.OS; import java.util.Locale; public class Vars{ - public static final boolean testMobile = false; + public static final boolean testMobile = true; //shorthand for whether or not this is running on android or ios public static boolean mobile; public static boolean ios; diff --git a/core/src/io/anuke/mindustry/content/fx/Fx.java b/core/src/io/anuke/mindustry/content/fx/Fx.java index bf831a53bc..33586e7ac3 100644 --- a/core/src/io/anuke/mindustry/content/fx/Fx.java +++ b/core/src/io/anuke/mindustry/content/fx/Fx.java @@ -12,7 +12,7 @@ import io.anuke.ucore.util.Angles; import static io.anuke.mindustry.Vars.tilesize; public class Fx implements ContentList { - public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock; + public static Effect none, placeBlock, breakBlock, smoke, spawn, tapBlock, select; @Override public void load() { @@ -45,6 +45,13 @@ public class Fx implements ContentList { Draw.reset(); }); + select = new Effect(23, e -> { + Draw.color(Palette.accent); + Lines.stroke(e.fout() * 3f); + Lines.circle(e.x, e.y, 3f + e.fin() * 14f); + Draw.reset(); + }); + smoke = new Effect(100, e -> { Draw.color(Color.GRAY, new Color(0.3f, 0.3f, 0.3f, 1f), e.fin()); float size = 7f - e.fin() * 7f; diff --git a/core/src/io/anuke/mindustry/content/fx/UnitFx.java b/core/src/io/anuke/mindustry/content/fx/UnitFx.java index 7f26881064..af9cdcaddf 100644 --- a/core/src/io/anuke/mindustry/content/fx/UnitFx.java +++ b/core/src/io/anuke/mindustry/content/fx/UnitFx.java @@ -1,15 +1,17 @@ package io.anuke.mindustry.content.fx; +import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.type.ContentList; import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Fill; +import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Mathf; public class UnitFx implements ContentList { - public static Effect vtolHover; + public static Effect vtolHover, unitDrop, unitPickup; @Override public void load() { @@ -21,5 +23,20 @@ public class UnitFx implements ContentList { Fill.circle(e.x + Angles.trnsx(ang, len), e.y + Angles.trnsy(ang, len), 2f * e.fout()); Draw.reset(); }); + + unitDrop = new GroundEffect(30, e -> { + Draw.color(Palette.lightishGray); + Angles.randLenVectors(e.id, 9, 3 + 20f * e.finpow(), (x, y) -> { + Fill.circle(e.x + x, e.y + y, e.fout() * 4f + 0.4f); + }); + Draw.reset(); + }); + + unitPickup = new GroundEffect(18, e -> { + Draw.color(Palette.lightishGray); + Lines.stroke(e.fin() * 2f); + Lines.poly(e.x, e.y, 4, 13f * e.fout()); + Draw.reset(); + }); } } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index b249b48dc3..2139a336cb 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -228,7 +228,6 @@ public class Renderer extends RendererModule{ drawAllTeams(true); EntityDraw.draw(bulletGroup); - EntityDraw.draw(fireGroup); EntityDraw.draw(effectGroup); overlays.drawTop(); diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index e91cae5dcd..657ba79ddd 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -65,6 +65,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { public boolean isLocal = false; public Timer timer = new Timer(4); public TargetTrait target; + public CarriableTrait pickupTarget; private boolean respawning; private float walktime; @@ -141,7 +142,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { @Override public boolean isFlying(){ - return mech.flying || noclip; + return mech.flying || noclip || isCarried(); } @Override @@ -172,10 +173,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { respawning = false; placeQueue.clear(); - if(carrying != null){ - carrying.setCarrier(null); - carrying = null; - } + dropCarry(); float explosiveness = 2f + (inventory.hasItem() ? inventory.getItem().item.explosiveness * inventory.getItem().amount : 0f); float flammability = (inventory.hasItem() ? inventory.getItem().item.flammability * inventory.getItem().amount : 0f); @@ -196,10 +194,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { @Override public void removed() { - if(carrying != null){ - carrying.setCarrier(null); - carrying = null; - } + dropCarry(); } @Override @@ -207,10 +202,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { return playerGroup; } - public void toggleTeam(){ - team = (team == Team.blue ? Team.red : Team.blue); - } - //endregion //region draw methods @@ -301,7 +292,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { drawBuilding(this); } - if(isFlying()){ + if(mech.flying){ trail.draw(Palette.lighterOrange, Palette.lightishOrange, 5f); } } @@ -479,6 +470,20 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { float targetX = Core.camera.position.x, targetY = Core.camera.position.y; float attractDst = 15f; + if(pickupTarget != null && !pickupTarget.isDead()){ + targetX = pickupTarget.getX(); + targetY = pickupTarget.getY(); + attractDst = 0f; + + if(distanceTo(pickupTarget) < 2f){ + carry(pickupTarget); + + pickupTarget = null; + } + }else{ + pickupTarget = null; + } + movement.set(targetX - x, targetY - y).limit(flySpeed); movement.setAngle(Mathf.slerpDelta(movement.angle(), velocity.angle(), 0.05f)); @@ -531,6 +536,10 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { //region utility methods + public void toggleTeam(){ + team = (team == Team.blue ? Team.red : Team.blue); + } + /**Resets all values of the player.*/ public void reset(){ weapon = Weapons.blaster; @@ -541,11 +550,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait { dead = true; respawning = false; - if(carrying != null){ - carrying.setCarrier(null); - carrying = null; - } - add(); heal(); } diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index 7323a30e2c..6050189ec4 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -12,10 +12,10 @@ import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; +import io.anuke.ucore.entities.impl.DestructibleEntity; import io.anuke.ucore.entities.trait.DamageTrait; import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.entities.trait.SolidTrait; -import io.anuke.ucore.entities.impl.DestructibleEntity; import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; @@ -148,6 +148,12 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ } public void updateVelocityStatus(float drag, float maxVelocity){ + if(isCarried()){ //carried units do not take into account velocity normally + set(carrier.getX(), carrier.getY()); + velocity.set(carrier.getVelocity()); + return; + } + Floor floor = getFloorOn(); Tile tile = world.tileWorld(x, y); diff --git a/core/src/io/anuke/mindustry/entities/effect/Fire.java b/core/src/io/anuke/mindustry/entities/effect/Fire.java index 1e206c0646..610dc6d78d 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Fire.java +++ b/core/src/io/anuke/mindustry/entities/effect/Fire.java @@ -7,14 +7,13 @@ import com.badlogic.gdx.utils.Pools; import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.fx.EnvironmentFx; import io.anuke.mindustry.entities.Damage; -import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.entities.TileEntity; +import io.anuke.mindustry.entities.traits.SaveTrait; import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Tile; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; -import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.entities.impl.TimedEntity; import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Mathf; @@ -25,7 +24,7 @@ import java.io.IOException; import static io.anuke.mindustry.Vars.*; -public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait { +public class Fire extends TimedEntity implements SaveTrait, Poolable { private static final IntMap map = new IntMap<>(); private static final float baseLifetime = 1000f; @@ -115,11 +114,6 @@ public class Fire extends TimedEntity implements SaveTrait, Poolable, DrawTrait } } - @Override - public float drawSize() { - return 10; - } - @Override public void writeSave(DataOutputStream stream) throws IOException { stream.writeInt(tile.packedPosition()); diff --git a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java index 9fc829dba7..810470cefe 100644 --- a/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java +++ b/core/src/io/anuke/mindustry/entities/effect/GroundEffectEntity.java @@ -72,5 +72,11 @@ public class GroundEffectEntity extends EffectEntity { this.staticLife = 0f; this.isStatic = isStatic; } + + public GroundEffect(float life, EffectRenderer draw) { + super(life, draw); + this.staticLife = 0f; + this.isStatic = false; + } } } diff --git a/core/src/io/anuke/mindustry/entities/effect/Shield.java b/core/src/io/anuke/mindustry/entities/effect/Shield.java index ddf05eccbd..11f183fce1 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Shield.java +++ b/core/src/io/anuke/mindustry/entities/effect/Shield.java @@ -6,13 +6,14 @@ import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.impl.BaseEntity; +import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.shieldGroup; //todo re-implement -public class Shield extends BaseEntity { +public class Shield extends BaseEntity implements DrawTrait { public boolean active; public boolean hitPlayers = false; public float radius = 0f; diff --git a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java b/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java index c4cb02605a..fecfc64f44 100644 --- a/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java +++ b/core/src/io/anuke/mindustry/entities/traits/CarryTrait.java @@ -1,9 +1,39 @@ package io.anuke.mindustry.entities.traits; +import io.anuke.mindustry.content.fx.UnitFx; +import io.anuke.ucore.core.Effects; import io.anuke.ucore.entities.trait.SolidTrait; public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ + /**Returns the thing this carrier is carrying.*/ CarriableTrait getCarry(); + /**Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.*/ void setCarry(CarriableTrait unit); + /**Returns maximum mass this carrier can carry.*/ float getCarryWeight(); + + /**Drops the unit that is being carried, if applicable.*/ + default void dropCarry(){ + carry(null); + } + + /**Do not override unless absolutely necessary. + * Carries a unit. To drop a unit, call with {@code null}.*/ + default void carry(CarriableTrait unit){ + if(getCarry() != null){ //already carrying something, drop it + //drop current + Effects.effect(UnitFx.unitDrop, getCarry()); + getCarry().setCarrier(null); + setCarry(null); + + if(unit != null){ + carry(unit); //now carry this new thing + } + }else if(unit != null){ //not currently carrying anything, make sure it's not null + setCarry(unit); + unit.setCarrier(this); + + Effects.effect(UnitFx.unitPickup, this); + } + } } diff --git a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java index d44f8bb6f3..9f9c58eb94 100644 --- a/core/src/io/anuke/mindustry/entities/units/BaseUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/BaseUnit.java @@ -221,11 +221,6 @@ public abstract class BaseUnit extends Unit{ return !isFlying(); } - @Override - public void removed(){ - - } - @Override public void added(){ hitbox.setSize(type.hitsize); diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java index f3462d304c..e43efeaba3 100644 --- a/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java +++ b/core/src/io/anuke/mindustry/entities/units/FlyingUnit.java @@ -1,6 +1,8 @@ package io.anuke.mindustry.entities.units; import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.traits.CarriableTrait; +import io.anuke.mindustry.entities.traits.CarryTrait; import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Trail; @@ -16,17 +18,33 @@ import io.anuke.ucore.util.Translator; import static io.anuke.mindustry.Vars.world; -public class FlyingUnit extends BaseUnit { +public class FlyingUnit extends BaseUnit implements CarryTrait{ protected static Translator vec = new Translator(); protected static float maxAim = 30f; protected static float wobblyness = 0.6f; protected Trail trail = new Trail(16); + protected CarriableTrait carrying; public FlyingUnit(UnitType type, Team team) { super(type, team); } + @Override + public CarriableTrait getCarry() { + return carrying; + } + + @Override + public void setCarry(CarriableTrait unit) { + this.carrying = unit; + } + + @Override + public float getCarryWeight() { + return type.carryWeight; + } + @Override public void update() { super.update(); @@ -69,6 +87,17 @@ public class FlyingUnit extends BaseUnit { return 60; } + @Override + public void removed() { + dropCarry(); + } + + @Override + public void onDeath() { + super.onDeath(); + dropCarry(); + } + protected void circle(float circleLength){ vec.set(target.getX() - x, target.getY() - y); diff --git a/core/src/io/anuke/mindustry/entities/units/UnitType.java b/core/src/io/anuke/mindustry/entities/units/UnitType.java index 9b021caedd..c807a38e75 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitType.java @@ -29,6 +29,7 @@ public class UnitType { public float reload = 40f; public float retreatPercent = 0.2f; public float armor = 0f; + public float carryWeight = 1f; public ObjectMap ammo = new ObjectMap<>(); public UnitType(String name, UnitCreator creator){ diff --git a/core/src/io/anuke/mindustry/input/AndroidInput.java b/core/src/io/anuke/mindustry/input/AndroidInput.java index aed88b4682..3f3e4ad0db 100644 --- a/core/src/io/anuke/mindustry/input/AndroidInput.java +++ b/core/src/io/anuke/mindustry/input/AndroidInput.java @@ -14,9 +14,9 @@ import io.anuke.mindustry.content.blocks.Blocks; import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.Player; -import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.entities.traits.TargetTrait; import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; @@ -203,9 +203,11 @@ public class AndroidInput extends InputHandler implements GestureListener{ margin(5); defaults().size(60f); - //Add a cancel button, which clears the selection. - new imagebutton("icon-cancel", 16 * 2f, () -> selection.clear()) - .cell.disabled(i -> selection.size == 0); + //Add a cancel button + new imagebutton("icon-cancel", 16 * 2f, () -> { + mode = none; + recipe = null; + }); //Add an accept button, which places everything. new imagebutton("icon-check", 16 * 2f, () -> { @@ -481,7 +483,9 @@ public class AndroidInput extends InputHandler implements GestureListener{ public boolean tap(float x, float y, int count, int button) { if(state.is(State.menu) || lineMode) return false; - checkTargets(Graphics.world(x, y).x, Graphics.world(x, y).y); + float worldx = Graphics.world(x, y).x, worldy = Graphics.world(x, y).y; + + checkTargets(worldx, worldy); //get tile on cursor Tile cursor = tileAt(x, y); @@ -498,6 +502,17 @@ public class AndroidInput extends InputHandler implements GestureListener{ }else if(mode == breaking && validBreak(cursor.x, cursor.y) && !hasRequest(cursor)){ //add to selection queue if it's a valid BREAK position selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy())); + }else{ //else, try and carry units + if(player.getCarry() != null){ + player.dropCarry(); //drop off unit + }else{ + Unit unit = Units.getClosest(player.getTeam(), Graphics.world(x, y).x, Graphics.world(x, y).y, 4f, u -> !u.isFlying()); + + if(unit != null){ + player.pickupTarget = unit; + Effects.effect(Fx.select, unit.getX(), unit.getY()); + } + } } return false;