Added (mobile) pickup/dropping of units

This commit is contained in:
Anuken
2018-06-05 00:02:07 -04:00
parent b10fa9e5b2
commit c5ed0afb4e
14 changed files with 148 additions and 44 deletions

View File

@@ -25,7 +25,7 @@ import io.anuke.ucore.util.OS;
import java.util.Locale; import java.util.Locale;
public class Vars{ 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 //shorthand for whether or not this is running on android or ios
public static boolean mobile; public static boolean mobile;
public static boolean ios; public static boolean ios;

View File

@@ -12,7 +12,7 @@ import io.anuke.ucore.util.Angles;
import static io.anuke.mindustry.Vars.tilesize; import static io.anuke.mindustry.Vars.tilesize;
public class Fx implements ContentList { 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 @Override
public void load() { public void load() {
@@ -45,6 +45,13 @@ public class Fx implements ContentList {
Draw.reset(); 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 -> { smoke = new Effect(100, e -> {
Draw.color(Color.GRAY, new Color(0.3f, 0.3f, 0.3f, 1f), e.fin()); Draw.color(Color.GRAY, new Color(0.3f, 0.3f, 0.3f, 1f), e.fin());
float size = 7f - e.fin() * 7f; float size = 7f - e.fin() * 7f;

View File

@@ -1,15 +1,17 @@
package io.anuke.mindustry.content.fx; package io.anuke.mindustry.content.fx;
import io.anuke.mindustry.entities.effect.GroundEffectEntity.GroundEffect;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.type.ContentList; import io.anuke.mindustry.type.ContentList;
import io.anuke.ucore.core.Effects.Effect; import io.anuke.ucore.core.Effects.Effect;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.Angles; import io.anuke.ucore.util.Angles;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
public class UnitFx implements ContentList { public class UnitFx implements ContentList {
public static Effect vtolHover; public static Effect vtolHover, unitDrop, unitPickup;
@Override @Override
public void load() { 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()); Fill.circle(e.x + Angles.trnsx(ang, len), e.y + Angles.trnsy(ang, len), 2f * e.fout());
Draw.reset(); 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();
});
} }
} }

View File

@@ -228,7 +228,6 @@ public class Renderer extends RendererModule{
drawAllTeams(true); drawAllTeams(true);
EntityDraw.draw(bulletGroup); EntityDraw.draw(bulletGroup);
EntityDraw.draw(fireGroup);
EntityDraw.draw(effectGroup); EntityDraw.draw(effectGroup);
overlays.drawTop(); overlays.drawTop();

View File

@@ -65,6 +65,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
public boolean isLocal = false; public boolean isLocal = false;
public Timer timer = new Timer(4); public Timer timer = new Timer(4);
public TargetTrait target; public TargetTrait target;
public CarriableTrait pickupTarget;
private boolean respawning; private boolean respawning;
private float walktime; private float walktime;
@@ -141,7 +142,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
@Override @Override
public boolean isFlying(){ public boolean isFlying(){
return mech.flying || noclip; return mech.flying || noclip || isCarried();
} }
@Override @Override
@@ -172,10 +173,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
respawning = false; respawning = false;
placeQueue.clear(); placeQueue.clear();
if(carrying != null){ dropCarry();
carrying.setCarrier(null);
carrying = null;
}
float explosiveness = 2f + (inventory.hasItem() ? inventory.getItem().item.explosiveness * inventory.getItem().amount : 0f); 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); 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 @Override
public void removed() { public void removed() {
if(carrying != null){ dropCarry();
carrying.setCarrier(null);
carrying = null;
}
} }
@Override @Override
@@ -207,10 +202,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
return playerGroup; return playerGroup;
} }
public void toggleTeam(){
team = (team == Team.blue ? Team.red : Team.blue);
}
//endregion //endregion
//region draw methods //region draw methods
@@ -301,7 +292,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
drawBuilding(this); drawBuilding(this);
} }
if(isFlying()){ if(mech.flying){
trail.draw(Palette.lighterOrange, Palette.lightishOrange, 5f); 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 targetX = Core.camera.position.x, targetY = Core.camera.position.y;
float attractDst = 15f; 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.set(targetX - x, targetY - y).limit(flySpeed);
movement.setAngle(Mathf.slerpDelta(movement.angle(), velocity.angle(), 0.05f)); 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 //region utility methods
public void toggleTeam(){
team = (team == Team.blue ? Team.red : Team.blue);
}
/**Resets all values of the player.*/ /**Resets all values of the player.*/
public void reset(){ public void reset(){
weapon = Weapons.blaster; weapon = Weapons.blaster;
@@ -541,11 +550,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
dead = true; dead = true;
respawning = false; respawning = false;
if(carrying != null){
carrying.setCarrier(null);
carrying = null;
}
add(); add();
heal(); heal();
} }

View File

@@ -12,10 +12,10 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers; 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.DamageTrait;
import io.anuke.ucore.entities.trait.DrawTrait; import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.trait.SolidTrait; 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.Geometry;
import io.anuke.ucore.util.Mathf; 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){ 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(); Floor floor = getFloorOn();
Tile tile = world.tileWorld(x, y); Tile tile = world.tileWorld(x, y);

View File

@@ -7,14 +7,13 @@ import com.badlogic.gdx.utils.Pools;
import io.anuke.mindustry.content.StatusEffects; import io.anuke.mindustry.content.StatusEffects;
import io.anuke.mindustry.content.fx.EnvironmentFx; import io.anuke.mindustry.content.fx.EnvironmentFx;
import io.anuke.mindustry.entities.Damage; import io.anuke.mindustry.entities.Damage;
import io.anuke.mindustry.entities.traits.SaveTrait;
import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.TileEntity;
import io.anuke.mindustry.entities.traits.SaveTrait;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.entities.impl.TimedEntity; import io.anuke.ucore.entities.impl.TimedEntity;
import io.anuke.ucore.util.Geometry; import io.anuke.ucore.util.Geometry;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
@@ -25,7 +24,7 @@ import java.io.IOException;
import static io.anuke.mindustry.Vars.*; 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<Fire> map = new IntMap<>(); private static final IntMap<Fire> map = new IntMap<>();
private static final float baseLifetime = 1000f; 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 @Override
public void writeSave(DataOutputStream stream) throws IOException { public void writeSave(DataOutputStream stream) throws IOException {
stream.writeInt(tile.packedPosition()); stream.writeInt(tile.packedPosition());

View File

@@ -72,5 +72,11 @@ public class GroundEffectEntity extends EffectEntity {
this.staticLife = 0f; this.staticLife = 0f;
this.isStatic = isStatic; this.isStatic = isStatic;
} }
public GroundEffect(float life, EffectRenderer draw) {
super(life, draw);
this.staticLife = 0f;
this.isStatic = false;
}
} }
} }

