Merging of map saves
This commit is contained in:
@@ -85,9 +85,8 @@ public class Damage{
|
||||
public static void collideLine(Bullet hitter, Team team, Effect effect, float x, float y, float angle, float length){
|
||||
tr.trns(angle, length);
|
||||
world.raycastEachWorld(x, y, x + tr.x, y + tr.y, (cx, cy) -> {
|
||||
Tile tile = world.tile(cx, cy);
|
||||
if(tile != null) tile = tile.target();
|
||||
if(tile != null && tile.entity != null && tile.target().getTeamID() != team.ordinal() && tile.entity.collide(hitter)){
|
||||
Tile tile = world.ltile(cx, cy);
|
||||
if(tile != null && tile.entity != null && tile.getTeamID() != team.ordinal() && tile.entity.collide(hitter)){
|
||||
tile.entity.collision(hitter);
|
||||
hitter.getBulletType().hit(hitter, tile.worldx(), tile.worldy());
|
||||
}
|
||||
@@ -216,12 +215,10 @@ public class Damage{
|
||||
int scaledDamage = (int)(damage * (1f - (float)dst / radius));
|
||||
|
||||
bits.set(bitOffset + x, bitOffset + y);
|
||||
Tile tile = world.tile(startx + x, starty + y);
|
||||
Tile tile = world.ltile(startx + x, starty + y);
|
||||
|
||||
if(scaledDamage <= 0 || tile == null) continue;
|
||||
|
||||
tile = tile.target();
|
||||
|
||||
//apply damage to entity if needed
|
||||
if(tile.entity != null && tile.getTeam() != team){
|
||||
int health = (int)tile.entity.health;
|
||||
|
||||
@@ -7,10 +7,11 @@ import io.anuke.arc.function.Consumer;
|
||||
import io.anuke.arc.function.Predicate;
|
||||
import io.anuke.arc.graphics.Camera;
|
||||
import io.anuke.arc.math.geom.Rectangle;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.traits.DrawTrait;
|
||||
import io.anuke.mindustry.entities.traits.Entity;
|
||||
|
||||
import static io.anuke.mindustry.Vars.collisions;
|
||||
|
||||
public class Entities{
|
||||
public static final int maxLeafObjects = 4;
|
||||
private static final Array<EntityGroup<?>> groupArray = new Array<>();
|
||||
@@ -48,7 +49,7 @@ public class Entities{
|
||||
group.updateEvents();
|
||||
|
||||
if(group.useTree()){
|
||||
Vars.collisions.updatePhysics(group);
|
||||
collisions.updatePhysics(group);
|
||||
}
|
||||
|
||||
for(Entity e : group.all()){
|
||||
|
||||
@@ -225,9 +225,8 @@ public class Bullet extends SolidEntity implements DamageTrait, ScaleTrait, Pool
|
||||
if(type.hitTiles && collidesTiles() && !supressCollision && initialized){
|
||||
world.raycastEach(world.toTile(lastPosition().x), world.toTile(lastPosition().y), world.toTile(x), world.toTile(y), (x, y) -> {
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
Tile tile = world.ltile(x, y);
|
||||
if(tile == null) return false;
|
||||
tile = tile.target();
|
||||
|
||||
if(tile.entity != null && tile.entity.collide(this) && type.collides(this, tile) && !tile.entity.isDead() && (type.collidesTeam || tile.getTeam() != team)){
|
||||
if(tile.getTeam() != team){
|
||||
|
||||
@@ -72,6 +72,11 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float lifetime(){
|
||||
return lifetime;
|
||||
@@ -98,7 +103,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
|
||||
return;
|
||||
}
|
||||
|
||||
TileEntity entity = tile.target().entity;
|
||||
TileEntity entity = tile.link().entity;
|
||||
boolean damage = entity != null;
|
||||
|
||||
float flammability = baseFlammability + puddleFlammability;
|
||||
@@ -151,7 +156,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
this.loadedPosition = stream.readInt();
|
||||
this.lifetime = stream.readFloat();
|
||||
this.time = stream.readFloat();
|
||||
|
||||
@@ -143,6 +143,11 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
|
||||
return liquid.flammability * amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hitbox(Rectangle rectangle){
|
||||
rectangle.setCenter(x, y).setSize(tilesize);
|
||||
@@ -201,7 +206,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
|
||||
}
|
||||
});
|
||||
|
||||
if(liquid.temperature > 0.7f && (tile.target().entity != null) && Mathf.chance(0.3 * Time.delta())){
|
||||
if(liquid.temperature > 0.7f && (tile.link().entity != null) && Mathf.chance(0.3 * Time.delta())){
|
||||
Fire.create(tile);
|
||||
}
|
||||
|
||||
@@ -245,7 +250,7 @@ public class Puddle extends SolidEntity implements SaveTrait, Poolable, DrawTrai
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
this.loadedPosition = stream.readInt();
|
||||
this.x = stream.readFloat();
|
||||
this.y = stream.readFloat();
|
||||
|
||||
@@ -40,10 +40,98 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
float placeDistance = 220f;
|
||||
float mineDistance = 70f;
|
||||
|
||||
//due to iOS wierdness
|
||||
class BuildDataStatic{
|
||||
static Array<BuildRequest> removal = new Array<>();
|
||||
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
||||
/**
|
||||
* Update building mechanism for this unit.
|
||||
* This includes mining.
|
||||
*/
|
||||
default void updateBuilding(){
|
||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
||||
Unit unit = (Unit)this;
|
||||
//remove already completed build requests
|
||||
removal.clear();
|
||||
for(BuildRequest req : getPlaceQueue()){
|
||||
removal.add(req);
|
||||
}
|
||||
|
||||
getPlaceQueue().clear();
|
||||
|
||||
for(BuildRequest request : removal){
|
||||
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
|
||||
(!request.breaking && (world.tile(request.x, request.y).rotation() == request.rotation || !request.block.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.block))){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
//update mining here
|
||||
if(current == null){
|
||||
if(getMineTile() != null){
|
||||
updateMining();
|
||||
}
|
||||
return;
|
||||
}else{
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(dst(tile) > finalPlaceDst){
|
||||
if(getPlaceQueue().size > 1){
|
||||
getPlaceQueue().removeFirst();
|
||||
getPlaceQueue().addLast(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
}else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
||||
Call.beginBreak(getTeam(), current.x, current.y);
|
||||
}else{
|
||||
getPlaceQueue().removeFirst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with or no build entity, stop building!
|
||||
if((core == null && !state.rules.infiniteResources) || !(tile.entity instanceof BuildEntity)){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity == null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(unit.dst(tile) <= finalPlaceDst){
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
//progress is synced, thus not updated clientside
|
||||
if(!Net.client()){
|
||||
//deconstructing is 2x as fast
|
||||
if(current.breaking){
|
||||
entity.deconstruct(unit, core, 2f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}
|
||||
|
||||
current.progress = entity.progress();
|
||||
}else{
|
||||
entity.progress = current.progress;
|
||||
}
|
||||
|
||||
if(!current.initialized){
|
||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
|
||||
current.initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the queue for storing build requests. */
|
||||
@@ -148,97 +236,10 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
return getPlaceQueue().size == 0 ? null : getPlaceQueue().first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update building mechanism for this unit.
|
||||
* This includes mining.
|
||||
*/
|
||||
default void updateBuilding(){
|
||||
Unit unit = (Unit)this;
|
||||
//remove already completed build requests
|
||||
removal.clear();
|
||||
for(BuildRequest req : getPlaceQueue()){
|
||||
removal.add(req);
|
||||
}
|
||||
|
||||
getPlaceQueue().clear();
|
||||
|
||||
for(BuildRequest request : removal){
|
||||
if(!((request.breaking && world.tile(request.x, request.y).block() == Blocks.air) ||
|
||||
(!request.breaking && (world.tile(request.x, request.y).getRotation() == request.rotation || !request.block.rotate)
|
||||
&& world.tile(request.x, request.y).block() == request.block))){
|
||||
getPlaceQueue().addLast(request);
|
||||
}
|
||||
}
|
||||
|
||||
BuildRequest current = getCurrentRequest();
|
||||
|
||||
//update mining here
|
||||
if(current == null){
|
||||
if(getMineTile() != null){
|
||||
updateMining();
|
||||
}
|
||||
return;
|
||||
}else{
|
||||
setMineTile(null);
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(dst(tile) > placeDistance){
|
||||
if(getPlaceQueue().size > 1){
|
||||
getPlaceQueue().removeFirst();
|
||||
getPlaceQueue().addLast(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
}else if(canCreateBlocks() && current.breaking && Build.validBreak(getTeam(), current.x, current.y)){
|
||||
Call.beginBreak(getTeam(), current.x, current.y);
|
||||
}else{
|
||||
getPlaceQueue().removeFirst();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
//if there is no core to build with or no build entity, stop building!
|
||||
if(core == null || !(tile.entity instanceof BuildEntity)){
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, update it.
|
||||
BuildEntity entity = tile.entity();
|
||||
|
||||
if(entity == null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(unit.dst(tile) <= placeDistance){
|
||||
unit.rotation = Mathf.slerpDelta(unit.rotation, unit.angleTo(entity), 0.4f);
|
||||
}
|
||||
|
||||
//progress is synced, thus not updated clientside
|
||||
if(!Net.client()){
|
||||
//deconstructing is 2x as fast
|
||||
if(current.breaking){
|
||||
entity.deconstruct(unit, core, 2f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}else{
|
||||
entity.construct(unit, core, 1f / entity.buildCost * Time.delta() * getBuildPower(tile) * state.rules.buildSpeedMultiplier);
|
||||
}
|
||||
|
||||
current.progress = entity.progress();
|
||||
}else{
|
||||
entity.progress = current.progress;
|
||||
}
|
||||
|
||||
if(!current.initialized){
|
||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
|
||||
current.initialized = true;
|
||||
}
|
||||
//due to iOS wierdness, this is apparently required
|
||||
class BuildDataStatic{
|
||||
static Array<BuildRequest> removal = new Array<>();
|
||||
static Vector2[] tmptr = new Vector2[]{new Vector2(), new Vector2(), new Vector2(), new Vector2()};
|
||||
}
|
||||
|
||||
/** Do not call directly. */
|
||||
@@ -291,7 +292,7 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
|
||||
if(dst(tile) > placeDistance){
|
||||
if(dst(tile) > placeDistance && !state.isEditor()){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@ package io.anuke.mindustry.entities.traits;
|
||||
* Marks an entity as serializable.
|
||||
*/
|
||||
public interface SaveTrait extends Entity, TypeTrait, Saveable{
|
||||
byte version();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,5 @@ import java.io.*;
|
||||
|
||||
public interface Saveable{
|
||||
void writeSave(DataOutput stream) throws IOException;
|
||||
|
||||
void readSave(DataInput stream) throws IOException;
|
||||
void readSave(DataInput stream, byte version) throws IOException;
|
||||
}
|
||||
|
||||
@@ -41,15 +41,6 @@ public interface SyncTrait extends Entity, TypeTrait{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Whether this entity is clipped and not synced when out of viewport. */
|
||||
default boolean isClipped(){
|
||||
return true;
|
||||
}
|
||||
|
||||
default float clipSize(){
|
||||
return (this instanceof DrawTrait ? ((DrawTrait)this).drawSize() : 8f);
|
||||
}
|
||||
|
||||
//Read and write sync data, usually position
|
||||
void write(DataOutput data) throws IOException;
|
||||
|
||||
|
||||
@@ -23,9 +23,7 @@ public interface TypeTrait{
|
||||
lastRegisteredID[0]++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a syncable type by ID.
|
||||
*/
|
||||
/**Gets a syncable type by ID.*/
|
||||
static Supplier<? extends TypeTrait> getTypeByID(int id){
|
||||
if(id == -1){
|
||||
throw new IllegalArgumentException("Attempt to retrieve invalid entity type ID! Did you forget to set it in ContentLoader.registerTypes()?");
|
||||
|
||||
@@ -306,11 +306,6 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
return type.hitsize * 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float clipSize(){
|
||||
return isBoss() ? 10000000000f : super.clipSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeath(){
|
||||
Call.onUnitDeath(this);
|
||||
@@ -338,6 +333,11 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
return unitGroups[team.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSave(DataOutput stream) throws IOException{
|
||||
super.writeSave(stream);
|
||||
@@ -346,8 +346,8 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
super.readSave(stream);
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
super.readSave(stream, version);
|
||||
byte type = stream.readByte();
|
||||
this.spawner = stream.readInt();
|
||||
|
||||
@@ -365,7 +365,9 @@ public abstract class BaseUnit extends Unit implements ShooterTrait{
|
||||
@Override
|
||||
public void read(DataInput data) throws IOException{
|
||||
float lastx = x, lasty = y, lastrot = rotation;
|
||||
super.readSave(data);
|
||||
|
||||
super.readSave(data, version());
|
||||
|
||||
this.type = content.getByID(ContentType.unit, data.readByte());
|
||||
this.spawner = data.readInt();
|
||||
|
||||
|
||||
@@ -432,7 +432,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
if(getCurrentRequest() == request && request.progress > 0.001f) continue;
|
||||
|
||||
if(request.breaking){
|
||||
Block block = world.tile(request.x, request.y).target().block();
|
||||
Block block = world.ltile(request.x, request.y).block();
|
||||
|
||||
//draw removal request
|
||||
Lines.stroke(2f, Pal.removeBack);
|
||||
@@ -636,13 +636,17 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
}
|
||||
|
||||
protected void updateShooting(){
|
||||
if(isShooting() && mech.canShoot(this)){
|
||||
if(!state.isEditor() && isShooting() && mech.canShoot(this)){
|
||||
mech.weapon.update(this, pointerX, pointerY);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateFlying(){
|
||||
if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity)target).damaged() && target.isValid() && ((TileEntity)target).isAdded() && target.getTeam() == team && mech.canHeal && dst(target) < getWeapon().bullet.range())){
|
||||
if(Units.invalidateTarget(target, this) && !(target instanceof TileEntity && ((TileEntity)target).damaged() && target.isValid() && target.getTeam() == team && mech.canHeal && dst(target) < getWeapon().bullet.range())){
|
||||
target = null;
|
||||
}
|
||||
|
||||
if(state.isEditor()){
|
||||
target = null;
|
||||
}
|
||||
|
||||
@@ -790,7 +794,11 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
|
||||
public void updateRespawning(){
|
||||
|
||||
if(spawner != null && spawner.isValid()){
|
||||
if(state.isEditor()){
|
||||
//instant respawn at center of map.
|
||||
set(world.width() * tilesize/2f, world.height() * tilesize/2f);
|
||||
setDead(false);
|
||||
}else if(spawner != null && spawner.isValid()){
|
||||
spawner.updateSpawning(this);
|
||||
}else if(!netServer.isWaitingForPlayers()){
|
||||
if(!Net.client()){
|
||||
@@ -817,8 +825,8 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
//region read and write methods
|
||||
|
||||
@Override
|
||||
public boolean isClipped(){
|
||||
return false;
|
||||
public byte version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -833,7 +841,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
boolean local = stream.readBoolean();
|
||||
|
||||
if(local){
|
||||
@@ -844,14 +852,14 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
lastSpawner = (SpawnerTrait)stile.entity;
|
||||
}
|
||||
Player player = headless ? this : Vars.player;
|
||||
player.readSaveSuper(stream);
|
||||
player.readSaveSuper(stream, version);
|
||||
player.mech = content.getByID(ContentType.mech, mechid);
|
||||
player.dead = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void readSaveSuper(DataInput stream) throws IOException{
|
||||
super.readSave(stream);
|
||||
private void readSaveSuper(DataInput stream, byte version) throws IOException{
|
||||
super.readSave(stream, version);
|
||||
|
||||
add();
|
||||
}
|
||||
@@ -859,7 +867,7 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
@Override
|
||||
public void write(DataOutput buffer) throws IOException{
|
||||
super.writeSave(buffer, !isLocal);
|
||||
TypeIO.writeStringData(buffer, name); //TODO writing strings is very inefficient
|
||||
TypeIO.writeStringData(buffer, name);
|
||||
buffer.writeByte(Pack.byteValue(isAdmin) | (Pack.byteValue(dead) << 1) | (Pack.byteValue(isBoosting) << 2) | (Pack.byteValue(isTyping) << 3));
|
||||
buffer.writeInt(Color.rgba8888(color));
|
||||
buffer.writeByte(mech.id);
|
||||
@@ -873,7 +881,9 @@ public class Player extends Unit implements BuilderTrait, ShooterTrait{
|
||||
@Override
|
||||
public void read(DataInput buffer) throws IOException{
|
||||
float lastx = x, lasty = y, lastrot = rotation, lastvx = velocity.x, lastvy = velocity.y;
|
||||
super.readSave(buffer);
|
||||
|
||||
super.readSave(buffer, version());
|
||||
|
||||
name = TypeIO.readStringData(buffer);
|
||||
byte bools = buffer.readByte();
|
||||
isAdmin = (bools & 1) != 0;
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package io.anuke.mindustry.entities.type;
|
||||
|
||||
import io.anuke.annotations.Annotations.Loc;
|
||||
import io.anuke.annotations.Annotations.Remote;
|
||||
import io.anuke.annotations.Annotations.*;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.collection.Array;
|
||||
import io.anuke.arc.collection.ObjectSet;
|
||||
import io.anuke.arc.math.geom.Point2;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.util.Interval;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.mindustry.entities.EntityGroup;
|
||||
import io.anuke.mindustry.entities.bullet.Bullet;
|
||||
import io.anuke.mindustry.entities.impl.BaseEntity;
|
||||
@@ -115,16 +113,35 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
return dead || tile.entity != this;
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
public void write(DataOutput stream) throws IOException{
|
||||
stream.writeShort((short)health);
|
||||
stream.writeByte(Pack.byteByte(tile.getTeamID(), tile.rotation())); //team + rotation
|
||||
if(items != null) items.write(stream);
|
||||
if(power != null) power.write(stream);
|
||||
if(liquids != null) liquids.write(stream);
|
||||
if(cons != null) cons.write(stream);
|
||||
}
|
||||
|
||||
public void writeConfig(DataOutput stream) throws IOException{
|
||||
@CallSuper
|
||||
public void read(DataInput stream, byte revision) throws IOException{
|
||||
health = stream.readUnsignedShort();
|
||||
byte tr = stream.readByte();
|
||||
byte team = Pack.leftByte(tr);
|
||||
byte rotation = Pack.rightByte(tr);
|
||||
|
||||
tile.setTeam(Team.all[team]);
|
||||
tile.rotation(rotation);
|
||||
|
||||
if(items != null) items.read(stream);
|
||||
if(power != null) power.read(stream);
|
||||
if(liquids != null) liquids.read(stream);
|
||||
if(cons != null) cons.read(stream);
|
||||
}
|
||||
|
||||
public void read(DataInput stream) throws IOException{
|
||||
}
|
||||
|
||||
public void readConfig(DataInput stream) throws IOException{
|
||||
/** Returns the version of this TileEntity IO code.*/
|
||||
public byte version(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean collide(Bullet other){
|
||||
@@ -168,14 +185,14 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
|
||||
Point2[] nearby = Edges.getEdges(block.size);
|
||||
for(Point2 point : nearby){
|
||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
|
||||
//remove this tile from all nearby tile's proximities
|
||||
if(other != null){
|
||||
other = other.target();
|
||||
other.block().onProximityUpdate(other);
|
||||
}
|
||||
if(other != null && other.entity != null){
|
||||
other.entity.proximity.removeValue(tile, true);
|
||||
|
||||
if(other.entity != null){
|
||||
other.entity.proximity.removeValue(tile, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,10 +203,9 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
|
||||
Point2[] nearby = Edges.getEdges(block.size);
|
||||
for(Point2 point : nearby){
|
||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||
Tile other = world.ltile(tile.x + point.x, tile.y + point.y);
|
||||
|
||||
if(other == null) continue;
|
||||
other = other.target();
|
||||
if(other.entity == null || !(other.interactable(tile.getTeam()))) continue;
|
||||
|
||||
other.block().onProximityUpdate(other);
|
||||
@@ -280,6 +296,11 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(){
|
||||
return !isDead() && tile.entity == this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityGroup targetGroup(){
|
||||
return tileGroup;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.entities.type;
|
||||
|
||||
import io.anuke.annotations.Annotations.Nullable;
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.Events;
|
||||
import io.anuke.arc.graphics.Color;
|
||||
@@ -8,7 +9,8 @@ import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.arc.math.geom.Geometry;
|
||||
import io.anuke.arc.math.geom.Vector2;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.Time;
|
||||
import io.anuke.arc.util.Tmp;
|
||||
import io.anuke.mindustry.content.Blocks;
|
||||
import io.anuke.mindustry.content.Fx;
|
||||
import io.anuke.mindustry.entities.*;
|
||||
@@ -138,7 +140,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
byte team = stream.readByte();
|
||||
boolean dead = stream.readBoolean();
|
||||
float x = stream.readFloat();
|
||||
@@ -150,7 +152,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
byte itemID = stream.readByte();
|
||||
short itemAmount = stream.readShort();
|
||||
|
||||
this.status.readSave(stream);
|
||||
this.status.readSave(stream, version);
|
||||
this.item.amount = itemAmount;
|
||||
this.item.item = content.item(itemID);
|
||||
this.dead = dead;
|
||||
@@ -221,7 +223,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
velocity.add(moveVector.x / mass() * Time.delta(), moveVector.y / mass() * Time.delta());
|
||||
}
|
||||
|
||||
public TileEntity getClosestCore(){
|
||||
public @Nullable TileEntity getClosestCore(){
|
||||
TeamData data = state.teams.get(team);
|
||||
|
||||
Tile tile = Geometry.findClosest(x, y, data.cores);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class Drone extends FlyingUnit implements BuilderTrait{
|
||||
if(isBreaking){
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y));
|
||||
}else{
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.getRotation(), entity.cblock));
|
||||
getPlaceQueue().addLast(new BuildRequest(entity.tile.x, entity.tile.y, entity.tile.rotation(), entity.cblock));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public class Statuses implements Saveable{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSave(DataInput stream) throws IOException{
|
||||
public void readSave(DataInput stream, byte version) throws IOException{
|
||||
for(StatusEntry effect : statuses){
|
||||
Pools.free(effect);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user