From 713dbccf74a9740f159c86a6722beba8dfd36ab7 Mon Sep 17 00:00:00 2001 From: Anuken Date: Thu, 16 Apr 2020 11:30:42 -0400 Subject: [PATCH] Bugfixes --- core/src/mindustry/core/Control.java | 2 +- core/src/mindustry/editor/EditorTile.java | 4 +- .../mindustry/editor/MapGenerateDialog.java | 2 +- core/src/mindustry/entities/def/TileComp.java | 9 +- core/src/mindustry/world/CachedTile.java | 2 +- core/src/mindustry/world/Edges.java | 2 +- core/src/mindustry/world/Tile.java | 65 +++-- .../blocks/distribution/MassConveyor.java | 18 +- .../blocks/units/PayloadUnitFactory.java | 233 ++++++++++++++++++ .../world/blocks/units/UnitFactory.java | 3 +- 10 files changed, 304 insertions(+), 36 deletions(-) create mode 100644 core/src/mindustry/world/blocks/units/PayloadUnitFactory.java diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index bbbdc415cb..45b856db4a 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -258,7 +258,7 @@ public class Control implements ApplicationListener, Loadable{ ui.planet.hide(); SaveSlot slot = sector.save; //TODO comment for new sector states - slot = null; + //slot = null; if(slot != null){ try{ net.reset(); diff --git a/core/src/mindustry/editor/EditorTile.java b/core/src/mindustry/editor/EditorTile.java index f4085a2876..10b75e1e85 100644 --- a/core/src/mindustry/editor/EditorTile.java +++ b/core/src/mindustry/editor/EditorTile.java @@ -101,9 +101,9 @@ public class EditorTile extends Tile{ } @Override - protected void changed(Team team){ + protected void changeEntity(Team team){ if(state.isGame()){ - super.changed(team); + super.changeEntity(team); return; } diff --git a/core/src/mindustry/editor/MapGenerateDialog.java b/core/src/mindustry/editor/MapGenerateDialog.java index 66de62325f..fdc5b47815 100644 --- a/core/src/mindustry/editor/MapGenerateDialog.java +++ b/core/src/mindustry/editor/MapGenerateDialog.java @@ -52,7 +52,7 @@ public class MapGenerateDialog extends FloatingDialog{ private CachedTile ctile = new CachedTile(){ //nothing. @Override - protected void changed(Team team){ + protected void changeEntity(Team team){ } }; diff --git a/core/src/mindustry/entities/def/TileComp.java b/core/src/mindustry/entities/def/TileComp.java index afa7df44cd..1e03c1cf3d 100644 --- a/core/src/mindustry/entities/def/TileComp.java +++ b/core/src/mindustry/entities/def/TileComp.java @@ -929,16 +929,21 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree public void removeFromProximity(){ onProximityRemoved(); + tmpTiles.clear(); Point2[] nearby = Edges.getEdges(block.size); for(Point2 point : nearby){ Tilec other = world.ent(tile.x + point.x, tile.y + point.y); //remove this tile from all nearby tile's proximities if(other != null){ - other.onProximityUpdate(); - other.proximity().remove(this, true); + tmpTiles.add(other); } } + + for(Tilec other : tmpTiles){ + other.proximity().remove(this, true); + other.onProximityUpdate(); + } } public void updateProximity(){ diff --git a/core/src/mindustry/world/CachedTile.java b/core/src/mindustry/world/CachedTile.java index 886f3f548e..a0fbb19535 100644 --- a/core/src/mindustry/world/CachedTile.java +++ b/core/src/mindustry/world/CachedTile.java @@ -20,7 +20,7 @@ public class CachedTile extends Tile{ } @Override - protected void changed(Team team){ + protected void changeEntity(Team team){ entity = null; Block block = block(); diff --git a/core/src/mindustry/world/Edges.java b/core/src/mindustry/world/Edges.java index 86d6e31449..4d9d4a76a7 100644 --- a/core/src/mindustry/world/Edges.java +++ b/core/src/mindustry/world/Edges.java @@ -8,7 +8,7 @@ import java.util.Arrays; import static mindustry.Vars.world; public class Edges{ - private static final int maxSize = 11; + private static final int maxSize = 14; private static final int maxRadius = 12; private static Point2[][] edges = new Point2[maxSize][0]; private static Point2[][] edgeInside = new Point2[maxSize][0]; diff --git a/core/src/mindustry/world/Tile.java b/core/src/mindustry/world/Tile.java index ac4ff69f05..5984dead6f 100644 --- a/core/src/mindustry/world/Tile.java +++ b/core/src/mindustry/world/Tile.java @@ -17,6 +17,8 @@ import mindustry.world.modules.*; import static mindustry.Vars.*; public class Tile implements Position, QuadTreeObject{ + static final ObjectSet tileSet = new ObjectSet<>(); + /** Tile traversal cost. */ public byte cost = 1; /** Tile entity, usually null. */ @@ -27,6 +29,7 @@ public class Tile implements Position, QuadTreeObject{ protected @NonNull Floor overlay; /** Rotation, 0-3. Also used to store offload location, in which case it can be any number.*/ protected byte rotation; + protected boolean changing = false; public Tile(int x, int y){ this.x = (short)x; @@ -42,7 +45,8 @@ public class Tile implements Position, QuadTreeObject{ this.block = wall; //update entity and create it if needed - changed(Team.derelict); + changeEntity(Team.derelict); + changed(); } public Tile(int x, int y, int floor, int overlay, int wall){ @@ -161,10 +165,12 @@ public class Tile implements Position, QuadTreeObject{ } public void setBlock(@NonNull Block type, Team team, int rotation){ - preChanged(); + changing = true; + this.block = type; this.rotation = rotation == 0 ? 0 : (byte)Mathf.mod(rotation, 4); - changed(team); + preChanged(); + changeEntity(team); if(entity != null){ entity.team(team); @@ -205,6 +211,9 @@ public class Tile implements Position, QuadTreeObject{ this.entity = entity; this.block = block; } + + changed(); + changing = false; } public void setBlock(@NonNull Block type, Team team){ @@ -501,12 +510,12 @@ public class Tile implements Position, QuadTreeObject{ //reset entity and block *manually* - thus, preChanged() will not be called anywhere else, for multiblocks if(other != this){ //do not remove own entity so it can be processed in changed() other.entity = null; - } - other.block = Blocks.air; + other.block = Blocks.air; - //manually call changed event - other.updateOcclusion(); - world.notifyChanged(other); + //manually call changed event + other.updateOcclusion(); + world.notifyChanged(other); + } } } } @@ -520,13 +529,27 @@ public class Tile implements Position, QuadTreeObject{ } } - protected void changed(Team team){ + protected void changeEntity(Team team){ if(entity != null){ + int size = entity.block().size; entity.remove(); entity = null; - } - Block block = block(); + //update edge entities + tileSet.clear(); + + for(Point2 edge : Edges.getEdges(size)){ + Tilec other = world.ent(x + edge.x, y + edge.y); + if(other != null){ + tileSet.add(other); + } + } + + //update proximity, since multiblock was just removed + for(Tilec t : tileSet){ + t.updateProximity(); + } + } if(block.hasEntity()){ entity = block.newEntity().init(this, team, block.update); @@ -537,16 +560,20 @@ public class Tile implements Position, QuadTreeObject{ entity.power(new PowerModule()); entity.power().graph.add(entity); } + } + } - if(!world.isGenerating()){ + protected void changed(){ + if(!world.isGenerating()){ + if(entity != null){ entity.updateProximity(); - } - }else if(!world.isGenerating()){ - //since the entity won't update proximity for us, update proximity for all nearby tiles manually - for(Point2 p : Geometry.d4){ - Tilec tile = world.ent(x + p.x, y + p.y); - if(tile != null){ - tile.onProximityUpdate(); + }else{ + //since the entity won't update proximity for us, update proximity for all nearby tiles manually + for(Point2 p : Geometry.d4){ + Tilec tile = world.ent(x + p.x, y + p.y); + if(tile != null && !tile.tile().changing){ + tile.onProximityUpdate(); + } } } } diff --git a/core/src/mindustry/world/blocks/distribution/MassConveyor.java b/core/src/mindustry/world/blocks/distribution/MassConveyor.java index fdcd23fec6..1afb2acec7 100644 --- a/core/src/mindustry/world/blocks/distribution/MassConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/MassConveyor.java @@ -68,15 +68,17 @@ public class MassConveyor extends Block{ public void onProximityUpdate(){ super.onProximityUpdate(); - Tilec accept = nearby(Geometry.d4[rotation()].x * size, Geometry.d4[rotation()].y * size); + Tilec accept = nearby(Geometry.d4(rotation()).x * size, Geometry.d4(rotation()).y * size); //next block must be aligned and of the same size if(accept != null && accept.block().size == size && - tileX() + Geometry.d4[rotation()].x * size == accept.tileX() && tileY() + Geometry.d4[rotation()].y * size == accept.tileY()){ + tileX() + Geometry.d4(rotation()).x * size == accept.tileX() && tileY() + Geometry.d4(rotation()).y * size == accept.tileY()){ next = accept; + }else{ + next = null; } int ntrns = 1 + size/2; - Tile next = tile.getNearby(Geometry.d4[rotation()].x * ntrns, Geometry.d4[rotation()].y * ntrns); + Tile next = tile.getNearby(Geometry.d4(rotation()).x * ntrns, Geometry.d4(rotation()).y * ntrns); blocked = (next != null && next.solid()) || (this.next != null && (this.next.rotation() + 2)%4 == rotation()); } @@ -109,7 +111,7 @@ public class MassConveyor extends Block{ } }else if(!blocked){ //dump item forward - float trnext = size * tilesize / 2f, cx = Geometry.d4[rotation()].x, cy = Geometry.d4[rotation()].y, rot = rotation() * 90; + float trnext = size * tilesize / 2f, cx = Geometry.d4(rotation()).x, cy = Geometry.d4(rotation()).y, rot = rotation() * 90; if(item.dump(x + cx * trnext, y + cy * trnext, rotation() * 90)){ item = null; @@ -192,14 +194,14 @@ public class MassConveyor extends Block{ @Override public boolean acceptPayload(Tilec source, Payload payload){ - return this.item == null; + return this.item == null && progress <= 5f; } @Override public void handlePayload(Tilec source, Payload payload){ this.item = payload; this.stepAccepted = curStep(); - this.itemRotation = source.rotation() * 90; + this.itemRotation = source.angleTo(this); this.animation = 0; } @@ -207,10 +209,10 @@ public class MassConveyor extends Block{ if(direction == rotation()){ return !blocked || next != null; }else{ - Tilec accept = nearby(Geometry.d4[direction].x * size, Geometry.d4[direction].y * size); + Tilec accept = nearby(Geometry.d4(direction).x * size, Geometry.d4(direction).y * size); return accept != null && accept.block().size == size && accept.block().outputsPayload && //block must either be facing this one, or not be rotating - ((accept.tileX() + Geometry.d4[accept.rotation()].x * size == tileX() && accept.tileY() + Geometry.d4[accept.rotation()].y * size == tileY()) || !accept.block().rotate); + ((accept.tileX() + Geometry.d4(accept.rotation()).x * size == tileX() && accept.tileY() + Geometry.d4(accept.rotation()).y * size == tileY()) || !accept.block().rotate); } } diff --git a/core/src/mindustry/world/blocks/units/PayloadUnitFactory.java b/core/src/mindustry/world/blocks/units/PayloadUnitFactory.java new file mode 100644 index 0000000000..98d8672a0c --- /dev/null +++ b/core/src/mindustry/world/blocks/units/PayloadUnitFactory.java @@ -0,0 +1,233 @@ +package mindustry.world.blocks.units; + +import arc.*; +import arc.graphics.g2d.*; +import arc.math.*; +import arc.scene.ui.layout.*; +import arc.struct.*; +import arc.util.ArcAnnotate.*; +import arc.util.io.*; +import mindustry.*; +import mindustry.annotations.Annotations.*; +import mindustry.content.*; +import mindustry.entities.*; +import mindustry.gen.*; +import mindustry.graphics.*; +import mindustry.type.*; +import mindustry.ui.*; +import mindustry.world.*; +import mindustry.world.blocks.*; +import mindustry.world.blocks.payloads.*; +import mindustry.world.consumers.*; +import mindustry.world.meta.*; + +//TODO remove +public class PayloadUnitFactory extends Block{ + public float launchVelocity = 0f; + public TextureRegion topRegion; + public int[] capacities; + + public UnitPlan[] plans = new UnitPlan[0]; + + public PayloadUnitFactory(String name){ + super(name); + update = true; + hasPower = true; + hasItems = true; + solid = false; + flags = EnumSet.of(BlockFlag.producer); + configurable = true; + outputsPayload = true; + + config(Integer.class, (tile, i) -> ((UnitFactoryEntity)tile).currentPlan = i < 0 || i >= plans.length ? -1 : i); + } + + @Remote(called = Loc.server) + public static void onUnitFactorySpawn(Tile tile){ + if(!(tile.entity instanceof UnitFactoryEntity)) return; + tile.ent().spawned(); + } + + @Override + public void init(){ + super.init(); + + capacities = new int[Vars.content.items().size]; + if(consumes.has(ConsumeType.item)){ + ConsumeItems cons = consumes.get(ConsumeType.item); + for(ItemStack stack : cons.items){ + capacities[stack.item.id] = stack.amount * 2; + } + } + } + + @Override + public void load(){ + super.load(); + + topRegion = Core.atlas.find(name + "-top"); + } + + @Override + public void setBars(){ + super.setBars(); + bars.add("progress", entity -> new Bar("bar.progress", Pal.ammo, ((UnitFactoryEntity)entity)::fraction)); + } + + @Override + public boolean outputsItems(){ + return false; + } + + @Override + public void setStats(){ + super.setStats(); + + stats.remove(BlockStat.itemCapacity); + //TODO + //stats.add(BlockStat.productionTime, produceTime / 60f, StatUnit.seconds); + } + + @Override + public TextureRegion[] generateIcons(){ + return new TextureRegion[]{Core.atlas.find(name), Core.atlas.find(name + "-top")}; + } + + public static class UnitPlan{ + public UnitType unit; + public ItemStack[] requirements; + public float time; + + public UnitPlan(UnitType unit, float time, ItemStack[] requirements){ + this.unit = unit; + this.time = time; + this.requirements = requirements; + } + + UnitPlan(){} + } + + public class UnitFactoryEntity extends TileEntity{ + public int currentPlan = -1; + + public float progress, time, speedScl; + public @Nullable UnitPayload payload; + + public float fraction(){ + return currentPlan == -1 ? 0 : progress / plans[currentPlan].time; + } + + public void spawned(){ + progress = 0f; + + Effects.shake(2f, 3f, this); + Fx.producesmoke.at(this); + + if(currentPlan != -1){ + UnitPlan plan = plans[currentPlan]; + Unitc unit = plan.unit.create(team); + + payload = new UnitPayload(unit); + } + } + + @Override + public void buildConfiguration(Table table){ + Array units = Array.with(plans).map(u -> u.unit); + + ItemSelection.buildTable(table, units, () -> currentPlan == -1 ? null : plans[currentPlan].unit, unit -> tile.configure(units.indexOf(unit))); + } + + @Override + public Object config(){ + return currentPlan; + } + + @Override + public void draw(){ + super.draw(); + + if(currentPlan != -1){ + UnitPlan plan = plans[currentPlan]; + + TextureRegion region = plan.unit.icon(Cicon.full); + + Shaders.build.region = region; + Shaders.build.progress = progress / plan.time; + Shaders.build.color.set(Pal.accent); + Shaders.build.color.a = speedScl; + Shaders.build.time = -time / 20f; + + Draw.shader(Shaders.build); + Draw.rect(region, x, y); + Draw.shader(); + + Draw.color(Pal.accent); + Draw.alpha(speedScl); + + Lines.lineAngleCenter(x + Mathf.sin(time, 20f, Vars.tilesize / 2f * size - 2f), y, 90, size * Vars.tilesize - 4f); + + Draw.reset(); + } + + Draw.rect(topRegion, x, y); + } + + @Override + public void updateTile(){ + if(currentPlan < 0 || currentPlan >= plans.length){ + currentPlan = -1; + } + + if((consValid() || tile.isEnemyCheat()) && currentPlan != -1 && payload == null){ + time += delta() * efficiency() * speedScl * Vars.state.rules.unitBuildSpeedMultiplier; + progress += delta() * efficiency() * Vars.state.rules.unitBuildSpeedMultiplier; + speedScl = Mathf.lerpDelta(speedScl, 1f, 0.05f); + }else{ + speedScl = Mathf.lerpDelta(speedScl, 0f, 0.05f); + } + + if(payload != null && dumpPayload(payload)){ + payload = null; + } + + if(currentPlan != -1){ + UnitPlan plan = plans[currentPlan]; + + if(progress >= plan.time){ + progress = 0f; + + Call.onUnitFactorySpawn(tile); + useContent(plan.unit); + consume(); + } + }else{ + progress = 0f; + } + } + + @Override + public int getMaximumAccepted(Item item){ + return capacities[item.id]; + } + + @Override + public byte version(){ + return 1; + } + + @Override + public void write(Writes write){ + super.write(write); + write.f(progress); + write.s(currentPlan); + } + + @Override + public void read(Reads read, byte revision){ + super.read(read, revision); + progress = read.f(); + currentPlan = read.s(); + } + } +} diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 0bb94f44bb..8977ffbf89 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -108,7 +108,6 @@ public class UnitFactory extends Block{ public class UnitFactoryEntity extends TileEntity{ public int currentPlan = -1; - public float progress, time, speedScl; public float fraction(){ @@ -216,12 +215,14 @@ public class UnitFactory extends Block{ public void write(Writes write){ super.write(write); write.f(progress); + write.s(currentPlan); } @Override public void read(Reads read, byte revision){ super.read(read, revision); progress = read.f(); + currentPlan = read.s(); } } }