Batched building health update packet
This commit is contained in:
@@ -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){
|
||||
|
||||
@@ -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")){{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user