Generic overlay tiles

This commit is contained in:
Anuken 2019-04-12 15:10:10 -04:00
parent ef2b8be726
commit 46c3b35028
22 changed files with 105 additions and 104 deletions

View File

@ -50,7 +50,7 @@ public class DrawOperation{
}else if(type == OpType.team.ordinal()){
tile.setTeam(Team.all[to]);
}else if(type == OpType.ore.ordinal()){
tile.setOreByte(to);
tile.setOverlayID(to);
}
});
editor.renderer().updatePoint(tile.x, tile.y);

View File

@ -6,8 +6,7 @@ import io.anuke.mindustry.game.Team;
import io.anuke.mindustry.gen.TileOp;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.mindustry.world.blocks.*;
import io.anuke.mindustry.world.modules.*;
import static io.anuke.mindustry.Vars.ui;
@ -25,19 +24,19 @@ public class EditorTile extends Tile{
@Override
public void setFloor(Floor type){
if(type instanceof OreBlock){
if(type instanceof OverlayFloor){
//don't place on liquids
if(!floor().isLiquid) setOreByte(type.id);
setOverlayID(type.id);
return;
}
Block previous = floor();
Block ore = ore();
Block ore = overlay();
if(previous == type && ore == Blocks.air) return;
super.setFloor(type);
//ore may get nullified so make sure to save editrs
if(ore() != ore){
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, ore().id));
if(overlay() != ore){
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), ore.id, overlay().id));
}
if(previous != type){
op(TileOp.get(x, y, (byte)OpType.floor.ordinal(), previous.id, type.id));
@ -69,10 +68,10 @@ public class EditorTile extends Tile{
}
@Override
public void setOreByte(byte ore){
byte previous = getOreByte();
public void setOverlayID(byte ore){
byte previous = getOverlayID();
if(previous == ore) return;
super.setOreByte(ore);
super.setOverlayID(ore);
op(TileOp.get(x, y, (byte)OpType.ore.ordinal(), previous, ore));
}

View File

@ -31,7 +31,7 @@ public enum EditorTool{
return;
}
editor.drawBlock = tile.block() == Blocks.air ? tile.ore() == Blocks.air ? tile.floor() : tile.ore() : tile.block();
editor.drawBlock = tile.block() == Blocks.air ? tile.overlay() == Blocks.air ? tile.floor() : tile.overlay() : tile.block();
}
},
pencil{
@ -100,7 +100,7 @@ public enum EditorTool{
boolean synth = editor.drawBlock.synthetic();
Block draw = editor.drawBlock;
dest = draw instanceof OreBlock ? tile.ore() : isfloor ? floor : block;
dest = draw instanceof OverlayFloor ? tile.overlay() : isfloor ? floor : block;
if(dest == draw || block == Blocks.part || block.isMultiblock()){
return;
@ -115,10 +115,10 @@ public enum EditorTool{
Tile write = editor.tile(px, py);
if(isfloor){
if(alt && !(draw instanceof OreBlock)){
Block ore = write.ore();
if(alt && !(draw instanceof OverlayFloor)){
Block ore = write.overlay();
write.setFloor((Floor)draw);
write.setOre(ore);
write.setOverlay(ore);
}else{
write.setFloor((Floor)draw);
}
@ -197,7 +197,7 @@ public enum EditorTool{
boolean eq(int px, int py){
Tile tile = data.tile(px, py);
return (data.drawBlock instanceof OreBlock ? tile.ore() : isfloor ? tile.floor() : tile.block()) == dest && !(data.drawBlock instanceof OreBlock && tile.floor().isLiquid);
return (data.drawBlock instanceof OverlayFloor ? tile.overlay() : isfloor ? tile.floor() : tile.block()) == dest && !(data.drawBlock instanceof OverlayFloor && tile.floor().isLiquid);
}
},
zoom;

View File

@ -26,7 +26,7 @@ import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.mindustry.world.blocks.OverlayFloor;
import io.anuke.mindustry.world.blocks.storage.CoreBlock;
import static io.anuke.mindustry.Vars.*;
@ -486,7 +486,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
if(core != 0) return core;
int synth = Boolean.compare(b1.synthetic(), b2.synthetic());
if(synth != 0) return synth;
int ore = Boolean.compare(b1 instanceof OreBlock, b2 instanceof OreBlock);
int ore = Boolean.compare(b1 instanceof OverlayFloor, b2 instanceof OverlayFloor);
if(ore != 0) return ore;
return Integer.compare(b1.id, b2.id);
});

View File

@ -220,7 +220,7 @@ public class MapGenerateDialog extends FloatingDialog{
for(int x = 0; x < editor.width(); x++){
for(int y = 0; y < editor.height(); y++){
Tile tile = editor.tile(x, y);
input.begin(editor, x, y, tile.floor(), tile.block(), tile.ore());
input.begin(editor, x, y, tile.floor(), tile.block(), tile.overlay());
filter.apply(input);
writeTiles[x][y].set(input.floor, input.block, input.ore, tile.getTeam(), tile.getRotation());
}
@ -237,7 +237,7 @@ public class MapGenerateDialog extends FloatingDialog{
tile.setFloor((Floor)content.block(write.floor));
tile.setBlock(content.block(write.block));
tile.setTeam(Team.all[write.team]);
tile.setOre(content.block(write.ore));
tile.setOverlay(content.block(write.ore));
}
}
});
@ -295,7 +295,7 @@ public class MapGenerateDialog extends FloatingDialog{
//get result from buffer1 if there's filters left, otherwise get from editor directly
if(filters.isEmpty()){
Tile tile = editor.tile(px * scaling, py * scaling);
color = MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), Team.none);
color = MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), Team.none);
}else{
DummyTile tile = buffer1[px][py];
color = MapIO.colorFor(content.block(tile.floor), content.block(tile.block), content.block(tile.ore), Team.none);
@ -339,7 +339,7 @@ public class MapGenerateDialog extends FloatingDialog{
}
void set(Tile other){
set(other.floor(), other.block(), other.ore(), other.getTeam(), other.getRotation());
set(other.floor(), other.block(), other.overlay(), other.getTeam(), other.getRotation());
}
}

