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) -> {
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) {

View File

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

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

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());
}
public Team getTeam(){
return team;
}
public void updateVelocityStatus(float drag, float maxVelocity){
Floor floor = getFloorOn();
Tile tile = world.tileWorld(x, y);

View File

@ -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()){

View File

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

View File

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