View File

@@ -6,13 +6,14 @@ import io.anuke.mindustry.world.blocks.types.defense.ShieldBlock;
import io.anuke.ucore.core.Timers; import io.anuke.ucore.core.Timers;
import io.anuke.ucore.entities.EntityGroup; import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.impl.BaseEntity; import io.anuke.ucore.entities.impl.BaseEntity;
import io.anuke.ucore.entities.trait.DrawTrait;
import io.anuke.ucore.graphics.Fill; import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.util.Mathf; import io.anuke.ucore.util.Mathf;
import static io.anuke.mindustry.Vars.shieldGroup; import static io.anuke.mindustry.Vars.shieldGroup;
//todo re-implement //todo re-implement
public class Shield extends BaseEntity { public class Shield extends BaseEntity implements DrawTrait {
public boolean active; public boolean active;
public boolean hitPlayers = false; public boolean hitPlayers = false;
public float radius = 0f; public float radius = 0f;

View File

@@ -1,9 +1,39 @@
package io.anuke.mindustry.entities.traits; 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; import io.anuke.ucore.entities.trait.SolidTrait;
public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{ public interface CarryTrait extends TeamTrait, SolidTrait, TargetTrait{
/**Returns the thing this carrier is carrying.*/
CarriableTrait getCarry(); CarriableTrait getCarry();
/**Sets the carrying unit. Internal use only! Use {@link #carry(CarriableTrait)} to set state.*/
void setCarry(CarriableTrait unit); void setCarry(CarriableTrait unit);
/**Returns maximum mass this carrier can carry.*/
float getCarryWeight(); 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);
}
}
} }

