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:
parent
2de706cc6d
commit
1a98a66f23
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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++){
|
||||
|
@ -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());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user