Batched building health update packet

This commit is contained in:
Anuken
2022-06-22 18:30:59 -04:00
parent 2de706cc6d
commit 1a98a66f23
11 changed files with 135 additions and 54 deletions

View File

@@ -306,24 +306,26 @@ public class BlockIndexer{
return breturnArray;
}
public void notifyBuildHealed(Building build){
if(build.wasDamaged && !build.damaged() && damagedTiles[build.team.id] != null){
damagedTiles[build.team.id].remove(build);
build.wasDamaged = false;
public void notifyHealthChanged(Building build){
boolean damaged = build.damaged();
if(build.wasDamaged != damaged){
if(damagedTiles[build.team.id] == null){
damagedTiles[build.team.id] = new Seq<>(false);
}
if(damaged){
//is now damaged, add to array
damagedTiles[build.team.id].add(build);
}else{
//no longer damaged, remove
damagedTiles[build.team.id].remove(build);
}
build.wasDamaged = damaged;
}
}
public void notifyBuildDamaged(Building build){
if(build.wasDamaged || !build.damaged()) return;
if(damagedTiles[build.team.id] == null){
damagedTiles[build.team.id] = new Seq<>(false);
}
damagedTiles[build.team.id].add(build);
build.wasDamaged = true;
}
public void allBuildings(float x, float y, float range, Cons<Building> cons){
breturnArray.clear();
for(int i = 0; i < activeTeams.size; i++){
@@ -473,7 +475,7 @@ public class BlockIndexer{
data.turretTree.insert(tile.build);
}
notifyBuildDamaged(tile.build);
notifyHealthChanged(tile.build);
}
if(blocksPresent != null){

View File

@@ -44,7 +44,7 @@ public class Liquids{
gasColor = Color.valueOf("c1e8f5");
}};
neoplasm = new CellLiquid("neoplasm", Color.valueOf("e05438")){{
neoplasm = new CellLiquid("neoplasm", Color.valueOf("c33e2b")){{
heatCapacity = 0.4f;
temperature = 0.54f;
viscosity = 0.85f;
@@ -53,8 +53,8 @@ public class Liquids{
hidden = true;
spreadTarget = Liquids.water;
colorFrom = Color.valueOf("f98f4a");
colorTo = Color.valueOf("9e172c");
colorFrom = Color.valueOf("e8803f");
colorTo = Color.valueOf("8c1225");
}};
arkycite = new Liquid("arkycite", Color.valueOf("84a94b")){{

View File

@@ -36,11 +36,12 @@ import static mindustry.Vars.*;
public class NetServer implements ApplicationListener{
/** note that snapshots are compressed, so the max snapshot size here is above the typical UDP safe limit */
private static final int maxSnapshotSize = 800;
private static final int timerBlockSync = 0;
private static final float blockSyncTime = 60 * 6;
private static final int timerBlockSync = 0, timerHealthSync = 1;
private static final float blockSyncTime = 60 * 6, healthSyncTime = 30;
private static final FloatBuffer fbuffer = FloatBuffer.allocate(20);
private static final Writes dataWrites = new Writes(null);
private static final IntSeq hiddenIds = new IntSeq();
private static final IntSeq healthSeq = new IntSeq(maxSnapshotSize / 4 + 1);
private static final Vec2 vector = new Vec2();
/** If a player goes away of their server-side coordinates by this distance, they get teleported back. */
private static final float correctDist = tilesize * 14f;
@@ -96,7 +97,8 @@ public class NetServer implements ApplicationListener{
};
private boolean closing = false;
private Interval timer = new Interval();
private Interval timer = new Interval(10);
private IntSet buildHealthChanged = new IntSet();
private ReusableByteOutStream writeBuffer = new ReusableByteOutStream(127);
private Writes outputBuffer = new Writes(new DataOutputStream(writeBuffer));
@@ -867,6 +869,11 @@ public class NetServer implements ApplicationListener{
}
}
/** Queues a building health update. This will be sent in a Call.buildHealthUpdate packet later. */
public void buildHealthUpdate(Building build){
buildHealthChanged.add(build.pos());
}
/** Should only be used on the headless backend. */
public void openServer(){
try{
@@ -1050,6 +1057,34 @@ public class NetServer implements ApplicationListener{
if(Groups.player.size() > 0 && Core.settings.getBool("blocksync") && timer.get(timerBlockSync, blockSyncTime)){
writeBlockSnapshots();
}
if(Groups.player.size() > 0 && buildHealthChanged.size > 0 && timer.get(timerHealthSync, healthSyncTime)){
healthSeq.clear();
var iter = buildHealthChanged.iterator();
while(iter.hasNext){
int next = iter.next();
var build = world.build(next);
//pack pos + health into update list
if(build != null){
healthSeq.add(next, Float.floatToRawIntBits(build.health));
}
//if size exceeds snapshot limit, send it out and begin building it up again
if(healthSeq.size * 4 >= maxSnapshotSize){
Call.buildHealthUpdate(healthSeq);
healthSeq.clear();
}
}
//send any residual health updates
if(healthSeq.size > 0){
Call.buildHealthUpdate(healthSeq);
}
buildHealthChanged.clear();
}
}catch(IOException e){
Log.err(e);
}

View File

@@ -1762,13 +1762,13 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
@MethodPriority(100)
@Override
public void heal(){
indexer.notifyBuildHealed(self());
healthChanged();
}
@MethodPriority(100)
@Override
public void heal(float amount){
indexer.notifyBuildHealed(self());
healthChanged();
}
@Override
@@ -1779,7 +1779,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
@Replace
@Override
public void kill(){
Call.tileDestroyed(self());
Call.buildDestroyed(self());
}
@Replace
@@ -1796,13 +1796,27 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
damage = Damage.applyArmor(damage, block.armor) / dm;
}
Call.tileDamage(self(), health - handleDamage(damage));
//TODO handle this better on the client.
if(!net.client()){
health -= handleDamage(damage);
}
healthChanged();
if(health <= 0){
Call.tileDestroyed(self());
Call.buildDestroyed(self());
}
}
public void healthChanged(){
//server-side, health updates are batched.
if(net.server()){
netServer.buildHealthUpdate(self());
}
indexer.notifyHealthChanged(self());
}
@Override
public double sense(LAccess sensor){
return switch(sensor){

View File

@@ -84,14 +84,14 @@ public class RegionPart extends DrawPart{
//can be null
var region = drawRegion ? regions[Math.min(i, regions.length - 1)] : null;
float sign = (i == 0 ? 1 : -1) * params.sideMultiplier;
Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad);
Tmp.v1.set((x + mx) * sign * Draw.xscl, (y + my) * Draw.yscl).rotateRadExact((params.rotation - 90) * Mathf.degRad);
float
rx = params.x + Tmp.v1.x,
ry = params.y + Tmp.v1.y,
rot = mr * sign + params.rotation - 90;
Draw.xscl = sign;
Draw.xscl *= sign;
if(outline && drawRegion){
Draw.z(prevZ + outlineLayerOffset);
@@ -115,7 +115,7 @@ public class RegionPart extends DrawPart{
Drawf.additive(heat, heatColor.write(Tmp.c1).a(heatProgress.getClamp(params) * heatColor.a), rx, ry, rot, turretShading ? Layer.turretHeat : Draw.z() + heatLayerOffset);
}
Draw.xscl = 1f;
Draw.xscl *= sign;
}
Draw.z(z);

View File

@@ -522,7 +522,7 @@ public class SectorDamage{
other.build.addPlan(false);
other.remove();
}else{
indexer.notifyBuildDamaged(other.build);
indexer.notifyHealthChanged(other.build);
}
}else if(other.solid() && !other.synthetic()){ //skip damage propagation through solid blocks

View File

@@ -709,20 +709,22 @@ public class Tile implements Position, QuadTreeObject, Displayable{
}
}
@Remote(called = Loc.server, unreliable = true)
public static void tileDamage(Building build, float health){
if(build == null) return;
build.health = health;
if(build.damaged()){
indexer.notifyBuildDamaged(build);
}
}
@Remote(called = Loc.server)
public static void tileDestroyed(Building build){
public static void buildDestroyed(Building build){
if(build == null) return;
build.killed();
}
@Remote
public static void buildHealthUpdate(IntSeq buildings){
for(int i = 0; i < buildings.size; i += 2){
int pos = buildings.items[i];
float health = Float.intBitsToFloat(buildings.items[i + 1]);
var build = world.build(pos);
if(build != null && build.health != health){
build.health = health;
indexer.notifyHealthChanged(build);
}
}
}
}

View File

@@ -89,9 +89,7 @@ public class ConstructBlock extends Block{
}
//make sure block indexer knows it's damaged
if(tile.build.damaged()){
indexer.notifyBuildDamaged(tile.build);
}
indexer.notifyHealthChanged(tile.build);
}
//last builder was this local client player, call placed()