diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 01d804c3fd..eb22512fe1 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -12,6 +12,8 @@ android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" + android:isGame="true" + android:appCategory="game" android:label="@string/app_name" android:theme="@style/GdxTheme" > > map = getMap(tile.getTeam()); for(BlockFlag flag : tile.block().flags){ diff --git a/core/src/io/anuke/mindustry/entities/effect/Rubble.java b/core/src/io/anuke/mindustry/entities/effect/Rubble.java index b8f224ede1..61027a5bf2 100644 --- a/core/src/io/anuke/mindustry/entities/effect/Rubble.java +++ b/core/src/io/anuke/mindustry/entities/effect/Rubble.java @@ -14,7 +14,7 @@ public class Rubble extends TimedEntity implements BelowLiquidEffect{ public static void create(float x, float y, int size){ Rubble rubble = new Rubble(); rubble.size = size; - rubble.set(x + Mathf.range(1), y + Mathf.range(1)).add(); + rubble.set(x, y).add(); } private Rubble(){ diff --git a/core/src/io/anuke/mindustry/entities/units/FlyingUnitType.java b/core/src/io/anuke/mindustry/entities/units/FlyingUnitType.java index 55d0b0aab6..9f7ea0fb39 100644 --- a/core/src/io/anuke/mindustry/entities/units/FlyingUnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/FlyingUnitType.java @@ -1,13 +1,26 @@ package io.anuke.mindustry.entities.units; import com.badlogic.gdx.math.Vector2; +import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.Units; +import io.anuke.mindustry.resource.AmmoType; +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.flags.BlockFlag; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; + +import static io.anuke.mindustry.Vars.world; public class FlyingUnitType extends UnitType { protected static Vector2 vec = new Vector2(); protected float boosterLength = 4.5f; + protected float retreatHealth = 10f; + protected float maxAim = 30f; public FlyingUnitType(String name) { super(name); @@ -38,4 +51,109 @@ public class FlyingUnitType extends UnitType { public void behavior(BaseUnit unit) { } + + protected void circle(BaseUnit unit, float circleLength){ + vec.set(unit.target.x - unit.x, unit.target.y - unit.y); + + if(vec.len() < circleLength){ + vec.rotate((circleLength-vec.len())/circleLength * 180f); + } + + vec.setLength(speed * Timers.delta()); + + unit.velocity.add(vec); + } + + protected void attack(BaseUnit unit, float circleLength){ + vec.set(unit.target.x - unit.x, unit.target.y - unit.y); + + float ang = unit.angleTo(unit.target); + float diff = Angles.angleDist(ang, unit.rotation); + + if(diff > 100f && vec.len() < circleLength){ + vec.setAngle(unit.velocity.angle()); + }else{ + vec.setAngle(Mathf.slerpDelta(unit.velocity.angle(), vec.angle(), 0.44f)); + } + + vec.setLength(speed*Timers.delta()); + + unit.velocity.add(vec); + } + + public final UnitState + + resupply = new UnitState(){ + public void entered(BaseUnit unit) { + unit.target = null; + } + + public void update(BaseUnit unit) { + if(unit.inventory.totalAmmo() + 10 >= unit.inventory.ammoCapacity()){ + unit.state.set(unit, attack); + }else if(!unit.targetHasFlag(BlockFlag.resupplyPoint)){ + if(unit.timer.get(timerTarget, 20)) { + Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.resupplyPoint)); + if (target != null) unit.target = target.entity; + } + }else{ + circle(unit, 20f); + } + } + }, + attack = new UnitState(){ + public void entered(BaseUnit unit) { + unit.target = null; + } + + public void update(BaseUnit unit) { + if(unit.target != null && (unit.target instanceof TileEntity && + (((TileEntity)unit.target).tile.getTeam() == unit.team || !((TileEntity)unit.target).tile.breakable()))){ + unit.target = null; + } + + if(!unit.inventory.hasAmmo()) { + unit.state.set(unit, resupply); + }else if (unit.target == null){ + if(unit.timer.get(timerTarget, 20)) { + Unit closest = Units.getClosestEnemy(unit.team, unit.x, unit.y, + unit.inventory.getAmmo().getRange(), other -> other.distanceTo(unit) < 60f); + if(closest != null){ + unit.target = closest; + }else { + Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getEnemy(unit.team, BlockFlag.resupplyPoint)); + if (target != null) unit.target = target.entity; + } + } + }else{ + attack(unit, 150f); + + if (unit.timer.get(timerReload, 7) && Mathf.angNear(unit.angleTo(unit.target), unit.rotation, 13f) + && unit.distanceTo(unit.target) < unit.inventory.getAmmo().getRange()) { + AmmoType ammo = unit.inventory.getAmmo(); + unit.inventory.useAmmo(); + + shoot(unit, ammo, Angles.moveToward(unit.rotation, unit.angleTo(unit.target), maxAim), 4f); + } + } + } + }, + retreat = new UnitState() { + public void entered(BaseUnit unit) { + unit.target = null; + } + + public void update(BaseUnit unit) { + if(unit.health >= health){ + unit.state.set(unit, attack); + }else if(!unit.targetHasFlag(BlockFlag.repair)){ + if(unit.timer.get(timerTarget, 20)) { + Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)); + if (target != null) unit.target = target.entity; + } + }else{ + circle(unit, 20f); + } + } + }; } diff --git a/core/src/io/anuke/mindustry/entities/units/UnitType.java b/core/src/io/anuke/mindustry/entities/units/UnitType.java index 8f5d47755b..3b6f7899bb 100644 --- a/core/src/io/anuke/mindustry/entities/units/UnitType.java +++ b/core/src/io/anuke/mindustry/entities/units/UnitType.java @@ -30,7 +30,7 @@ public abstract class UnitType { public final String name; public final byte id; - protected int health = 60; + protected float health = 60; protected float hitsize = 5f; protected float hitsizeTile = 4f; protected float speed = 0.4f; @@ -94,7 +94,7 @@ public abstract class UnitType { public abstract void behavior(BaseUnit unit); public void updateTargeting(BaseUnit unit){ - if(unit.target == null || (unit.target instanceof Unit && ((Unit)unit.target).isDead())){ + if(unit.target == null || (unit.target instanceof Unit && (((Unit)unit.target).isDead() || ((Unit)unit.target).team == unit.team))){ unit.target = null; } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Cruiser.java b/core/src/io/anuke/mindustry/entities/units/types/Cruiser.java index 07aa14b11d..c09a84c8e1 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Cruiser.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Cruiser.java @@ -1,10 +1,81 @@ package io.anuke.mindustry.entities.units.types; +import io.anuke.mindustry.content.AmmoTypes; +import io.anuke.mindustry.entities.Unit; +import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.FlyingUnitType; +import io.anuke.mindustry.entities.units.UnitState; +import io.anuke.mindustry.graphics.Palette; +import io.anuke.mindustry.world.flags.BlockFlag; +import io.anuke.ucore.core.Timers; +import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.util.Angles; +import io.anuke.ucore.util.Geometry; +import io.anuke.ucore.util.Mathf; + +import static io.anuke.mindustry.Vars.world; public class Cruiser extends FlyingUnitType { - public Cruiser(String name) { - super(name); + + public Cruiser(){ + super("vtol"); + setAmmo(AmmoTypes.basicIron); + speed = 0.2f; + maxVelocity = 1.4f; + health = 300f; + } + + @Override + public void drawUnder(BaseUnit unit) { + float rotation = unit.rotation - 90; + float scl = 0.6f + Mathf.absin(Timers.time(), 1f, 0.3f); + float dy = -6f*scl; + + Draw.color(Palette.lighterOrange, Palette.lightFlame, Mathf.absin(Timers.time(), 3f, 0.7f)); + + Draw.rect("vtol-flame", + unit.x + Angles.trnsx(rotation, 0, dy), + unit.y + Angles.trnsy(rotation, 0, dy), Mathf.atan2(0, dy) + rotation); + + Draw.color(); + } + + @Override + public void draw(BaseUnit unit) { + Draw.alpha(unit.hitTime / Unit.hitDuration); + + Draw.rect(name, unit.x, unit.y, unit.rotation - 90); + + Draw.alpha(1f); + } + + @Override + public void update(BaseUnit unit) { + super.update(unit); + + unit.x += Mathf.sin(Timers.time() + unit.id * 999, 25f, 0.06f); + unit.y += Mathf.cos(Timers.time() + unit.id * 999, 25f, 0.06f); + + if(unit.velocity.len() <= 0.2f){ + unit.rotation += Mathf.sin(Timers.time() + unit.id * 99, 10f, 8f); + } + + if(unit.timer.get(timerBoost, 2)){ + // unit.effectAt(UnitFx.vtolHover, unit.rotation + 180f, 4f, 0); + } + } + + @Override + public void behavior(BaseUnit unit) { + if(unit.health <= retreatHealth && + Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)) != null){ + unit.setState(retreat); + } + } + + @Override + public UnitState getStartState(){ + return resupply; } } diff --git a/core/src/io/anuke/mindustry/entities/units/types/Vtol.java b/core/src/io/anuke/mindustry/entities/units/types/Vtol.java index 32b149325a..4e10ad0c7c 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/Vtol.java +++ b/core/src/io/anuke/mindustry/entities/units/types/Vtol.java @@ -3,13 +3,10 @@ package io.anuke.mindustry.entities.units.types; import io.anuke.mindustry.content.AmmoTypes; import io.anuke.mindustry.content.fx.UnitFx; import io.anuke.mindustry.entities.Unit; -import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.entities.units.BaseUnit; import io.anuke.mindustry.entities.units.FlyingUnitType; import io.anuke.mindustry.entities.units.UnitState; import io.anuke.mindustry.graphics.Palette; -import io.anuke.mindustry.resource.AmmoType; -import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.flags.BlockFlag; import io.anuke.ucore.core.Timers; import io.anuke.ucore.graphics.Draw; @@ -20,7 +17,6 @@ import io.anuke.ucore.util.Mathf; import static io.anuke.mindustry.Vars.world; public class Vtol extends FlyingUnitType { - private float retreatHealth = 10f; public Vtol(){ super("vtol"); @@ -42,28 +38,6 @@ public class Vtol extends FlyingUnitType { unit.y + Angles.trnsy(rotation, 0, dy), Mathf.atan2(0, dy) + rotation); Draw.color(); - - - /* - for(int i : Mathf.signs) { - - float rotation = unit.rotation - 90; - float scl = 0.7f + Mathf.absin(Timers.time(), 3f, 0.2f); - float dx = 5f * i*scl, dx2 = 6f * i*scl; - float dy = 4f*scl, dy2 = -5f*scl; - - Draw.color(Palette.lighterOrange, Palette.lightFlame, Mathf.absin(Timers.time(), 3f, 0.7f)); - - Draw.rect("vtol-flame", - unit.x + Angles.trnsx(rotation, dx, dy), - unit.y + Angles.trnsy(rotation, dx, dy), Mathf.atan2(dx, dy) + rotation); - - Draw.rect("vtol-flame", - unit.x + Angles.trnsx(rotation, dx2, dy2), - unit.y + Angles.trnsy(rotation, dx2, dy2), Mathf.atan2(dx2, dy2) + rotation); - - Draw.color(); - }*/ } @Override @@ -108,104 +82,4 @@ public class Vtol extends FlyingUnitType { return resupply; } - void circle(BaseUnit unit, float circleLength){ - vec.set(unit.target.x - unit.x, unit.target.y - unit.y); - - if(vec.len() < circleLength){ - vec.rotate((circleLength-vec.len())/circleLength * 180f); - } - - vec.setLength(speed * Timers.delta()); - - unit.velocity.add(vec); - } - - void attack(BaseUnit unit, float circleLength){ - vec.set(unit.target.x - unit.x, unit.target.y - unit.y); - - float ang = unit.angleTo(unit.target); - float diff = Angles.angleDist(ang, unit.rotation); - - if(diff > 100f && vec.len() < circleLength){ - vec.setAngle(unit.velocity.angle()); - }else{ - vec.setAngle(Mathf.slerpDelta(unit.velocity.angle(), vec.angle(), 0.44f)); - } - - vec.setLength(speed*Timers.delta()); - - unit.velocity.add(vec); - } - - public final UnitState - - resupply = new UnitState(){ - public void entered(BaseUnit unit) { - unit.target = null; - } - - public void update(BaseUnit unit) { - if(unit.inventory.totalAmmo() + 10 >= unit.inventory.ammoCapacity()){ - unit.state.set(unit, attack); - }else if(!unit.targetHasFlag(BlockFlag.resupplyPoint)){ - if(unit.timer.get(timerTarget, 20)) { - Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.resupplyPoint)); - if (target != null) unit.target = target.entity; - } - }else{ - circle(unit, 20f); - } - } - }, - attack = new UnitState(){ - public void entered(BaseUnit unit) { - unit.target = null; - } - - public void update(BaseUnit unit) { - if(!unit.inventory.hasAmmo()) { - unit.state.set(unit, resupply); - }else if (unit.target == null){ - if(unit.timer.get(timerTarget, 20)) { - Unit closest = Units.getClosestEnemy(unit.team, unit.x, unit.y, - unit.inventory.getAmmo().getRange(), other -> other.distanceTo(unit) < 60f); - if(closest != null){ - unit.target = closest; - }else { - Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getEnemy(unit.team, BlockFlag.resupplyPoint)); - if (target != null) unit.target = target.entity; - } - } - }else{ - attack(unit, 150f); - - if (unit.timer.get(timerReload, 7) && Mathf.angNear(unit.angleTo(unit.target), unit.rotation, 13f) - && unit.distanceTo(unit.target) < unit.inventory.getAmmo().getRange()) { - AmmoType ammo = unit.inventory.getAmmo(); - unit.inventory.useAmmo(); - - shoot(unit, ammo, unit.rotation, 4f); - } - } - } - }, - retreat = new UnitState() { - public void entered(BaseUnit unit) { - unit.target = null; - } - - public void update(BaseUnit unit) { - if(unit.health >= health){ - unit.state.set(unit, attack); - }else if(!unit.targetHasFlag(BlockFlag.repair)){ - if(unit.timer.get(timerTarget, 20)) { - Tile target = Geometry.findClosest(unit.x, unit.y, world.indexer().getAllied(unit.team, BlockFlag.repair)); - if (target != null) unit.target = target.entity; - } - }else{ - circle(unit, 20f); - } - } - }; - } diff --git a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java index b9e89ffd95..007414c082 100644 --- a/core/src/io/anuke/mindustry/input/DefaultKeybinds.java +++ b/core/src/io/anuke/mindustry/input/DefaultKeybinds.java @@ -11,63 +11,63 @@ public class DefaultKeybinds { public static void load(){ KeyBinds.defaults( - "move_x", new Axis(Input.A, Input.D), - "move_y", new Axis(Input.S, Input.W), - "select", Input.MOUSE_LEFT, - "break", Input.MOUSE_RIGHT, - "shoot", Input.MOUSE_LEFT, - "zoom_hold", Input.CONTROL_LEFT, - "zoom", new Axis(Input.SCROLL), - "zoom_minimap", new Axis(Input.MINUS, Input.PLUS), - "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, - "pause", Input.SPACE, - "dash", Input.SHIFT_LEFT, - "rotate_alt", new Axis(Input.R, Input.E), - "rotate", new Axis(Input.SCROLL), - "block_info", Input.CONTROL_LEFT, - "player_list", Input.TAB, - "chat", Input.ENTER, - "chat_history_prev", Input.UP, - "chat_history_next", Input.DOWN, - "chat_scroll", new Axis(Input.SCROLL), - "item_withdraw", Input.SHIFT_LEFT, - "console", Input.GRAVE, - "weapon_1", Input.NUM_1, - "weapon_2", Input.NUM_2, - "weapon_3", Input.NUM_3, - "weapon_4", Input.NUM_4, - "weapon_5", Input.NUM_5, - "weapon_6", Input.NUM_6 + "move_x", new Axis(Input.A, Input.D), + "move_y", new Axis(Input.S, Input.W), + "select", Input.MOUSE_LEFT, + "break", Input.MOUSE_RIGHT, + "shoot", Input.MOUSE_LEFT, + "zoom_hold", Input.CONTROL_LEFT, + "zoom", new Axis(Input.SCROLL), + "zoom_minimap", new Axis(Input.MINUS, Input.PLUS), + "menu", Gdx.app.getType() == ApplicationType.Android ? Input.BACK : Input.ESCAPE, + "pause", Input.SPACE, + "dash", Input.SHIFT_LEFT, + "rotate_alt", new Axis(Input.R, Input.E), + "rotate", new Axis(Input.SCROLL), + "block_info", Input.CONTROL_LEFT, + "player_list", Input.TAB, + "chat", Input.ENTER, + "chat_history_prev", Input.UP, + "chat_history_next", Input.DOWN, + "chat_scroll", new Axis(Input.SCROLL), + "item_withdraw", Input.SHIFT_LEFT, + "console", Input.GRAVE, + "weapon_1", Input.NUM_1, + "weapon_2", Input.NUM_2, + "weapon_3", Input.NUM_3, + "weapon_4", Input.NUM_4, + "weapon_5", Input.NUM_5, + "weapon_6", Input.NUM_6 ); KeyBinds.defaults( - DeviceType.controller, - "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), - "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), - "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), - "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), - "select", Input.CONTROLLER_R_BUMPER, - "break", Input.CONTROLLER_L_BUMPER, - "shoot", Input.CONTROLLER_R_TRIGGER, - "zoom_hold", Input.ANY_KEY, - "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), - "menu", Input.CONTROLLER_X, - "pause", Input.CONTROLLER_L_TRIGGER, - "dash", Input.CONTROLLER_Y, - "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), - "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), - "player_list", Input.CONTROLLER_START, - "chat", Input.ENTER, - "chat_history_prev", Input.UP, - "chat_history_next", Input.DOWN, - "chat_scroll", new Axis(Input.SCROLL), - "console", Input.GRAVE, - "weapon_1", Input.NUM_1, - "weapon_2", Input.NUM_2, - "weapon_3", Input.NUM_3, - "weapon_4", Input.NUM_4, - "weapon_5", Input.NUM_5, - "weapon_6", Input.NUM_6 + DeviceType.controller, + "move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS), + "move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS), + "cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS), + "cursor_y", new Axis(Input.CONTROLLER_R_STICK_VERTICAL_AXIS), + "select", Input.CONTROLLER_R_BUMPER, + "break", Input.CONTROLLER_L_BUMPER, + "shoot", Input.CONTROLLER_R_TRIGGER, + "zoom_hold", Input.ANY_KEY, + "zoom", new Axis(Input.CONTROLLER_DPAD_DOWN, Input.CONTROLLER_DPAD_UP), + "menu", Input.CONTROLLER_X, + "pause", Input.CONTROLLER_L_TRIGGER, + "dash", Input.CONTROLLER_Y, + "rotate_alt", new Axis(Input.CONTROLLER_DPAD_RIGHT, Input.CONTROLLER_DPAD_LEFT), + "rotate", new Axis(Input.CONTROLLER_A, Input.CONTROLLER_B), + "player_list", Input.CONTROLLER_START, + "chat", Input.ENTER, + "chat_history_prev", Input.UP, + "chat_history_next", Input.DOWN, + "chat_scroll", new Axis(Input.SCROLL), + "console", Input.GRAVE, + "weapon_1", Input.NUM_1, + "weapon_2", Input.NUM_2, + "weapon_3", Input.NUM_3, + "weapon_4", Input.NUM_4, + "weapon_5", Input.NUM_5, + "weapon_6", Input.NUM_6 ); } } diff --git a/core/src/io/anuke/mindustry/world/blocks/types/units/ResupplyPoint.java b/core/src/io/anuke/mindustry/world/blocks/types/units/ResupplyPoint.java index 976a165a30..b70dfdc005 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/units/ResupplyPoint.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/units/ResupplyPoint.java @@ -63,9 +63,9 @@ public class ResupplyPoint extends Block{ x1, y1, entity.lastx, entity.lasty, entity.strength); Draw.color("accent"); - for(int i = 0; i < dstTo/space; i ++){ - float fract = (i * space) / dstTo; - Draw.alpha(Mathf.absin(Timers.time() - i*space, 3f, 1f)); + for(int i = 0; i < dstTo/space-1; i ++){ + float fract = (i * space) / dstTo + ((Timers.time()/90f) % (space/dstTo)); + Draw.alpha(Mathf.clamp(fract*1.5f)); Draw.rect("transfer-arrow", x1 + fract*xf, y1 + fract*yf, 8, 8*entity.strength, ang); }