View File

@@ -221,11 +221,6 @@ public abstract class BaseUnit extends Unit{
return !isFlying(); return !isFlying();
} }
@Override
public void removed(){
}
@Override @Override
public void added(){ public void added(){
hitbox.setSize(type.hitsize); hitbox.setSize(type.hitsize);

View File

@@ -1,6 +1,8 @@
package io.anuke.mindustry.entities.units; package io.anuke.mindustry.entities.units;
import 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.game.Team;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail; import io.anuke.mindustry.graphics.Trail;
@@ -16,17 +18,33 @@ import io.anuke.ucore.util.Translator;
import static io.anuke.mindustry.Vars.world; 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 Translator vec = new Translator();
protected static float maxAim = 30f; protected static float maxAim = 30f;
protected static float wobblyness = 0.6f; protected static float wobblyness = 0.6f;
protected Trail trail = new Trail(16); protected Trail trail = new Trail(16);
protected CarriableTrait carrying;
public FlyingUnit(UnitType type, Team team) { public FlyingUnit(UnitType type, Team team) {
super(type, 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 @Override
public void update() { public void update() {
super.update(); super.update();
@@ -69,6 +87,17 @@ public class FlyingUnit extends BaseUnit {
return 60; return 60;
} }
@Override
public void removed() {
dropCarry();
}
@Override
public void onDeath() {
super.onDeath();
dropCarry();
}
protected void circle(float circleLength){ protected void circle(float circleLength){
vec.set(target.getX() - x, target.getY() - y); vec.set(target.getX() - x, target.getY() - y);

View File

@@ -29,6 +29,7 @@ public class UnitType {
public float reload = 40f; public float reload = 40f;
public float retreatPercent = 0.2f; public float retreatPercent = 0.2f;
public float armor = 0f; public float armor = 0f;
public float carryWeight = 1f;
public ObjectMap<Item, AmmoType> ammo = new ObjectMap<>(); public ObjectMap<Item, AmmoType> ammo = new ObjectMap<>();
public UnitType(String name, UnitCreator creator){ public UnitType(String name, UnitCreator creator){

View File

@@ -14,9 +14,9 @@ import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.entities.Unit; import io.anuke.mindustry.entities.Unit;
import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.Units;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.graphics.Palette; import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult; import io.anuke.mindustry.input.PlaceUtils.NormalizeDrawResult;
@@ -203,9 +203,11 @@ public class AndroidInput extends InputHandler implements GestureListener{
margin(5); margin(5);
defaults().size(60f); defaults().size(60f);
//Add a cancel button, which clears the selection. //Add a cancel button
new imagebutton("icon-cancel", 16 * 2f, () -> selection.clear()) new imagebutton("icon-cancel", 16 * 2f, () -> {
.cell.disabled(i -> selection.size == 0); mode = none;
recipe = null;
});
//Add an accept button, which places everything. //Add an accept button, which places everything.
new imagebutton("icon-check", 16 * 2f, () -> { 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) { public boolean tap(float x, float y, int count, int button) {
if(state.is(State.menu) || lineMode) return false; 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 //get tile on cursor
Tile cursor = tileAt(x, y); 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)){ }else if(mode == breaking && validBreak(cursor.x, cursor.y) && !hasRequest(cursor)){
//add to selection queue if it's a valid BREAK position //add to selection queue if it's a valid BREAK position
selection.add(new PlaceRequest(cursor.worldx(), cursor.worldy())); 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; return false;