View File

@ -138,8 +138,8 @@ public class MapRenderer implements Disposable{
region = !Core.atlas.isFound(wall.editorIcon()) ? Core.atlas.find("clear-editor") : wall.editorIcon();
offsetX = tilesize / 2f - region.getWidth() / 2f * Draw.scl;
offsetY = tilesize / 2f - region.getHeight() / 2f * Draw.scl;
}else if(wall == Blocks.air && tile.ore() != null){
region = tile.ore().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.ore().editorVariantRegions().length - 1)];
}else if(wall == Blocks.air && tile.overlay() != null){
region = tile.overlay().editorVariantRegions()[Mathf.randomSeed(idxWall, 0, tile.overlay().editorVariantRegions().length - 1)];
}else{
region = Core.atlas.find("clear-editor");
}

View File

@ -9,15 +9,14 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.world.Block.Icon;
import io.anuke.mindustry.world.blocks.Floor;
import io.anuke.mindustry.world.blocks.OreBlock;
import io.anuke.mindustry.world.blocks.*;
import static io.anuke.mindustry.Vars.updateEditorOnChange;
public abstract class FilterOption{
public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OreBlock)) && Core.atlas.isFound(b.icon(Icon.full));
public static final Predicate<Block> floorsOnly = b -> (b instanceof Floor && !(b instanceof OverlayFloor)) && Core.atlas.isFound(b.icon(Icon.full));
public static final Predicate<Block> wallsOnly = b -> (!b.synthetic() && !(b instanceof Floor)) && Core.atlas.isFound(b.icon(Icon.full));
public static final Predicate<Block> oresOnly = b -> b instanceof OreBlock && Core.atlas.isFound(b.icon(Icon.full));
public static final Predicate<Block> oresOnly = b -> b instanceof OverlayFloor && Core.atlas.isFound(b.icon(Icon.full));
public abstract void build(Table table);

View File

@ -130,7 +130,7 @@ public class MinimapRenderer implements Disposable{
private int colorFor(Tile tile){
tile = tile.target();
return MapIO.colorFor(tile.floor(), tile.block(), tile.ore(), tile.getTeam());
return MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam());
}
@Override

