package mindustry.world; import arc.func.*; import arc.math.*; import arc.math.geom.*; import arc.util.*; import mindustry.gen.*; import java.util.*; /** A tile container. */ public class Tiles implements Iterable{ public final int width, height; final Tile[] array; final Puddle[] puddles; final Fire[] fires; public Tiles(int width, int height){ this.array = new Tile[width * height]; this.width = width; this.height = height; this.puddles = new Puddle[width * height]; this.fires = new Fire[width * height]; } public Puddle getPuddle(int pos){ return puddles[pos]; } public void setPuddle(int pos, Puddle p){ puddles[pos] = p; } public @Nullable Fire getFire(int pos){ return fires[pos]; } public void setFire(int pos, Fire f){ fires[pos] = f; } public void each(Intc2 cons){ for(int x = 0; x < width; x++){ for(int y = 0; y < height; y++){ cons.get(x, y); } } } /** fills this tile set with empty air tiles. */ public void fill(){ for(int i = 0; i < array.length; i++){ array[i] = new Tile(i % width, i / width); } } /** set a tile at a position; does not range-check. use with caution. */ public void set(int x, int y, Tile tile){ array[y*width + x] = tile; } /** set a tile at a raw array position; used for fast iteration / 1-D for-loops */ public void seti(int i, Tile tile){ array[i] = tile; } /** @return whether these coordinates are in bounds */ public boolean in(int x, int y){ return x >= 0 && x < width && y >= 0 && y < height; } /** @return a tile at coordinates, or null if out of bounds */ @Nullable public Tile get(int x, int y){ return (x < 0 || x >= width || y < 0 || y >= height) ? null : array[y*width + x]; } /** @return a tile at coordinates; throws an exception if out of bounds */ public Tile getn(int x, int y){ if(x < 0 || x >= width || y < 0 || y >= height) throw new IllegalArgumentException(x + ", " + y + " out of bounds: width=" + width + ", height=" + height); return array[y*width + x]; } /** @return a tile at coordinates, clamped. */ public Tile getc(int x, int y){ x = Mathf.clamp(x, 0, width - 1); y = Mathf.clamp(y, 0, height - 1); return array[y*width + x]; } /** @return a tile at an iteration index [0, width * height] */ public Tile geti(int idx){ return array[idx]; } /** @return a tile at an int position (not equivalent to geti) */ public @Nullable Tile getp(int pos){ return get(Point2.x(pos), Point2.y(pos)); } public void eachTile(Cons cons){ for(Tile tile : array){ cons.get(tile); } } @Override public Iterator iterator(){ //iterating through the entire map is expensive anyway, so a new allocation doesn't make much of a difference return new TileIterator(); } private class TileIterator implements Iterator{ int index = 0; TileIterator(){ } @Override public boolean hasNext(){ return index < array.length; } @Override public Tile next(){ return array[index++]; } } }