Fixed player dupes, new breaking system, multiplayer block edits

This commit is contained in:
Anuken
2018-06-09 23:23:14 -04:00
parent d5a58be440
commit aca1001f9a
22 changed files with 533 additions and 224 deletions
@@ -2,7 +2,6 @@ package io.anuke.mindustry.entities;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.math.GridPoint2;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pools;
@@ -23,6 +22,7 @@ import io.anuke.mindustry.graphics.Palette;
import io.anuke.mindustry.graphics.Trail;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.type.*;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.storage.CoreBlock.CoreEntity;
@@ -30,9 +30,11 @@ import io.anuke.ucore.core.*;
import io.anuke.ucore.entities.EntityGroup;
import io.anuke.ucore.entities.trait.SolidTrait;
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.Angles;
import io.anuke.ucore.util.Mathf;
import io.anuke.ucore.util.ThreadQueue;
import io.anuke.ucore.util.Timer;
import java.io.DataInput;
import java.io.DataOutput;
@@ -57,7 +59,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
public String name = "name";
public String uuid;
public boolean isAdmin;
public boolean isAdmin, isTransferring;
public Color color = new Color();
public Array<Upgrade> upgrades = new Array<>();
@@ -342,28 +344,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
for (BuildRequest request : getPlaceQueue()) {
if(request.remove){
Block block = world.tile(request.x, request.y).target().block();
//draw removal request
Draw.color(Palette.remove);
Draw.alpha(0.4f);
Lines.stroke(1f);
Draw.color(Palette.remove);
float progress = request.progress;
Tile tile = world.tile(request.x, request.y);
float size = tile.block().size * tilesize/2f;
float ss = -(progress*2f-1f);
Lines.stroke((1f-request.progress));
for(int i = 0; i < 4; i ++){
GridPoint2 p = Geometry.d8edge(i);
Fill.tri(tile.drawx() + size*p.x, tile.drawy() + size * p.y,
tile.drawx() + size*p.x*ss, tile.drawy() + size * p.y,
tile.drawx() + size*p.x, tile.drawy() + size * p.y*ss);
}
Draw.alpha(1f);
Lines.poly(tile.drawx(), tile.drawy(),
4, tile.block().size * tilesize /2f * (1f-progress) + Mathf.absin(Timers.time(), 3f, 1f));
Lines.poly(request.x * tilesize + block.offset(),
request.y * tilesize + block.offset(),
4, block.size * tilesize /2f, 45 + 15);
}else{
//draw place request
Draw.color(Palette.accent);
@@ -398,6 +388,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
if(!isLocal){
interpolate();
updateBuilding(this); //building happens even with non-locals
return;
}
@@ -651,6 +642,11 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
mech = Upgrade.getByID(buffer.readByte());
interpolator.read(lastx, lasty, x, y, time, rotation);
rotation = lastrot;
if(isLocal){
x = lastx;
y = lasty;
}
}
//endregion
@@ -1,10 +1,14 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.math.Vector2;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.content.fx.Fx;
import io.anuke.mindustry.entities.bullet.Bullet;
import io.anuke.mindustry.entities.traits.TargetTrait;
import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.CallBlocks;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Wall;
@@ -92,7 +96,7 @@ public class TileEntity extends BaseEntity implements TargetTrait {
public void write(DataOutputStream stream) throws IOException{}
public void read(DataInputStream stream) throws IOException{}
public void onDeath(){
private void onDeath(){
if(!dead) {
dead = true;
Block block = tile.block();
@@ -102,7 +106,6 @@ public class TileEntity extends BaseEntity implements TargetTrait {
block.afterDestroyed(tile, this);
remove();
}
}
public boolean collide(Bullet other){
@@ -115,10 +118,12 @@ public class TileEntity extends BaseEntity implements TargetTrait {
public void damage(float damage){
if(dead) return;
float amount = tile.block().handleDamage(tile, damage);
health -= amount;
if(health <= 0) onDeath();
CallBlocks.onTileDamage(tile, health - tile.block().handleDamage(tile, damage));
if(health <= 0){
CallBlocks.onTileDestroyed(tile);
}
}
@Override
@@ -153,4 +158,14 @@ public class TileEntity extends BaseEntity implements TargetTrait {
public EntityGroup targetGroup() {
return tileGroup;
}
@Remote(called = Loc.server, in = In.blocks)
public static void onTileDamage(Tile tile, float health){
tile.entity.health = health;
}
@Remote(called = Loc.server, in = In.blocks)
public static void onTileDestroyed(Tile tile){
tile.entity.onDeath();
}
}
@@ -1,6 +1,7 @@
package io.anuke.mindustry.entities;
import com.badlogic.gdx.utils.Array;
import io.anuke.mindustry.content.Items;
import io.anuke.mindustry.type.AmmoEntry;
import io.anuke.mindustry.type.AmmoType;
import io.anuke.mindustry.type.Item;
@@ -11,7 +12,7 @@ import java.io.*;
public class UnitInventory {
private Array<AmmoEntry> ammos = new Array<>();
private int totalAmmo;
private ItemStack item;
private ItemStack item = new ItemStack(Items.stone, 0);
//TODO move these somewhere else so they're not variables?
private int capacity, ammoCapacity;
private boolean infiniteAmmo;
@@ -30,32 +31,31 @@ public class UnitInventory {
}
public void write(DataOutput stream) throws IOException {
stream.writeInt(item == null ? 0 : item.amount);
stream.writeByte(item == null ? 0 : item.item.id);
stream.writeShort(item.amount);
stream.writeByte(item.item.id);
stream.writeBoolean(infiniteAmmo);
stream.writeInt(totalAmmo);
stream.writeShort(totalAmmo);
stream.writeByte(ammos.size);
for(int i = 0; i < ammos.size; i ++){
stream.writeByte(ammos.get(i).type.id);
stream.writeInt(ammos.get(i).amount);
stream.writeShort(ammos.get(i).amount);
}
}
public void read(DataInput stream) throws IOException {
int iamount = stream.readInt();
short iamount = stream.readShort();
byte iid = stream.readByte();
infiniteAmmo = stream.readBoolean();
this.totalAmmo = stream.readInt();
this.totalAmmo = stream.readShort();
byte ammoa = stream.readByte();
for(int i = 0; i < ammoa; i ++){
byte aid = stream.readByte();
int am = stream.readInt();
int am = stream.readShort();
ammos.add(new AmmoEntry(AmmoType.getByID(aid), am));
}
if(iamount != 0){
item = new ItemStack(Item.getByID(iid), iamount);
}
item.item = Item.getByID(iid);
item.amount = iamount;
}
/**Returns ammo range, or MAX_VALUE if this inventory has no ammo.*/
@@ -116,7 +116,7 @@ public class UnitInventory {
}
public boolean isEmpty(){
return item == null;
return item.amount == 0;
}
public int itemCapacityUsed(Item type){
@@ -136,30 +136,29 @@ public class UnitInventory {
}
public void clear(){
item = null;
item.amount = 0;
ammos.clear();
totalAmmo = 0;
}
public void clearItem(){
item = null;
item.amount = 0;
}
public boolean hasItem(){
return item != null;
return item.amount > 0;
}
public boolean hasItem(Item i, int amount){
return item.item == i && item.amount >= amount;
}
public void addItem(Item item, int amount){
if(hasItem()){
getItem().amount = getItem().item == item ? getItem().amount + amount : amount;
getItem().item = item;
}else{
this.item = new ItemStack(item, amount);
}
getItem().amount = getItem().item == item ? getItem().amount + amount : amount;
getItem().item = item;
}
public ItemStack getItem(){
if(!hasItem()) throw new RuntimeException("This inventory has no item! Check hasItem() first.");
return item;
}
}
@@ -4,8 +4,12 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Pool.Poolable;
import com.badlogic.gdx.utils.Pools;
import io.anuke.annotations.Annotations.Loc;
import io.anuke.annotations.Annotations.Remote;
import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.entities.traits.SyncTrait;
import io.anuke.mindustry.gen.CallEntity;
import io.anuke.mindustry.net.In;
import io.anuke.mindustry.net.Interpolator;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
@@ -24,9 +28,7 @@ import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import static io.anuke.mindustry.Vars.itemGroup;
import static io.anuke.mindustry.Vars.itemSize;
import static io.anuke.mindustry.Vars.world;
import static io.anuke.mindustry.Vars.*;
public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait, VelocityTrait, TimeTrait, Poolable {
private static final float sinkLifetime = 80f;
@@ -50,6 +52,11 @@ public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait, Veloc
return drop;
}
@Remote(called = Loc.server, in = In.entities)
public static void onPickup(int itemid){
itemGroup.removeByID(itemid);
}
/**Internal use only!*/
public ItemDrop(){
hitbox.setSize(5f);
@@ -86,7 +93,7 @@ public class ItemDrop extends SolidEntity implements SyncTrait, DrawTrait, Veloc
Player player = (Player)other;
if(player.inventory.canAcceptItem(item, amount)){
player.inventory.addItem(item, amount);
remove();
CallEntity.onPickup(getID());
}
}
@@ -16,6 +16,8 @@ import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.type.Recipe;
import io.anuke.mindustry.world.Build;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.BreakBlock;
import io.anuke.mindustry.world.blocks.BreakBlock.BreakEntity;
import io.anuke.mindustry.world.blocks.BuildBlock;
import io.anuke.mindustry.world.blocks.BuildBlock.BuildEntity;
import io.anuke.ucore.core.Effects;
@@ -113,6 +115,7 @@ public interface BuilderTrait {
if(unit.distanceTo(tile) > placeDistance) { //out of range, skip it.
getPlaceQueue().removeFirst();
}else if(current.remove){
/*
if(Build.validBreak(unit.getTeam(), current.x, current.y) && current.recipe == Recipe.getByResult(tile.block())){ //if it's valid, break it
float progress = 1f / tile.getBreakTime() * Timers.delta() * getBuildPower(tile);
@@ -138,18 +141,43 @@ public interface BuilderTrait {
if(current.progress >= 1f){
//FIXME a player instace is required here, but the the builder may not be a player
CallBlocks.breakBlock(unit instanceof Player ? (Player)unit : null, unit.getTeam(), current.x, current.y, true, true);
CallBlocks.breakBlock((Player)unit, unit.getTeam(), current.x, current.y, true, true);
}
}else{
//otherwise, skip it
getPlaceQueue().removeFirst();
}*/
if (!(tile.block() instanceof BreakBlock)) { //check if haven't started placing
if(Build.validBreak(unit.getTeam(), current.x, current.y)){
//if it's valid, place it
//FIXME a player instance is required here, but the the builder may not be a player
CallBlocks.breakBlock((Player)unit, unit.getTeam(), current.x, current.y);
}else{
//otherwise, skip it
getPlaceQueue().removeFirst();
}
}else{
TileEntity core = unit.getClosestCore();
//if there is no core to build with, stop building!
if(core == null){
return;
}
//otherwise, update it.
BreakEntity entity = tile.entity();
entity.addProgress(core, unit, 1f / entity.breakTime * Timers.delta() * getBuildPower(tile));
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
getCurrentRequest().progress = entity.progress();
}
}else{
if (!(tile.block() instanceof BuildBlock)) { //check if haven't started placing
if(Build.validPlace(unit.getTeam(), current.x, current.y, current.recipe.result, current.rotation)){
//if it's valid, place it
//FIXME a player instace is required here, but the the builder may not be a player
CallBlocks.placeBlock(unit instanceof Player ? (Player)unit : null, unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
//FIXME a player instance is required here, but the the builder may not be a player
CallBlocks.placeBlock((Player)unit, unit.getTeam(), current.x, current.y, current.recipe, current.rotation);
//fire build event
threads.run(() -> Events.fire(BlockBuildEvent.class, unit.getTeam(), world.tile(current.x, current.y)));
@@ -278,8 +306,6 @@ public interface BuilderTrait {
public float progress;
private float[] removeAccumulator;
/**This creates a build request.*/
public BuildRequest(int x, int y, int rotation, Recipe recipe) {
this.x = x;
@@ -296,10 +322,6 @@ public interface BuilderTrait {
this.rotation = -1;
this.recipe = Recipe.getByResult(world.tile(x, y).block());
this.remove = true;
if(this.recipe != null){
this.removeAccumulator = new float[recipe.requirements.length];
}
}
}
}