View File

@ -234,7 +234,7 @@ public abstract class InputHandler implements InputProcessor{
boolean canMine(Tile tile){
return !Core.scene.hasMouse()
&& tile.drop() != null && tile.drop().hardness <= player.mech.drillPower
&& !(tile.floor().playerUnmineable && tile.ore() == Blocks.air)
&& !(tile.floor().playerUnmineable && tile.overlay() == Blocks.air)
&& player.acceptsItem(tile.drop())
&& tile.block() == Blocks.air && player.dst(tile.worldx(), tile.worldy()) <= Player.mineDistance;
}

View File

@ -75,7 +75,7 @@ public class MapIO{
}
@Override
public void setOreByte(byte b){
public void setOverlayID(byte b){
if(b != 0)
floors.drawPixel(x, floors.getHeight() - 1 - y, colorFor(floor(), Blocks.air, content.block(b), getTeam()));
}
@ -105,7 +105,7 @@ public class MapIO{
for(int x = 0; x < pixmap.getWidth(); x++){
for(int y = 0; y < pixmap.getHeight(); y++){
Tile tile = tiles[x][y];
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.ore(), tile.getTeam()));
pixmap.drawPixel(x, pixmap.getHeight() - 1 - y, colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam()));
}
}
return pixmap;
@ -144,13 +144,13 @@ public class MapIO{
for(int i = 0; i < tiles.length * tiles[0].length; i++){
Tile tile = tiles[i % width][i / width];
stream.writeByte(tile.getFloorID());
stream.writeByte(tile.getOreByte());
stream.writeByte(tile.getOverlayID());
int consecutives = 0;
for(int j = i + 1; j < width * height && consecutives < 255; j++){
Tile nextTile = tiles[j % width][j / width];
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getOreByte() != tile.getOreByte()){
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.block() != Blocks.air || nextTile.getOverlayID() != tile.getOverlayID()){
break;
}
@ -272,13 +272,13 @@ public class MapIO{
Tile tile = tiles.get(x, y);
tile.setFloor((Floor)content.block(floorid));
tile.setOre(content.block(oreid));
tile.setOverlay(content.block(oreid));
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
Tile newTile = tiles.get(newx, newy);
newTile.setFloor((Floor)content.block(floorid));
newTile.setOre(content.block(oreid));
newTile.setOverlay(content.block(oreid));
}
i += consecutives;
@ -337,7 +337,7 @@ public class MapIO{
tile.setFloor(block.floor);
tile.setBlock(block.wall);
if(block.ore != null) tile.setOre(block.ore);
if(block.ore != null) tile.setOverlay(block.ore);
//place core
if(color == Color.rgba8888(Color.GREEN)){
@ -437,7 +437,7 @@ public class MapIO{
}
if(oreMap.containsKey(floorb)){
tile.setOre(content.block(oreMap.get(floorb, 0)));
tile.setOverlay(content.block(oreMap.get(floorb, 0)));
}
}
}

View File

@ -44,13 +44,13 @@ public abstract class SaveFileVersion{
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i % world.width(), i / world.width());
stream.writeByte(tile.getFloorID());
stream.writeByte(tile.getOreByte());
stream.writeByte(tile.getOverlayID());
int consecutives = 0;
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
Tile nextTile = world.tile(j % world.width(), j / world.width());
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.getOreByte() != tile.getOreByte()){
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.getOverlayID() != tile.getOverlayID()){
break;
}
@ -116,12 +116,12 @@ public abstract class SaveFileVersion{
Block ore = content.block(oreid);
tiles[x][y] = new Tile(x, y, floorid, (byte)0);
tiles[x][y].setOre(ore);
tiles[x][y].setOverlay(ore);
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
Tile newTile = new Tile(newx, newy, floorid, (byte)0);
newTile.setOre(ore);
newTile.setOverlay(ore);
tiles[newx][newy] = newTile;
}

View File

@ -145,10 +145,10 @@ public abstract class BasicGenerator extends RandomGenerator{
for(int y = 0; y < height; y++){
floor = tiles[x][y].floor();
block = tiles[x][y].block();
ore = tiles[x][y].ore();
ore = tiles[x][y].overlay();
r.accept(x, y);
tiles[x][y] = new Tile(x, y, floor.id, block.id);
tiles[x][y].setOre(ore);
tiles[x][y].setOverlay(ore);
}
}
}

