1
0
mirror of https://github.com/Anuken/Mindustry.git synced 2024-09-11 08:15:35 +03:00

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()

View File

@ -25,4 +25,4 @@ org.gradle.caching=true
#used for slow jitpack builds; TODO see if this actually works
org.gradle.internal.http.socketTimeout=100000
org.gradle.internal.http.connectionTimeout=100000
archash=89f5cbe7ab
archash=123fbf12b9

View File

@ -285,9 +285,6 @@ public class Generators{
for(Block block : content.blocks()){
if(block.isAir() || block instanceof ConstructBlock || block instanceof OreBlock || block instanceof LegacyBlock) continue;
block.load();
block.loadIcon();
Seq<TextureRegion> toOutline = new Seq<>();
block.getRegionsToOutline(toOutline);
@ -481,6 +478,37 @@ public class Generators{
}
});
MultiPacker packer = new MultiPacker(){
@Override
public void add(PageType type, String name, PixmapRegion region, int[] splits, int[] pads){
String prefix = type == PageType.main ? "" : "../" + type.name() + "/";
Log.info("@ | @x@", prefix + name, region.width, region.height);
//save(region.pixmap, prefix + name);
}
};
//TODO !!!!! currently just an experiment
if(false)
generate("all-icons", () -> {
for(Seq<Content> arr : content.getContentMap()){
for(Content cont : arr){
if(cont instanceof UnlockableContent && !(cont instanceof Planet)){
UnlockableContent unlock = (UnlockableContent)cont;
if(unlock.generateIcons){
try{
unlock.createIcons(packer);
}catch(IllegalArgumentException e){
Log.err(e);
Log.err("Skip: @", unlock.name);
}
}
}
}
}
});
generate("unit-icons", () -> content.units().each(type -> {
if(type.internal) return; //internal hidden units don't generate
@ -488,9 +516,6 @@ public class Generators{
try{
Unit sample = type.constructor.get();
type.load();
type.loadIcon();
type.init();
Func<Pixmap, Pixmap> outline = i -> i.outline(type.outlineColor, 3);
Cons<TextureRegion> outliner = t -> {
@ -703,7 +728,6 @@ public class Generators{
generate("ore-icons", () -> {
content.blocks().<OreBlock>each(b -> b instanceof OreBlock, ore -> {
ore.load();
int shadowColor = Color.rgba8888(0, 0, 0, 0.3f);
for(int i = 0; i < ore.variants; i++){

View File

@ -79,6 +79,11 @@ public class ImagePacker{
return find(name);
}
@Override
public PixmapRegion getPixmap(AtlasRegion region){
return new PixmapRegion(get(region.name));
}
@Override
public boolean has(String s){
return cache.containsKey(s);
@ -88,6 +93,7 @@ public class ImagePacker{
Draw.scl = 1f / Core.atlas.find("scale_marker").width;
Time.mark();
Vars.content.load();
Generators.run();
Log.info("&ly[Generator]&lc Total time to generate: &lg@&lcms", Time.elapsed());