Fixed player dupes, new breaking system, multiplayer block edits
This commit is contained in:
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user