View File

@ -125,7 +125,7 @@ public class MapGenerator extends Generator{
if(distortFloor){
tile.setFloor(tiles[newX][newY].floor());
tile.setOre(tiles[newX][newY].ore());
tile.setOverlay(tiles[newX][newY].overlay());
}
for(Decoration decor : decorations){
@ -168,7 +168,7 @@ public class MapGenerator extends Generator{
double dst = Mathf.dst(x, y);
if(dst < frad && Structs.inBounds(wx, wy, tiles) && (dst <= rad || Mathf.chance(0.5))){
Tile tile = tiles[wx][wy];
tile.clearOre();
tile.clearOverlay();
}
}
}

View File

@ -27,7 +27,7 @@ public abstract class RandomGenerator extends Generator{
ore = Blocks.air;
generate(x, y);
tiles[x][y] = new Tile(x, y, floor.id, block.id);
tiles[x][y].setOre(ore);
tiles[x][y].setOverlay(ore);
}
}

View File

@ -100,7 +100,7 @@ public class Item extends UnlockableContent implements Comparable<Item>{
}
}
/** Allocates a new array containing all items the generate ores. */
/** Allocates a new array containing all items that generate ores. */
public static Array<Item> getAllOres(){
return content.blocks().select(b -> b instanceof OreBlock).map(b -> ((Floor)b).itemDrop);
}

View File

@ -74,7 +74,7 @@ public class Loadout extends Content{
tile.setRotation((byte)entry.value.rotation);
if(entry.value.ore != null){
for(Tile t : tile.getLinkedTiles(outArray)){
t.setOre(entry.value.ore);
t.setOverlay(entry.value.ore);
}
}
}

View File

@ -337,6 +337,6 @@ public class PlacementFragment extends Fragment{
/** Returns the block currently being hovered over in the world. */
Block tileDisplayBlock(){
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.ore() != Blocks.air ? hoverTile.ore() : null;
return hoverTile == null ? null : hoverTile.block().synthetic() ? hoverTile.block() : hoverTile.overlay() != Blocks.air ? hoverTile.overlay() : null;
}
}

View File

