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;
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;

View File

@ -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;

View File

@ -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();
});
}
}

View File

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

View File

@ -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();
}

View File

@ -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);

View File

@ -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<Fire> 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());

View File

@ -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;
}
}
}

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.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;

View File

@ -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);
}
}
}

View File

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

View File

@ -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);

View File

@ -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<Item, AmmoType> ammo = new ObjectMap<>();
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.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;