parent
b2cf0d14a0
commit
e83047ff38
@ -0,0 +1,89 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
import mightypork.util.constraints.rect.proxy.RectBound; |
||||
import mightypork.util.control.timing.Updateable; |
||||
import mightypork.util.files.ion.BinaryUtils; |
||||
import mightypork.util.files.ion.Ionizable; |
||||
|
||||
|
||||
public class ItemData implements Ionizable, Updateable { |
||||
|
||||
public static final short ION_MARK = 701; |
||||
|
||||
private Model<ItemData, RectBound> model; |
||||
|
||||
// data fields for models to use
|
||||
public Object data; |
||||
public boolean[] flags; |
||||
public int[] ints; |
||||
|
||||
|
||||
/** |
||||
* Create from model id |
||||
* |
||||
* @param id model id |
||||
*/ |
||||
public ItemData(int id) { |
||||
this(Items.get(id)); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create from model |
||||
* |
||||
* @param model model |
||||
*/ |
||||
public ItemData(Model<ItemData, RectBound> model) { |
||||
this.model = model; |
||||
model.create(this); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create without model. Model will be read from ION input stream. |
||||
*/ |
||||
public ItemData() { |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void loadFrom(InputStream in) throws IOException |
||||
{ |
||||
final int id = BinaryUtils.readInt(in); |
||||
model = Items.get(id); |
||||
model.load(this, in); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void saveTo(OutputStream out) throws IOException |
||||
{ |
||||
BinaryUtils.writeInt(out, model.getId()); |
||||
model.save(this, out); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public short getIonMark() |
||||
{ |
||||
return ION_MARK; |
||||
} |
||||
|
||||
|
||||
public void render(RectBound context) |
||||
{ |
||||
model.render(this, context); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void update(double delta) |
||||
{ |
||||
model.update(this, delta); |
||||
} |
||||
} |
@ -0,0 +1,84 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
import mightypork.util.annotations.DefaultImpl; |
||||
import mightypork.util.constraints.rect.proxy.RectBound; |
||||
|
||||
|
||||
/** |
||||
* An item model |
||||
* |
||||
* @author MightyPork |
||||
*/ |
||||
public abstract class ItemModel implements Model<ItemData, RectBound> { |
||||
|
||||
public final int id; |
||||
|
||||
|
||||
public ItemModel(int id) { |
||||
this.id = id; |
||||
Items.register(id, this); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public final int getId() |
||||
{ |
||||
return id; |
||||
} |
||||
|
||||
|
||||
@Override |
||||
@DefaultImpl |
||||
public void create(ItemData item) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/** |
||||
* On search performed (reveal hidden door etc) |
||||
* |
||||
* @param item item in world |
||||
*/ |
||||
@DefaultImpl |
||||
public void search(TileData item) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Check if an entity can walk this item. If the item is not potentially |
||||
* walkable, then this method must always return false. |
||||
* |
||||
* @param item item in world |
||||
*/ |
||||
public abstract void isWalkable(TileData item); |
||||
|
||||
|
||||
@Override |
||||
@DefaultImpl |
||||
public void load(ItemData item, InputStream in) |
||||
{ |
||||
} |
||||
|
||||
|
||||
@Override |
||||
@DefaultImpl |
||||
public void save(ItemData item, OutputStream out) |
||||
{ |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public abstract void render(ItemData item, RectBound context); |
||||
|
||||
|
||||
@Override |
||||
@DefaultImpl |
||||
public void update(ItemData item, double delta) |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
|
||||
public class Items { |
||||
|
||||
private static final Map<Integer, ItemModel> registered = new HashMap<>(); |
||||
|
||||
|
||||
public static void register(int id, ItemModel model) |
||||
{ |
||||
if (registered.containsKey(id)) throw new IllegalArgumentException("Item ID " + id + " already in use."); |
||||
registered.put(id, model); |
||||
} |
||||
|
||||
|
||||
public static ItemModel get(int id) |
||||
{ |
||||
final ItemModel m = registered.get(id); |
||||
if (m == null) throw new IllegalArgumentException("No item with ID " + id + "."); |
||||
return m; |
||||
} |
||||
} |
@ -0,0 +1,63 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
import mightypork.util.constraints.rect.proxy.RectBound; |
||||
|
||||
|
||||
public interface Model<DATA, RCTX> { |
||||
|
||||
/** |
||||
* Get the id. |
||||
* |
||||
* @return id |
||||
*/ |
||||
int getId(); |
||||
|
||||
|
||||
/** |
||||
* Populate an entity with data for this model |
||||
* |
||||
* @param entity entity in world |
||||
*/ |
||||
void create(DATA entity); |
||||
|
||||
|
||||
/** |
||||
* Load entity data from a binary stream. |
||||
* |
||||
* @param entity item to load |
||||
* @param in input stream |
||||
*/ |
||||
void load(DATA entity, InputStream in); |
||||
|
||||
|
||||
/** |
||||
* Save entity data to a binary stream. |
||||
* |
||||
* @param entity entity to save |
||||
* @param out output stream |
||||
*/ |
||||
void save(DATA entity, OutputStream out); |
||||
|
||||
|
||||
/** |
||||
* Render according to given context. |
||||
* |
||||
* @param entity data object |
||||
* @param context rendering context |
||||
*/ |
||||
void render(DATA entity, RCTX context); |
||||
|
||||
|
||||
/** |
||||
* Update the entity (animation, decay etc) |
||||
* |
||||
* @param entity data object |
||||
* @param delta delta time |
||||
*/ |
||||
void update(DATA entity, double delta); |
||||
|
||||
} |
@ -0,0 +1,102 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
import java.util.Stack; |
||||
|
||||
import mightypork.util.control.timing.Updateable; |
||||
import mightypork.util.files.ion.BinaryUtils; |
||||
import mightypork.util.files.ion.Ionizable; |
||||
|
||||
|
||||
/** |
||||
* Concrete tile in the world. |
||||
* |
||||
* @author MightyPork |
||||
*/ |
||||
public class TileData implements Ionizable, Updateable { |
||||
|
||||
public static final short ION_MARK = 700; |
||||
|
||||
/** Items dropped onto this tile */ |
||||
public final Stack<ItemData> items = new Stack<>(); |
||||
|
||||
/** Whether the tile is occupied by an entity */ |
||||
public boolean occupied; |
||||
|
||||
private TileModel model; |
||||
|
||||
// data fields for models to use
|
||||
public Object data; |
||||
public boolean[] flags; |
||||
public int[] ints; |
||||
|
||||
|
||||
/** |
||||
* Create from model id |
||||
* |
||||
* @param id model id |
||||
*/ |
||||
public TileData(int id) { |
||||
this(Tiles.get(id)); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create from model |
||||
* |
||||
* @param model model |
||||
*/ |
||||
public TileData(TileModel model) { |
||||
this.model = model; |
||||
model.create(this); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Create without model. Model will be read from ION input stream. |
||||
*/ |
||||
public TileData() { |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void loadFrom(InputStream in) throws IOException |
||||
{ |
||||
final int id = BinaryUtils.readInt(in); |
||||
model = Tiles.get(id); |
||||
model.load(this, in); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void saveTo(OutputStream out) throws IOException |
||||
{ |
||||
BinaryUtils.writeInt(out, model.getId()); |
||||
model.save(this, out); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public short getIonMark() |
||||
{ |
||||
return ION_MARK; |
||||
} |
||||
|
||||
|
||||
public void render(TileRenderContext context) |
||||
{ |
||||
model.render(this, context); |
||||
if (!items.isEmpty()) items.peek().render(context); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public void update(double delta) |
||||
{ |
||||
model.update(this, delta); |
||||
if (!items.isEmpty()) items.peek().update(delta); |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
public interface TileHolder { |
||||
|
||||
TileData getTile(int x, int y); |
||||
|
||||
|
||||
int getWidth(); |
||||
|
||||
|
||||
int getHeight(); |
||||
} |
@ -0,0 +1,106 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.io.InputStream; |
||||
import java.io.OutputStream; |
||||
|
||||
import mightypork.util.annotations.DefaultImpl; |
||||
|
||||
|
||||
public abstract class TileModel { |
||||
|
||||
public final int id; |
||||
|
||||
|
||||
public TileModel(int id) { |
||||
this.id = id; |
||||
Tiles.register(id, this); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Get the id. |
||||
* |
||||
* @return id |
||||
*/ |
||||
public final int getId() |
||||
{ |
||||
return id; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* @return can be walked through (if discovered / open) |
||||
*/ |
||||
public abstract boolean isPotentiallyWalkable(); |
||||
|
||||
|
||||
/** |
||||
* Populate a tile holder with data for this tile model |
||||
* |
||||
* @param tile tile in world |
||||
*/ |
||||
@DefaultImpl |
||||
public void create(TileData tile) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/** |
||||
* On search performed (reveal hidden door etc) |
||||
* |
||||
* @param tile tile in world |
||||
*/ |
||||
@DefaultImpl |
||||
public void search(TileData tile) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Check if an entity can walk this tile. If the tile is not potentially |
||||
* walkable, then this method must always return false. |
||||
* |
||||
* @param tile tile in world |
||||
*/ |
||||
public abstract void isWalkable(TileData tile); |
||||
|
||||
|
||||
/** |
||||
* Load a tile from binary stream. |
||||
* |
||||
* @param tile tile to load |
||||
* @param in input stream |
||||
*/ |
||||
@DefaultImpl |
||||
public void load(TileData tile, InputStream in) |
||||
{ |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Save a tile to binary stream. |
||||
* |
||||
* @param tile tile to save |
||||
* @param out output stream |
||||
*/ |
||||
@DefaultImpl |
||||
public void save(TileData tile, OutputStream out) |
||||
{ |
||||
} |
||||
|
||||
|
||||
public abstract void render(TileData tile, TileRenderContext context); |
||||
|
||||
|
||||
/** |
||||
* Update the tile (animation, item spawning etc) |
||||
* |
||||
* @param tile tile to update |
||||
* @param delta delta time |
||||
*/ |
||||
@DefaultImpl |
||||
public void update(TileData tile, double delta) |
||||
{ |
||||
} |
||||
} |
@ -0,0 +1,39 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import mightypork.util.constraints.rect.Rect; |
||||
import mightypork.util.constraints.rect.builders.TiledRect; |
||||
import mightypork.util.constraints.rect.proxy.RectBound; |
||||
|
||||
|
||||
public class TileRenderContext implements RectBound { |
||||
|
||||
private final TileHolder map; |
||||
private final TiledRect tiler; |
||||
private int x, y; |
||||
|
||||
|
||||
public TileRenderContext(TileHolder map, Rect mapArea) { |
||||
this.map = map; |
||||
this.tiler = mapArea.tiles(map.getWidth(), map.getHeight()); |
||||
} |
||||
|
||||
|
||||
public TileData getTile() |
||||
{ |
||||
return map.getTile(x, y); |
||||
} |
||||
|
||||
|
||||
public TileData getAdjacentTile(int offsetX, int offsetY) |
||||
{ |
||||
return map.getTile(x + offsetX, y + offsetY); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public Rect getRect() |
||||
{ |
||||
return tiler.tile(x, y); |
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
package mightypork.rogue.world; |
||||
|
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
|
||||
public class Tiles { |
||||
|
||||
private static final Map<Integer, TileModel> registered = new HashMap<>(); |
||||
|
||||
|
||||
public static void register(int id, TileModel model) |
||||
{ |
||||
if (registered.containsKey(id)) throw new IllegalArgumentException("Tile ID " + id + " already in use."); |
||||
registered.put(id, model); |
||||
} |
||||
|
||||
|
||||
public static TileModel get(int id) |
||||
{ |
||||
final TileModel m = registered.get(id); |
||||
if (m == null) throw new IllegalArgumentException("No tile with ID " + id + "."); |
||||
return m; |
||||
} |
||||
} |
Loading…
Reference in new issue