@ -37,7 +37,7 @@ public class Tile implements Position, TargetTrait{
/** Team ordinal. */
private byte team;
/** Ore that is on top of this (floor) block. */
private byte ore = 0;
private byte overlay = 0;
public Tile(int x, int y){
this.x = (short)x;
@ -136,6 +136,10 @@ public class Tile implements Position, TargetTrait{
return wall;
}
public Floor overlay(){
return (Floor)content.block(overlay);
}
@SuppressWarnings("unchecked")
public <T extends Block> T cblock(){
return (T)wall;
@ -178,9 +182,10 @@ public class Tile implements Position, TargetTrait{
changed();
}
/**This resets the overlay!*/
public void setFloor(Floor type){
this.floor = type;
this.ore = 0;
this.overlay = 0;
}
public byte getRotation(){
@ -199,6 +204,22 @@ public class Tile implements Position, TargetTrait{
this.rotation = dump;
}
public byte getOverlayID(){
return overlay;
}
public void setOverlayID(byte ore){
this.overlay = ore;
}
public void setOverlay(Block block){
setOverlayID(block.id);
}
public void clearOverlay(){
this.overlay = 0;
}
public boolean passable(){
Block block = block();
Block floor = floor();
@ -350,28 +371,8 @@ public class Tile implements Position, TargetTrait{
return getTeam() == Team.none || team == getTeam();
}
public byte getOreByte(){
return ore;
}
public void setOreByte(byte ore){
this.ore = ore;
}
public void setOre(Block block){
setOreByte(block.id);
}
public void clearOre(){
this.ore = 0;
}
public Floor ore(){
return (Floor)content.block(ore);
}
public Item drop(){
return ore == 0 ? floor.itemDrop : ((Floor)content.block(ore)).itemDrop;
return overlay == 0 || ((Floor)content.block(overlay)).itemDrop == null ? floor.itemDrop : ((Floor)content.block(overlay)).itemDrop;
}
public void updateOcclusion(){
@ -481,7 +482,7 @@ public class Tile implements Position, TargetTrait{
Block block = block();
Block floor = floor();
return floor.name + ":" + block.name + ":" + content.block(ore) + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) +
return floor.name + ":" + block.name + ":" + content.block(overlay) + "[" + x + "," + y + "] " + "entity=" + (entity == null ? "null" : (entity.getClass())) +
(link != 0 ? " link=[" + (Pack.leftByte(link) - 8) + ", " + (Pack.rightByte(link) - 8) + "]" : "");
}
}

View File

@ -100,7 +100,7 @@ public class Floor extends Block{
drawEdges(tile);
Floor floor = tile.ore();
Floor floor = tile.overlay();
if(floor != Blocks.air && floor != this){ //ore should never have itself on top, but it's possible, so prevent a crash in that case
floor.draw(tile);
}

View File

@ -1,11 +1,10 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.type.Item;
import io.anuke.mindustry.world.Tile;
public class OreBlock extends Floor{
/**An overlay ore for a specific item type.*/
public class OreBlock extends OverlayFloor{
public OreBlock(Item ore){
super("ore-" + ore.name);
@ -24,9 +23,4 @@ public class OreBlock extends Floor{
public String getDisplayName(Tile tile){
return itemDrop.localizedName();
}
@Override
public void draw(Tile tile){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
}
}

View File

@ -0,0 +1,18 @@
package io.anuke.mindustry.world.blocks;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.math.Mathf;
import io.anuke.mindustry.world.Tile;
/**A type of floor that is overlaid on top of over floors.*/
public class OverlayFloor extends Floor{
public OverlayFloor(String name){
super(name);
}
@Override
public void draw(Tile tile){
Draw.rect(variantRegions[Mathf.randomSeed(tile.pos(), 0, Math.max(0, variantRegions.length - 1))], tile.worldx(), tile.worldy());
}
}

View File

@ -147,7 +147,6 @@ public class Generators{
ImagePacker.generate("mech-icons", () -> {
for(Mech mech : content.<Mech>getBy(ContentType.mech)){
mech.load();
mech.weapon.load();
@ -171,9 +170,7 @@ public class Generators{
});
ImagePacker.generate("unit-icons", () -> {
for(UnitType type : content.<UnitType>getBy(ContentType.unit)){
if(type.isFlying) continue;
content.<UnitType>getBy(ContentType.unit).each(type -> type.isFlying, type -> {
type.load();
type.weapon.load();
@ -192,14 +189,11 @@ public class Generators{
}
image.save("unit-icon-" + type.name);
}
});
});
ImagePacker.generate("ore-icons", () -> {
for(Block block : content.blocks()){
if(!(block instanceof OreBlock)) continue;
OreBlock ore = (OreBlock)block;
content.blocks().<OreBlock>each(b -> b instanceof OreBlock, ore -> {
Item item = ore.itemDrop;
for(int i = 0; i < 3; i++){
@ -226,25 +220,22 @@ public class Generators{
image.save("../editor/editor-ore-" + item.name + (i + 1));
//save icons
image.save(block.name + "-icon-full");
image.save(ore.name + "-icon-full");
for(Icon icon : Icon.values()){
if(icon.size == 0) continue;
Image scaled = new Image(icon.size, icon.size);
scaled.drawScaled(image);
scaled.save(block.name + "-icon-" + icon.name());
scaled.save(ore.name + "-icon-" + icon.name());
}
}
}
});
});
ImagePacker.generate("edges", () -> {
for(Block block : content.blocks()){
if(!(block instanceof Floor)) continue;
Floor floor = (Floor)block;
content.blocks().<Floor>each(b -> b instanceof Floor, floor -> {
if(ImagePacker.has(floor.name + "-edge") || floor.blendGroup != floor){
continue;
return;
}
try{
@ -260,9 +251,8 @@ public class Generators{
result.save("../blocks/environment/" + floor.name + "-edge");
}catch(Exception ignored){
}
}
}catch(Exception ignored){}
});
});
}