Fixed many various bugs with syncing things
This commit is contained in:
@@ -189,12 +189,16 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
|
||||
@Remote(in = In.entities, targets = Loc.server, called = Loc.server)
|
||||
public static void onPlayerDamage(Player player, float amount){
|
||||
if(player == null) return;
|
||||
|
||||
player.hitTime = hitDuration;
|
||||
player.health -= amount;
|
||||
}
|
||||
|
||||
@Remote(in = In.entities, targets = Loc.server, called = Loc.server)
|
||||
public static void onPlayerDeath(Player player){
|
||||
if(player == null) return;
|
||||
|
||||
player.dead = true;
|
||||
player.respawning = false;
|
||||
player.placeQueue.clear();
|
||||
@@ -393,6 +397,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait {
|
||||
if(!isLocal){
|
||||
interpolate();
|
||||
updateBuilding(this); //building happens even with non-locals
|
||||
status.update(this); //status effect updating also happens with non locals for effect purposes
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,7 @@ public abstract class Unit extends DestructibleEntity implements SaveTrait, Targ
|
||||
return (Floor)(tile == null || (tile.floor() == null) ? Blocks.defaultFloor : tile.floor());
|
||||
}
|
||||
|
||||
/**Updates velocity and status effects.*/
|
||||
public void updateVelocityStatus(float drag, float maxVelocity){
|
||||
if(isCarried()){ //carried units do not take into account velocity normally
|
||||
set(carrier.getX(), carrier.getY());
|
||||
|
||||
@@ -52,6 +52,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
||||
fire = Pools.obtain(Fire.class);
|
||||
fire.tile = tile;
|
||||
fire.lifetime = baseLifetime;
|
||||
fire.set(tile.worldx(), tile.worldy());
|
||||
fire.add();
|
||||
map.put(tile.packedPosition(), fire);
|
||||
}else{
|
||||
@@ -72,7 +73,7 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
||||
|
||||
@Override
|
||||
public int getTypeID() {
|
||||
return 0;
|
||||
return typeID;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,11 +84,11 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
||||
@Override
|
||||
public void update() {
|
||||
if(Mathf.chance(0.1 * Timers.delta())) {
|
||||
Effects.effect(EnvironmentFx.fire, tile.worldx() + Mathf.range(4f), tile.worldy() + Mathf.range(4f));
|
||||
Effects.effect(EnvironmentFx.fire, x + Mathf.range(4f), y + Mathf.range(4f));
|
||||
}
|
||||
|
||||
if(Mathf.chance(0.05 * Timers.delta())){
|
||||
Effects.effect(EnvironmentFx.smoke, tile.worldx() + Mathf.range(4f), tile.worldy() + Mathf.range(4f));
|
||||
Effects.effect(EnvironmentFx.smoke, x + Mathf.range(4f), y + Mathf.range(4f));
|
||||
}
|
||||
|
||||
if(Net.client()){
|
||||
@@ -136,7 +137,11 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
||||
if(damage){
|
||||
entity.damage(0.4f);
|
||||
}
|
||||
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, unit -> unit.applyEffect(StatusEffects.burning, 0.8f));
|
||||
Damage.damageUnits(null, tile.worldx(), tile.worldy(), tilesize, 3f, unit -> {
|
||||
if(!unit.isFlying()) {
|
||||
unit.applyEffect(StatusEffects.burning, 0.8f);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +191,9 @@ public class Fire extends TimedEntity implements SaveTrait, SyncTrait, Poolable
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
map.remove(tile.packedPosition());
|
||||
if(tile != null){
|
||||
map.remove(tile.packedPosition());
|
||||
}
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public class ItemTransfer extends TimedEntity implements DrawTrait{
|
||||
|
||||
@Remote(in = In.entities, called = Loc.server, unreliable = true)
|
||||
public static void transferAmmo(Item item, float x, float y, Unit to){
|
||||
if(to == null) return;
|
||||
to.addAmmo(item);
|
||||
create(item, x, y, to, () -> {});
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
import static io.anuke.mindustry.Vars.puddleGroup;
|
||||
import static io.anuke.mindustry.Vars.world;
|
||||
|
||||
public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait, SyncTrait {
|
||||
private static final IntMap<Puddle> map = new IntMap<>();
|
||||
@@ -52,6 +53,7 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
||||
|
||||
private int loadedPosition = -1;
|
||||
|
||||
private float updateTime;
|
||||
private Tile tile;
|
||||
private Liquid liquid;
|
||||
private float amount, targetAmount;
|
||||
@@ -145,14 +147,46 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if(amount >= maxLiquid/2f && Timers.get(this, "update", 20)){
|
||||
|
||||
//no updating happens clientside
|
||||
if(Net.client()){
|
||||
amount = Mathf.lerpDelta(amount, targetAmount, 0.15f);
|
||||
}else{
|
||||
//update code
|
||||
float addSpeed = accepting > 0 ? 3f : 0f;
|
||||
|
||||
amount -= Timers.delta() * (1f - liquid.viscosity) / (5f + addSpeed);
|
||||
|
||||
amount += accepting;
|
||||
accepting = 0f;
|
||||
|
||||
if (amount >= maxLiquid / 1.5f && generation < maxGeneration) {
|
||||
float deposited = Math.min((amount - maxLiquid / 1.5f) / 4f, 0.3f) * Timers.delta();
|
||||
for (GridPoint2 point : Geometry.d4) {
|
||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||
if (other.block() == Blocks.air) {
|
||||
deposit(other, tile, liquid, deposited, generation + 1);
|
||||
amount -= deposited / 4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amount = Mathf.clamp(amount, 0, maxLiquid);
|
||||
|
||||
if (amount <= 0f) {
|
||||
CallEntity.onPuddleRemoved(getID());
|
||||
}
|
||||
}
|
||||
|
||||
//effects-only code
|
||||
if(amount >= maxLiquid/2f && updateTime <= 0f){
|
||||
Units.getNearby(rect.setSize(Mathf.clamp(amount/(maxLiquid/1.5f))*10f).setCenter(x, y), unit -> {
|
||||
unit.getHitbox(rect2);
|
||||
if(!rect.overlaps(rect2)) return;
|
||||
|
||||
unit.applyEffect(liquid.effect, 0.5f);
|
||||
|
||||
if(unit.getVelocity().len() > 0.4) {
|
||||
if(unit.getVelocity().len() > 0.1) {
|
||||
Effects.effect(BlockFx.ripple, liquid.color, unit.x, unit.y);
|
||||
}
|
||||
});
|
||||
@@ -160,37 +194,11 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
||||
if(liquid.temperature > 0.7f && tile.entity != null && Mathf.chance(0.3 * Timers.delta())){
|
||||
Fire.create(tile);
|
||||
}
|
||||
|
||||
updateTime = 20f;
|
||||
}
|
||||
|
||||
//no updating happens clientside
|
||||
if(Net.client()){
|
||||
amount = Mathf.lerpDelta(amount, targetAmount, 0.15f);
|
||||
return;
|
||||
}
|
||||
|
||||
float addSpeed = accepting > 0 ? 3f : 0f;
|
||||
|
||||
amount -= Timers.delta() * (1f - liquid.viscosity) /(5f+addSpeed);
|
||||
|
||||
amount += accepting;
|
||||
accepting = 0f;
|
||||
|
||||
if(amount >= maxLiquid/1.5f && generation < maxGeneration){
|
||||
float deposited = Math.min((amount - maxLiquid/1.5f)/4f, 0.3f) * Timers.delta();
|
||||
for(GridPoint2 point : Geometry.d4){
|
||||
Tile other = world.tile(tile.x + point.x, tile.y + point.y);
|
||||
if(other.block() == Blocks.air){
|
||||
deposit(other, tile, liquid, deposited, generation + 1);
|
||||
amount -= deposited/4f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
amount = Mathf.clamp(amount, 0, maxLiquid);
|
||||
|
||||
if(amount <= 0f){
|
||||
CallEntity.onPuddleRemoved(getID());
|
||||
}
|
||||
updateTime -= Timers.delta();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -282,6 +290,8 @@ public class Puddle extends BaseEntity implements SaveTrait, Poolable, DrawTrait
|
||||
liquid = Liquid.getByID(data.readByte());
|
||||
targetAmount = data.readShort()/4f;
|
||||
tile = world.tile(data.readInt());
|
||||
|
||||
map.put(tile.packedPosition(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**Marks an entity as serializable.*/
|
||||
public interface SaveTrait extends Entity{
|
||||
public interface SaveTrait extends Entity, TypeTrait{
|
||||
void writeSave(DataOutput stream) throws IOException;
|
||||
void readSave(DataInput stream) throws IOException;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.net.Interpolator;
|
||||
import io.anuke.ucore.entities.trait.Entity;
|
||||
import io.anuke.ucore.function.Supplier;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
@@ -12,25 +10,7 @@ import java.io.IOException;
|
||||
|
||||
import static io.anuke.mindustry.Vars.threads;
|
||||
|
||||
public interface SyncTrait extends Entity {
|
||||
int[] lastRegisteredID = {0};
|
||||
Array<Supplier<? extends SyncTrait>> registeredTypes = new Array<>();
|
||||
|
||||
/**Register and return a type ID. The supplier should return a fresh instace of that type.*/
|
||||
static int registerType(Supplier<? extends SyncTrait> supplier){
|
||||
registeredTypes.add(supplier);
|
||||
int result = lastRegisteredID[0];
|
||||
lastRegisteredID[0] ++;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**Registers a syncable type by ID.*/
|
||||
static Supplier<? extends SyncTrait> 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()?");
|
||||
}
|
||||
return registeredTypes.get(id);
|
||||
}
|
||||
public interface SyncTrait extends Entity, TypeTrait {
|
||||
|
||||
/**Whether smoothing of entities is enabled; not yet implemented.*/
|
||||
static boolean isSmoothing(){
|
||||
@@ -64,9 +44,6 @@ public interface SyncTrait extends Entity {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX.*/
|
||||
int getTypeID();
|
||||
|
||||
//Read and write sync data, usually position
|
||||
void write(DataOutput data) throws IOException;
|
||||
void read(DataInput data, long time) throws IOException;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.anuke.mindustry.entities.traits;
|
||||
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.ucore.function.Supplier;
|
||||
|
||||
public interface TypeTrait {
|
||||
int[] lastRegisteredID = {0};
|
||||
Array<Supplier<? extends TypeTrait>> registeredTypes = new Array<>();
|
||||
|
||||
/**Register and return a type ID. The supplier should return a fresh instace of that type.*/
|
||||
static int registerType(Supplier<? extends TypeTrait> supplier){
|
||||
registeredTypes.add(supplier);
|
||||
int result = lastRegisteredID[0];
|
||||
lastRegisteredID[0] ++;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**Registers 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()?");
|
||||
}
|
||||
return registeredTypes.get(id);
|
||||
}
|
||||
|
||||
/**Returns the type ID of this entity used for intstantiation. Should be < BYTE_MAX.*/
|
||||
int getTypeID();
|
||||
}
|
||||
@@ -266,6 +266,8 @@ public abstract class BaseUnit extends Unit{
|
||||
|
||||
@Remote(called = Loc.server, in = In.entities)
|
||||
public static void onUnitShoot(BaseUnit unit, AmmoType type, float rotation){
|
||||
if(unit == null) return;
|
||||
|
||||
Bullet.create(type.bullet, unit,
|
||||
unit.x + Angles.trnsx(rotation, unit.type.shootTranslation),
|
||||
unit.y + Angles.trnsy(rotation, unit.type.shootTranslation), rotation);
|
||||
@@ -277,11 +279,14 @@ public abstract class BaseUnit extends Unit{
|
||||
|
||||
@Remote(called = Loc.server, in = In.entities)
|
||||
public static void onUnitDeath(BaseUnit unit){
|
||||
if(unit == null) return;
|
||||
|
||||
unit.onSuperDeath();
|
||||
|
||||
Effects.effect(ExplosionFx.explosion, unit);
|
||||
Effects.shake(2f, 2f, unit);
|
||||
|
||||
unit.remove();
|
||||
//must run afterwards so the unit's group is not null
|
||||
threads.runDelay(unit::remove);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user