Fixed many various bugs with syncing things

This commit is contained in:
Anuken
2018-06-10 23:33:37 -04:00
parent 2ddd768393
commit cbd83b5e39
20 changed files with 175 additions and 120 deletions
@@ -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);
}
}