Added unit-based block building with effects

This commit is contained in:
Anuken
2018-05-16 12:54:36 -07:00
parent e2f74fd4f0
commit a889571b98
9 changed files with 123 additions and 12 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

View File

@@ -164,7 +164,7 @@ public class NetClient extends Module {
Net.handleClient(PlacePacket.class, (packet) -> { Net.handleClient(PlacePacket.class, (packet) -> {
Player placer = playerGroup.getByID(packet.playerid); 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) { for(Player player : players) {
if (packet.playerid == player.id) { if (packet.playerid == player.id) {

View File

@@ -214,7 +214,7 @@ public class NetServer extends Module{
state.inventory.removeItems(recipe.requirements); 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)); TraceInfo trace = admins.getTraceByID(getUUID(id));

View File

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

View File

@@ -3,6 +3,7 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.content.Mechs; import io.anuke.mindustry.content.Mechs;
import io.anuke.mindustry.content.Weapons; import io.anuke.mindustry.content.Weapons;
import io.anuke.mindustry.content.fx.ExplosionFx; 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.net.NetEvents;
import io.anuke.mindustry.resource.*; import io.anuke.mindustry.resource.*;
import io.anuke.mindustry.world.Tile; 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.mindustry.world.blocks.types.Floor;
import io.anuke.ucore.core.Effects; import io.anuke.ucore.core.Effects;
import io.anuke.ucore.core.Inputs; 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.core.Timers;
import io.anuke.ucore.entities.SolidEntity; import io.anuke.ucore.entities.SolidEntity;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.graphics.Fill;
import io.anuke.ucore.graphics.Lines;
import io.anuke.ucore.util.*; import io.anuke.ucore.util.*;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
import static io.anuke.mindustry.Vars.*; 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 speed = 1.1f;
static final float dashSpeed = 1.8f; static final float dashSpeed = 1.8f;
static final float placeDistance = 80f;
static final int maxPlacing = 5;
static final int timerDash = 0; static final int timerDash = 0;
static final int timerRegen = 3; static final int timerRegen = 3;
static final Translator[] tmptr = {new Translator(), new Translator(), new Translator(), new Translator()};
public String name = "name"; public String name = "name";
public String uuid; public String uuid;
@@ -55,6 +64,7 @@ public class Player extends Unit{
public float walktime; public float walktime;
public float respawntime; public float respawntime;
private Array<Tile> placeBlocks = new Array<>();
private Vector2 movement = new Vector2(); private Vector2 movement = new Vector2();
public Player(){ 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 @Override
public boolean collides(SolidEntity other){ public boolean collides(SolidEntity other){
return !isDead() && super.collides(other) && !mech.flying; return !isDead() && super.collides(other) && !mech.flying;
@@ -208,6 +225,47 @@ public class Player extends Unit{
x = px; x = px;
y = py; 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 @Override
public void update(){ public void update(){
@@ -253,6 +311,10 @@ public class Player extends Unit{
heal(); heal();
} }
public boolean isShooting(){
return control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo();
}
protected void updateMech(){ protected void updateMech(){
Tile tile = world.tileWorld(x, y); Tile tile = world.tileWorld(x, y);
@@ -262,6 +324,18 @@ public class Player extends Unit{
damage(health + 1); //die instantly 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; if(ui.chatfrag.chatOpen()) return;
dashing = Inputs.keyDown("dash"); dashing = Inputs.keyDown("dash");
@@ -289,7 +363,7 @@ public class Player extends Unit{
movement.y += ya*speed; movement.y += ya*speed;
movement.x += xa*speed; movement.x += xa*speed;
boolean shooting = control.input(playerIndex).canShoot() && control.input(playerIndex).isShooting() && inventory.hasAmmo(); boolean shooting = isShooting();
if(shooting){ if(shooting){
weapon.update(this, true); weapon.update(this, true);

View File

@@ -81,6 +81,10 @@ public abstract class Unit extends SyncEntity implements SerializableEntity {
return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor()); return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor());
} }
public Team getTeam(){
return team;
}
public void updateVelocityStatus(float drag, float maxVelocity){ public void updateVelocityStatus(float drag, float maxVelocity){
Floor floor = getFloorOn(); Floor floor = getFloorOn();
Tile tile = world.tileWorld(x, y); Tile tile = world.tileWorld(x, y);

View File

@@ -154,8 +154,7 @@ public abstract class InputHandler extends InputAdapter{
} }
public boolean cursorNear(){ public boolean cursorNear(){
return Vector2.dst(player.x, player.y, getBlockX() * tilesize, getBlockY() * tilesize) <= placerange || return true;
state.mode.infiniteResources || debug;
} }
public boolean tryPlaceBlock(int x, int y, boolean sound){ 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){ public void placeBlock(int x, int y, Block result, int rotation, boolean effects, boolean sound){
if(!Net.client()){ //is server or singleplayer 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()){ if(Net.active()){

View File

@@ -5,9 +5,10 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Recipes; import io.anuke.mindustry.content.Recipes;
import io.anuke.mindustry.content.blocks.Blocks; 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.entities.Units;
import io.anuke.mindustry.game.Team; import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.resource.ItemStack; import io.anuke.mindustry.resource.ItemStack;
import io.anuke.mindustry.resource.Recipe; import io.anuke.mindustry.resource.Recipe;
import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity; import io.anuke.mindustry.world.blocks.types.BuildBlock.BuildEntity;
@@ -57,8 +58,9 @@ public class Placement {
return block; 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); Tile tile = world.tile(x, y);
Team team = placer.getTeam();
//just in case //just in case
if(tile == null) return; if(tile == null) return;
@@ -91,6 +93,8 @@ public class Placement {
}else if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize); }else if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize);
if(effects && sound) threads.run(() -> Effects.sound("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){ public static boolean validPlace(Team team, int x, int y, Block type, int rotation){

View File

@@ -7,12 +7,17 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.graphics.Layer; import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.graphics.Shaders; import io.anuke.mindustry.graphics.Shaders;
import io.anuke.mindustry.world.Block; 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.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.core.Graphics;
import io.anuke.ucore.graphics.Draw; import io.anuke.ucore.graphics.Draw;
import io.anuke.mindustry.entities.effect.*;
public class BuildBlock extends Block { public class BuildBlock extends Block {
private static final float buildTime = 120f; private static final float decaySpeedScl = 4f;
public BuildBlock(String name) { public BuildBlock(String name) {
super(name); super(name);
@@ -23,6 +28,20 @@ public class BuildBlock extends Block {
layer = Layer.placement; layer = Layer.placement;
} }
@Override
public void setBars(){
bars.replace(new BlockBar(BarType.health, true, tile -> tile.<BuildEntity>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 @Override
public void draw(Tile tile){ public void draw(Tile tile){
@@ -53,11 +72,13 @@ public class BuildBlock extends Block {
@Override @Override
public void update(Tile tile) { public void update(Tile tile) {
BuildEntity entity = tile.entity(); BuildEntity entity = tile.entity();
entity.progress += 1f/buildTime; entity.progress -= 1f/entity.result.health/decaySpeedScl;
if(entity.progress > 1f){ if(entity.progress > 1f){
Team team = tile.getTeam(); Team team = tile.getTeam();
tile.setBlock(entity.result); tile.setBlock(entity.result);
tile.setTeam(team); 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 class BuildEntity extends TileEntity{
public Block result; public Block result;
public float progress; public float progress = 0.05f;
} }
} }