From a889571b983b2d51d14467214b133d2d6c4f7ea2 Mon Sep 17 00:00:00 2001 From: Anuken Date: Wed, 16 May 2018 12:54:36 -0700 Subject: [PATCH] Added unit-based block building with effects --- .../sprites/blocks/extra/rubble-3-1png | Bin 0 -> 313 bytes .../io/anuke/mindustry/core/NetClient.java | 2 +- .../io/anuke/mindustry/core/NetServer.java | 2 +- .../anuke/mindustry/entities/BlockPlacer.java | 9 ++ .../io/anuke/mindustry/entities/Player.java | 78 +++++++++++++++++- .../src/io/anuke/mindustry/entities/Unit.java | 4 + .../anuke/mindustry/input/InputHandler.java | 5 +- .../io/anuke/mindustry/world/Placement.java | 8 +- .../world/blocks/types/BuildBlock.java | 27 +++++- 9 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 core/assets-raw/sprites/blocks/extra/rubble-3-1png create mode 100644 core/src/io/anuke/mindustry/entities/BlockPlacer.java diff --git a/core/assets-raw/sprites/blocks/extra/rubble-3-1png b/core/assets-raw/sprites/blocks/extra/rubble-3-1png new file mode 100644 index 0000000000000000000000000000000000000000..4fb1a666db35fe7339c11cfb4be65d75a61fa524 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuJoI14-?iy0WWg+Z8+Vb&aw z3ic9DUsv`=tc+qjI*Er^1Q{3@BuiW)N}Tg^b5rw57@Uhz6H8K46v{J8G8EiBeFMT9 z`NSC*7&d#lIEHu}zZ&Mq$E?U9(-Z$R)UK>*g_$&0nfalG#fB3^S<+KlRTu>FPsB{` z?Vf+^m~6apU$&B=^n5mU2Cj6@WFF}k9IH-+GIBB1ugbEwtKzxLS+@Lm8p=yMf+sSNgIF8b})ESzU{QqyBh_EpTBy*8oJRr_P4UmdIkmt22WQ% Jmvv4FO#pMnX?_3z literal 0 HcmV?d00001 diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 4cda49f93c..d3bdae4aeb 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -164,7 +164,7 @@ public class NetClient extends Module { Net.handleClient(PlacePacket.class, (packet) -> { Player placer = playerGroup.getByID(packet.playerid); - Placement.placeBlock(placer.team, packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, Timers.get("placeblocksound", 10)); + Placement.placeBlock(placer, packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, Timers.get("placeblocksound", 10)); for(Player player : players) { if (packet.playerid == player.id) { diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index af9fb5a66d..dfbf01316e 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -214,7 +214,7 @@ public class NetServer extends Module{ state.inventory.removeItems(recipe.requirements); - Placement.placeBlock(placer.team, packet.x, packet.y, block, packet.rotation, true, false); + Placement.placeBlock(placer, packet.x, packet.y, block, packet.rotation, true, false); TraceInfo trace = admins.getTraceByID(getUUID(id)); diff --git a/core/src/io/anuke/mindustry/entities/BlockPlacer.java b/core/src/io/anuke/mindustry/entities/BlockPlacer.java new file mode 100644 index 0000000000..e58a35dab7 --- /dev/null +++ b/core/src/io/anuke/mindustry/entities/BlockPlacer.java @@ -0,0 +1,9 @@ +package io.anuke.mindustry.entities; + +import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.game.Team; + +public interface BlockPlacer { + void addPlaceBlock(Tile tile); + Team getTeam(); +} diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index 609913b792..f5e99b6f54 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -3,6 +3,7 @@ package io.anuke.mindustry.entities; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import io.anuke.mindustry.Vars; import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.content.fx.ExplosionFx; @@ -13,6 +14,8 @@ import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.NetEvents; import io.anuke.mindustry.resource.*; import io.anuke.mindustry.world.Tile; +import io.anuke.mindustry.world.blocks.types.BuildBlock; +import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; import io.anuke.mindustry.world.blocks.types.Floor; import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Inputs; @@ -20,21 +23,27 @@ import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.graphics.Draw; +import io.anuke.ucore.graphics.Fill; +import io.anuke.ucore.graphics.Lines; import io.anuke.ucore.util.*; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.Arrays; import static io.anuke.mindustry.Vars.*; -public class Player extends Unit{ +public class Player extends Unit implements BlockPlacer{ static final float speed = 1.1f; static final float dashSpeed = 1.8f; + static final float placeDistance = 80f; + static final int maxPlacing = 5; static final int timerDash = 0; static final int timerRegen = 3; + static final Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()}; public String name = "name"; public String uuid; @@ -55,6 +64,7 @@ public class Player extends Unit{ public float walktime; public float respawntime; + private Array placeBlocks = new Array<>(); private Vector2 movement = new Vector2(); public Player(){ @@ -99,6 +109,13 @@ public class Player extends Unit{ } } + @Override + public void addPlaceBlock(Tile tile){ + if(placeBlocks.size < maxPlacing) { + placeBlocks.add(tile); + } + } + @Override public boolean collides(SolidEntity other){ return !isDead() && super.collides(other) && !mech.flying; @@ -208,6 +225,47 @@ public class Player extends Unit{ x = px; y = py; } + + @Override + public void drawOver(){ + if(!isShooting()) { + Draw.color("accent"); + float focusLen = 3.8f + Mathf.absin(Timers.time(), 1.1f, 0.6f); + float px = x + Angles.trnsx(rotation, focusLen); + float py = y + Angles.trnsy(rotation, focusLen); + + for (Tile tile : placeBlocks) { + float sz = Vars.tilesize*tile.block().size/2f; + float ang = angleTo(tile); + + tmptr[0].set(tile.drawx() - sz, tile.drawy() - sz); + tmptr[1].set(tile.drawx() + sz, tile.drawy() - sz); + tmptr[2].set(tile.drawx() - sz, tile.drawy() + sz); + tmptr[3].set(tile.drawx() + sz, tile.drawy() + sz); + + Arrays.sort(tmptr, (a, b) -> -Float.compare(Angles.angleDist(Angles.angle(x, y, a.x, a.y), ang), + Angles.angleDist(Angles.angle(x, y, b.x, b.y), ang))); + + float x1 = tmptr[0].x, y1 = tmptr[0].y, + x3 = tmptr[1].x, y3 = tmptr[1].y; + Translator close = Geometry.findClosest(x, y, tmptr); + float x2 = close.x, y2 = close.y; + + Draw.alpha(0.3f + Mathf.absin(Timers.time(), 0.9f, 0.2f)); + + Fill.tri(px, py, x2, y2, x1, y1); + Fill.tri(px, py, x2, y2, x3, y3); + + Draw.alpha(1f); + + Lines.line(px, py, x1, y1); + Lines.line(px, py, x3, y3); + + Fill.circle(px, py, 1.5f + Mathf.absin(Timers.time(), 1f, 1.8f)); + } + Draw.color(); + } + } @Override public void update(){ @@ -253,6 +311,10 @@ public class Player extends Unit{ heal(); } + public boolean isShooting(){ + return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo(); + } + protected void updateMech(){ Tile tile = world.tileWorld(x, y); @@ -262,6 +324,18 @@ public class Player extends Unit{ damage(health + 1); //die instantly } + if(!isShooting()) { + for (Tile check : placeBlocks) { + if (!(check.block() instanceof BuildBlock) || distanceTo(check) > placeDistance) { + placeBlocks.removeValue(check, true); + break; + } + BuildEntity entity = check.entity(); + entity.progress += 1f / entity.result.health; + rotation = Mathf.slerpDelta(rotation, angleTo(entity), 0.4f); + } + } + if(ui.chatfrag.chatOpen()) return; dashing = Inputs.keyDown("dash"); @@ -289,7 +363,7 @@ public class Player extends Unit{ movement.y += ya*speed; movement.x += xa*speed; - boolean shooting = control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo(); + boolean shooting = isShooting(); if(shooting){ weapon.update(this, true); diff --git a/core/src/io/anuke/mindustry/entities/Unit.java b/core/src/io/anuke/mindustry/entities/Unit.java index 4a0fca1c52..ad369c166e 100644 --- a/core/src/io/anuke/mindustry/entities/Unit.java +++ b/core/src/io/anuke/mindustry/entities/Unit.java @@ -81,6 +81,10 @@ public abstract class Unit extends SyncEntity implements SerializableEntity { return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor()); } + public Team getTeam(){ + return team; + } + public void updateVelocityStatus(float drag, float maxVelocity){ Floor floor = getFloorOn(); Tile tile = world.tileWorld(x, y); diff --git a/core/src/io/anuke/mindustry/input/InputHandler.java b/core/src/io/anuke/mindustry/input/InputHandler.java index 3c31d54ea7..0e556d678f 100644 --- a/core/src/io/anuke/mindustry/input/InputHandler.java +++ b/core/src/io/anuke/mindustry/input/InputHandler.java @@ -154,8 +154,7 @@ public abstract class InputHandler extends InputAdapter{ } public boolean cursorNear(){ - return Vector2.dst(player.x, player.y, getBlockX() * tilesize, getBlockY() * tilesize) <= placerange || - state.mode.infiniteResources || debug; + return true; } public boolean tryPlaceBlock(int x, int y, boolean sound){ @@ -196,7 +195,7 @@ public abstract class InputHandler extends InputAdapter{ public void placeBlock(int x, int y, Block result, int rotation, boolean effects, boolean sound){ if(!Net.client()){ //is server or singleplayer - threads.run(() -> Placement.placeBlock(player.team, x, y, result, rotation, effects, sound)); + threads.run(() -> Placement.placeBlock(player, x, y, result, rotation, effects, sound)); } if(Net.active()){ diff --git a/core/src/io/anuke/mindustry/world/Placement.java b/core/src/io/anuke/mindustry/world/Placement.java index 5e52f3f036..1355547c96 100644 --- a/core/src/io/anuke/mindustry/world/Placement.java +++ b/core/src/io/anuke/mindustry/world/Placement.java @@ -5,9 +5,10 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.content.Recipes; import io.anuke.mindustry.content.blocks.Blocks; +import io.anuke.mindustry.content.fx.Fx; +import io.anuke.mindustry.entities.BlockPlacer; import io.anuke.mindustry.entities.Units; import io.anuke.mindustry.game.Team; -import io.anuke.mindustry.content.fx.Fx; import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; @@ -57,8 +58,9 @@ public class Placement { return block; } - public static void placeBlock(Team team, int x, int y, Block result, int rotation, boolean effects, boolean sound){ + public static void placeBlock(BlockPlacer placer, int x, int y, Block result, int rotation, boolean effects, boolean sound){ Tile tile = world.tile(x, y); + Team team = placer.getTeam(); //just in case if(tile == null) return; @@ -91,6 +93,8 @@ public class Placement { }else if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize); if(effects && sound) threads.run(() -> Effects.sound("place", x * tilesize, y * tilesize)); + + placer.addPlaceBlock(tile); } public static boolean validPlace(Team team, int x, int y, Block type, int rotation){ diff --git a/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java b/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java index 3a5d5fed80..d3bdf82977 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/BuildBlock.java @@ -7,12 +7,17 @@ import io.anuke.mindustry.game.Team; import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.world.Block; +import io.anuke.mindustry.world.BarType; +import io.anuke.mindustry.world.BlockBar; import io.anuke.mindustry.world.Tile; +import io.anuke.ucore.core.Effects; +import io.anuke.mindustry.content.fx.*; import io.anuke.ucore.core.Graphics; import io.anuke.ucore.graphics.Draw; +import io.anuke.mindustry.entities.effect.*; public class BuildBlock extends Block { - private static final float buildTime = 120f; + private static final float decaySpeedScl = 4f; public BuildBlock(String name) { super(name); @@ -23,6 +28,20 @@ public class BuildBlock extends Block { layer = Layer.placement; } + @Override + public void setBars(){ + bars.replace(new BlockBar(BarType.health, true, tile -> tile.entity().progress)); + } + + @Override + public void onDestroyed(Tile tile){ + Effects.effect(ExplosionFx.blockExplosionSmoke, tile); + + if(!tile.floor().solid && !tile.floor().liquid){ + Rubble.create(tile.drawx(), tile.drawy(), size); + } + } + @Override public void draw(Tile tile){ @@ -53,11 +72,13 @@ public class BuildBlock extends Block { @Override public void update(Tile tile) { BuildEntity entity = tile.entity(); - entity.progress += 1f/buildTime; + entity.progress -= 1f/entity.result.health/decaySpeedScl; if(entity.progress > 1f){ Team team = tile.getTeam(); tile.setBlock(entity.result); tile.setTeam(team); + }else if(entity.progress < 0f){ + entity.damage(entity.health + 1); } } @@ -68,6 +89,6 @@ public class BuildBlock extends Block { public class BuildEntity extends TileEntity{ public Block result; - public float progress; + public float progress = 0.05f; } }