Merge branch 'master' of https://github.com/Anuken/Mindustry into v106-alpha
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -19,7 +19,7 @@ assignees: ''
|
||||
|
||||
**Link(s) to mod(s) used**: *The mod repositories or zip files that are related to the issue, if applicable.*
|
||||
|
||||
**Save file**: *The save file you were playing on when the bug happened, if applicable.*
|
||||
**Save file**: *The save file you were playing on when the bug happened. REQUIRED for any issue that happens in-game.*
|
||||
|
||||
**Crash report**: *The contents of relevant crash report files. REQUIRED if you are reporting a crash.*
|
||||
|
||||
|
Before Width: | Height: | Size: 230 B After Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 278 B |
Before Width: | Height: | Size: 298 B After Width: | Height: | Size: 491 B |
Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 499 B |
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 522 B |
Before Width: | Height: | Size: 304 B After Width: | Height: | Size: 515 B |
Before Width: | Height: | Size: 268 B After Width: | Height: | Size: 300 B |
Before Width: | Height: | Size: 252 B After Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 294 B |
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 375 B |
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 408 B |
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 419 B |
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 409 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 640 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 636 B |
Before Width: | Height: | Size: 245 B After Width: | Height: | Size: 410 B |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 763 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 812 B After Width: | Height: | Size: 812 B |
Before Width: | Height: | Size: 969 KiB After Width: | Height: | Size: 968 KiB |
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 506 KiB |
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 189 KiB |
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 419 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 190 KiB |
Before Width: | Height: | Size: 419 KiB After Width: | Height: | Size: 419 KiB |
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
@ -45,7 +45,7 @@ public class GroundAI extends AIController{
|
||||
}
|
||||
}
|
||||
|
||||
if(unit.type().canBoost && unit.canPassOn()){
|
||||
if(unit.type().canBoost && unit.tileOn() != null && !unit.tileOn().solid()){
|
||||
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, 0.08f);
|
||||
}
|
||||
|
||||
|
@ -210,8 +210,9 @@ public class Blocks implements ContentList{
|
||||
cacheLayer = CacheLayer.slag;
|
||||
attributes.set(Attribute.heat, 0.85f);
|
||||
|
||||
lightRadius = 65f;
|
||||
lightColor = Color.orange.cpy().a(0.4f);
|
||||
emitLight = true;
|
||||
lightRadius = 40f;
|
||||
lightColor = Color.orange.cpy().a(0.38f);
|
||||
}};
|
||||
|
||||
stone = new Floor("stone");
|
||||
|
@ -112,7 +112,7 @@ public class EditorTile extends Tile{
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
if(block.hasBuilding()){
|
||||
build = entityprov.get().init(this, team, false, rotation);
|
||||
build.cons = new ConsumeModule(build);
|
||||
if(block.hasItems) build.items = new ItemModule();
|
||||
|
@ -122,7 +122,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
||||
Building tile = payload.entity;
|
||||
int tx = Vars.world.toTile(x - tile.block.offset), ty = Vars.world.toTile(y - tile.block.offset);
|
||||
Tile on = Vars.world.tile(tx, ty);
|
||||
if(on != null && Build.validPlace(tile.block, tile.team, tx, ty, tile.rotation)){
|
||||
if(on != null && Build.validPlace(tile.block, tile.team, tx, ty, tile.rotation, false)){
|
||||
int rot = (int)((rotation + 45f) / 90f) % 4;
|
||||
payload.place(on, rot);
|
||||
|
||||
|
@ -417,7 +417,7 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
dead = true;
|
||||
|
||||
//don't waste time when the unit is already on the ground, just destroy it
|
||||
if(isGrounded()){
|
||||
if(!type.flying){
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class BlockRenderer implements Disposable{
|
||||
private FrameBuffer dark = new FrameBuffer();
|
||||
private Seq<Building> outArray2 = new Seq<>();
|
||||
private Seq<Tile> shadowEvents = new Seq<>();
|
||||
private IntSet processedEntities = new IntSet();
|
||||
private IntSet processedEntities = new IntSet(), processedLinks = new IntSet();
|
||||
private boolean displayStatus = false;
|
||||
|
||||
public BlockRenderer(){
|
||||
@ -180,6 +180,7 @@ public class BlockRenderer implements Disposable{
|
||||
tileview.clear();
|
||||
lightview.clear();
|
||||
processedEntities.clear();
|
||||
processedLinks.clear();
|
||||
|
||||
int minx = Math.max(avgx - rangex - expandr, 0);
|
||||
int miny = Math.max(avgy - rangey - expandr, 0);
|
||||
@ -196,10 +197,15 @@ public class BlockRenderer implements Disposable{
|
||||
tile = tile.build.tile;
|
||||
}
|
||||
|
||||
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.build == null || !processedEntities.contains(tile.build.id()))){
|
||||
if(block != Blocks.air && block.cacheLayer == CacheLayer.normal && (tile.build == null || !processedEntities.contains(tile.build.id))){
|
||||
if(block.expanded || !expanded){
|
||||
tileview.add(tile);
|
||||
if(tile.build != null) processedEntities.add(tile.build.id());
|
||||
if(tile.build == null || processedLinks.add(tile.build.id)){
|
||||
tileview.add(tile);
|
||||
if(tile.build != null){
|
||||
processedEntities.add(tile.build.id);
|
||||
processedLinks.add(tile.build.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//lights are drawn even in the expanded range
|
||||
@ -209,7 +215,7 @@ public class BlockRenderer implements Disposable{
|
||||
|
||||
if(tile.build != null && tile.build.power != null && tile.build.power.links.size > 0){
|
||||
for(Building other : tile.build.getPowerConnections(outArray2)){
|
||||
if(other.block instanceof PowerNode){ //TODO need a generic way to render connections!
|
||||
if(other.block instanceof PowerNode && processedLinks.add(other.id)){ //TODO need a generic way to render connections!
|
||||
tileview.add(other.tile);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class FloorRenderer implements Disposable{
|
||||
//TODO find out number with best performance
|
||||
private static final int chunksize = mobile ? 16 : 32;
|
||||
|
||||
private Chunk[][] cache;
|
||||
private int[][][] cache;
|
||||
private MultiCacheBatch cbatch;
|
||||
private IntSet drawnLayerSet = new IntSet();
|
||||
private IntSet recacheSet = new IntSet();
|
||||
@ -63,11 +63,11 @@ public class FloorRenderer implements Disposable{
|
||||
if(!Structs.inBounds(worldx, worldy, cache))
|
||||
continue;
|
||||
|
||||
Chunk chunk = cache[worldx][worldy];
|
||||
int[] chunk = cache[worldx][worldy];
|
||||
|
||||
//loop through all layers, and add layer index if it exists
|
||||
for(int i = 0; i < layers; i++){
|
||||
if(chunk.caches[i] != -1 && i != CacheLayer.walls.ordinal()){
|
||||
if(chunk[i] != -1 && i != CacheLayer.walls.ordinal()){
|
||||
drawnLayerSet.add(i);
|
||||
}
|
||||
}
|
||||
@ -154,9 +154,9 @@ public class FloorRenderer implements Disposable{
|
||||
continue;
|
||||
}
|
||||
|
||||
Chunk chunk = cache[worldx][worldy];
|
||||
if(chunk.caches[layer.ordinal()] == -1) continue;
|
||||
cbatch.drawCache(chunk.caches[layer.ordinal()]);
|
||||
int[] chunk = cache[worldx][worldy];
|
||||
if(chunk[layer.ordinal()] == -1) continue;
|
||||
cbatch.drawCache(chunk[layer.ordinal()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ public class FloorRenderer implements Disposable{
|
||||
|
||||
private void cacheChunk(int cx, int cy){
|
||||
used.clear();
|
||||
Chunk chunk = cache[cx][cy];
|
||||
int[] chunk = cache[cx][cy];
|
||||
|
||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize && tilex < world.width(); tilex++){
|
||||
for(int tiley = cy * chunksize; tiley < (cy + 1) * chunksize && tiley < world.height(); tiley++){
|
||||
@ -184,15 +184,15 @@ public class FloorRenderer implements Disposable{
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheChunkLayer(int cx, int cy, Chunk chunk, CacheLayer layer){
|
||||
private void cacheChunkLayer(int cx, int cy, int[] chunk, CacheLayer layer){
|
||||
Batch current = Core.batch;
|
||||
Core.batch = cbatch;
|
||||
|
||||
//begin a new cache
|
||||
if(chunk.caches[layer.ordinal()] == -1){
|
||||
if(chunk[layer.ordinal()] == -1){
|
||||
cbatch.beginCache();
|
||||
}else{
|
||||
cbatch.beginCache(chunk.caches[layer.ordinal()]);
|
||||
cbatch.beginCache(chunk[layer.ordinal()]);
|
||||
}
|
||||
|
||||
for(int tilex = cx * chunksize; tilex < (cx + 1) * chunksize; tilex++){
|
||||
@ -218,7 +218,7 @@ public class FloorRenderer implements Disposable{
|
||||
|
||||
Core.batch = current;
|
||||
cbatch.reserve(layer.capacity * chunksize * chunksize);
|
||||
chunk.caches[layer.ordinal()] = cbatch.endCache();
|
||||
chunk[layer.ordinal()] = cbatch.endCache();
|
||||
}
|
||||
|
||||
public void clearTiles(){
|
||||
@ -227,15 +227,14 @@ public class FloorRenderer implements Disposable{
|
||||
recacheSet.clear();
|
||||
int chunksx = Mathf.ceil((float)(world.width()) / chunksize),
|
||||
chunksy = Mathf.ceil((float)(world.height()) / chunksize);
|
||||
cache = new Chunk[chunksx][chunksy];
|
||||
cbatch = new MultiCacheBatch(chunksize * chunksize * 8);
|
||||
cache = new int[chunksx][chunksy][CacheLayer.all.length];
|
||||
cbatch = new MultiCacheBatch(chunksize * chunksize * 9);
|
||||
|
||||
Time.mark();
|
||||
|
||||
for(int x = 0; x < chunksx; x++){
|
||||
for(int y = 0; y < chunksy; y++){
|
||||
cache[x][y] = new Chunk();
|
||||
Arrays.fill(cache[x][y].caches, -1);
|
||||
Arrays.fill(cache[x][y], -1);
|
||||
|
||||
cacheChunk(x, y);
|
||||
}
|
||||
@ -251,13 +250,4 @@ public class FloorRenderer implements Disposable{
|
||||
cbatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Chunk{
|
||||
/** Maps cache layer ID to cache ID in the batch.
|
||||
* -1 means that this cache is unoccupied. */
|
||||
int[] caches = new int[CacheLayer.all.length];
|
||||
|
||||
Chunk(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ public abstract class SaveVersion extends SaveFileReader{
|
||||
|
||||
if(hadEntity){
|
||||
if(isCenter){ //only read entity for center blocks
|
||||
if(block.hasEntity()){
|
||||
if(block.hasBuilding()){
|
||||
try{
|
||||
readChunk(stream, true, in -> {
|
||||
byte revision = in.readByte();
|
||||
|
@ -61,7 +61,7 @@ public abstract class LegacySaveVersion extends SaveVersion{
|
||||
tile.setBlock(block);
|
||||
}
|
||||
|
||||
if(block.hasEntity()){
|
||||
if(block.hasBuilding()){
|
||||
try{
|
||||
readChunk(stream, true, in -> {
|
||||
byte version = in.readByte();
|
||||
|
@ -25,15 +25,15 @@ import static mindustry.Vars.net;
|
||||
public class CrashSender{
|
||||
|
||||
public static String createReport(String error){
|
||||
String report = "Oh no, Mindustry crashed!\n";
|
||||
if(mods.list().size == 0){
|
||||
report += "Please report this at " + Vars.reportIssueURL + "\n\n";
|
||||
String report = "Mindustry has crashed. How unforunate.\n";
|
||||
if(mods.list().size == 0 && Version.build != -1){
|
||||
report += "Report this at " + Vars.reportIssueURL + "\n\n";
|
||||
}
|
||||
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
|
||||
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
||||
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
||||
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
||||
+ mods.list().size + " Mods: " + (mods.list().isEmpty() ? "none" : mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
||||
+ mods.list().size + " Mods" + (mods.list().isEmpty() ? "" : ": " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
||||
+ "\n\n" + error;
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ public class Block extends UnlockableContent{
|
||||
return variantRegions;
|
||||
}
|
||||
|
||||
public boolean hasEntity(){
|
||||
public boolean hasBuilding(){
|
||||
return destructible || update;
|
||||
}
|
||||
|
||||
|
@ -68,8 +68,13 @@ public class Build{
|
||||
|
||||
/** Returns whether a tile can be placed at this location by this team. */
|
||||
public static boolean validPlace(Block type, Team team, int x, int y, int rotation){
|
||||
return validPlace(type, team, x, y, rotation, true);
|
||||
}
|
||||
|
||||
/** Returns whether a tile can be placed at this location by this team. */
|
||||
public static boolean validPlace(Block type, Team team, int x, int y, int rotation, boolean checkVisible){
|
||||
//the wave team can build whatever they want as long as it's visible - banned blocks are not applicable
|
||||
if(type == null || (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible()))){
|
||||
if(type == null || (checkVisible && (!type.isPlaceable() && !(state.rules.waves && team == state.rules.waveTeam && type.isVisible())))){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class CachedTile extends Tile{
|
||||
|
||||
Block block = block();
|
||||
|
||||
if(block.hasEntity()){
|
||||
if(block.hasBuilding()){
|
||||
Building n = entityprov.get();
|
||||
n.cons(new ConsumeModule(build));
|
||||
n.tile(this);
|
||||
|
@ -508,7 +508,7 @@ public class Tile implements Position, QuadTreeObject, Displayable{
|
||||
}
|
||||
}
|
||||
|
||||
if(block.hasEntity()){
|
||||
if(block.hasBuilding()){
|
||||
build = entityprov.get().init(this, team, block.update && !state.isEditor(), rotation);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ public class PowerNode extends PowerBlock{
|
||||
|
||||
public PowerNode(String name){
|
||||
super(name);
|
||||
expanded = true;
|
||||
configurable = true;
|
||||
consumesPower = false;
|
||||
outputsPower = false;
|
||||
@ -392,7 +391,7 @@ public class PowerNode extends PowerBlock{
|
||||
|
||||
if(!linkValid(this, link)) continue;
|
||||
|
||||
if(link.block instanceof PowerNode && !(link.pos() < tile.pos())) continue;
|
||||
if(link.block instanceof PowerNode && link.id >= id) continue;
|
||||
|
||||
drawLaser(team, x, y, link.x, link.y, size, link.block.size);
|
||||
}
|
||||
|