diff --git a/src/main/java/de/welterde/em/Entity.java b/src/main/java/de/welterde/em/Entity.java index 09d62c3..04651d0 100644 --- a/src/main/java/de/welterde/em/Entity.java +++ b/src/main/java/de/welterde/em/Entity.java @@ -21,6 +21,7 @@ package de.welterde.em; * @author welterde */ public interface Entity { + public GameContext getContext(); public int getEntityId(); - public void initEntity(EntityStorage ctx, int id); + public void initEntity(GameContext ctx, int id); } diff --git a/src/main/java/de/welterde/em/EntityBase.java b/src/main/java/de/welterde/em/EntityBase.java index 7b41bf4..c649408 100644 --- a/src/main/java/de/welterde/em/EntityBase.java +++ b/src/main/java/de/welterde/em/EntityBase.java @@ -23,7 +23,7 @@ import de.welterde.em.io.EntityRecord; * @author welterde */ public abstract class EntityBase implements Entity { - protected EntityStorage ctx; + protected GameContext ctx; protected int id; public EntityBase() { @@ -31,7 +31,7 @@ public abstract class EntityBase implements Entity { this.ctx = null; } - public EntityBase(EntityStorage ctx, int id) { + public EntityBase(GameContext ctx, int id) { this.id = id; this.ctx = ctx; } @@ -41,12 +41,14 @@ public abstract class EntityBase implements Entity { this.ctx = r.getContext(); } + @Override public int getEntityId() { if(this.id == -1) throw new IllegalStateException("Entity not initialized"); return this.id; } - public void initEntity(EntityStorage ctx, int id) { + @Override + public void initEntity(GameContext ctx, int id) { if((this.id != -1) && (this.ctx != null)) throw new IllegalStateException("Entity already initialized"); if(id == -1) @@ -61,4 +63,11 @@ public abstract class EntityBase implements Entity { return this.id != -1; } + @Override + public GameContext getContext() { + if(this.ctx == null) + throw new IllegalStateException("Entity not initialized"); + return this.ctx; + } + } diff --git a/src/main/java/de/welterde/em/EntityContainer.java b/src/main/java/de/welterde/em/EntityContainer.java new file mode 100644 index 0000000..8652f07 --- /dev/null +++ b/src/main/java/de/welterde/em/EntityContainer.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em; + +/** + * + * @author welterde + */ +public interface EntityContainer { + public void addEntity(Entity e); + public Iterable listEntities(); + public void removeEntity(Entity e); +} diff --git a/src/main/java/de/welterde/em/EntityRef.java b/src/main/java/de/welterde/em/EntityRef.java index 16d050f..1a76616 100644 --- a/src/main/java/de/welterde/em/EntityRef.java +++ b/src/main/java/de/welterde/em/EntityRef.java @@ -28,18 +28,24 @@ public class EntityRef { static Location maybeGet(EntityRef currentLocation) { throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody } - protected final EntityStorage ctx; + protected final GameContext ctx; protected WeakReference ref; protected final int entityId; protected boolean invalid; - public EntityRef(EntityStorage ctx, X entity) { + public EntityRef(GameContext ctx, X entity) { this.ctx = ctx; this.entityId = entity.getEntityId(); this.invalid = false; } + public EntityRef(X entity) { + this.ctx = entity.getContext(); + this.entityId = entity.getEntityId(); + this.invalid = false; + } + public X get() { if(this.invalid) throw new InvalidEntityReference(this.entityId); @@ -68,4 +74,5 @@ public class EntityRef { } } } + } diff --git a/src/main/java/de/welterde/em/GameContext.java b/src/main/java/de/welterde/em/GameContext.java new file mode 100644 index 0000000..2615ffc --- /dev/null +++ b/src/main/java/de/welterde/em/GameContext.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em; + +import de.welterde.em.data.CounterName; + +/** + * + * @author welterde + */ +public interface GameContext { + public Entity getEntity(int entityId); + + public EntityContainer getContainer(int entityId); + + int allocateId(CounterName name); + + int addEntity(EntityBase e); +} diff --git a/src/main/java/de/welterde/em/LocatedEntity.java b/src/main/java/de/welterde/em/LocatedEntity.java index a2a1ee0..d823ac1 100644 --- a/src/main/java/de/welterde/em/LocatedEntity.java +++ b/src/main/java/de/welterde/em/LocatedEntity.java @@ -20,13 +20,7 @@ package de.welterde.em; * * @author welterde */ -public class LocatedEntity extends EntityBase { - protected EntityRef currentLocation; - - public Location getLocation() { - if(this.currentLocation == null) - return null; - else - return this.currentLocation.get(); - } +public interface LocatedEntity extends Entity { + public Location getLocation(); + public void setLocation(Location newLoc); } diff --git a/src/main/java/de/welterde/em/LocatedEntityBase.java b/src/main/java/de/welterde/em/LocatedEntityBase.java new file mode 100644 index 0000000..a68e8a5 --- /dev/null +++ b/src/main/java/de/welterde/em/LocatedEntityBase.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em; + +/** + * + * @author welterde + */ +public class LocatedEntityBase extends EntityBase implements LocatedEntity { + protected EntityRef currentLocation; + + @Override + public Location getLocation() { + if(this.currentLocation == null) + return null; + else + return this.currentLocation.get(); + } + + @Override + public void setLocation(Location newLoc) { + newLoc.addEntity(this); + if(this.currentLocation != null) { + this.currentLocation.get().removeEntity(this); + } + this.currentLocation = new EntityRef(newLoc); + } +} diff --git a/src/main/java/de/welterde/em/Location.java b/src/main/java/de/welterde/em/Location.java index 44add0d..5cb231f 100644 --- a/src/main/java/de/welterde/em/Location.java +++ b/src/main/java/de/welterde/em/Location.java @@ -16,11 +16,18 @@ */ package de.welterde.em; +import de.welterde.em.w.Area; + /** * * @author welterde */ -public interface Location extends Entity { +public interface Location extends Entity, EntityContainer { public short getSecurityLevel(); public Location setSecurityLevel(short newLevel); + + public Area getArea(); + public void setArea(Area area); + + } diff --git a/src/main/java/de/welterde/em/EntityStorage.java b/src/main/java/de/welterde/em/LocationListener.java similarity index 90% rename from src/main/java/de/welterde/em/EntityStorage.java rename to src/main/java/de/welterde/em/LocationListener.java index d75586d..73cc3bc 100644 --- a/src/main/java/de/welterde/em/EntityStorage.java +++ b/src/main/java/de/welterde/em/LocationListener.java @@ -20,6 +20,6 @@ package de.welterde.em; * * @author welterde */ -public interface EntityStorage { - public EntityBase getEntity(int entityId); +public interface LocationListener { + } diff --git a/src/main/java/de/welterde/em/MovableEntity.java b/src/main/java/de/welterde/em/MovableEntity.java new file mode 100644 index 0000000..a04b46d --- /dev/null +++ b/src/main/java/de/welterde/em/MovableEntity.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em; + +/** + * + * @author welterde + */ +public interface MovableEntity extends Entity, Positioned, LocatedEntity { + +} diff --git a/src/main/java/de/welterde/em/PositionTracker.java b/src/main/java/de/welterde/em/PositionTracker.java index 71ac737..67dbf2c 100644 --- a/src/main/java/de/welterde/em/PositionTracker.java +++ b/src/main/java/de/welterde/em/PositionTracker.java @@ -36,5 +36,5 @@ public interface PositionTracker { public void moveEntityCardinal(Entity e, Direction dir); - public void enrollEntity(Entity e, MapCoord startCoord); + public void enrollEntity(LocatedEntity e, MapCoord startCoord); } diff --git a/src/main/java/de/welterde/em/PositionTrackerImpl.java b/src/main/java/de/welterde/em/PositionTrackerImpl.java index f802b57..abf49ba 100644 --- a/src/main/java/de/welterde/em/PositionTrackerImpl.java +++ b/src/main/java/de/welterde/em/PositionTrackerImpl.java @@ -16,17 +16,50 @@ */ package de.welterde.em; +import de.welterde.em.data.Direction; import de.welterde.em.data.MapCoord; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * * @author welterde */ -public class PositionTrackerImpl implements PositionTracker { - - @Override - public MapCoord getPosition(Entity e) { - throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody +public class PositionTrackerImpl implements PositionTracker, LocationListener { + protected Map map; + protected MapCoord coordCenter; + protected Map entityCoord; + + public PositionTrackerImpl(Map map, MapCoord coordCenter) { + this.map = map; + this.coordCenter = coordCenter; + this.entityCoord = new ConcurrentHashMap<>(); } + @Override + public MapCoord getPosition(Entity e) { + var eid = e.getEntityId(); + if(!this.entityCoord.containsKey(eid)) + return null; + var c = this.entityCoord.get(eid); + return this.coordCenter.add(c); + } + + @Override + public void teleportEntity(Entity e, MapCoord destination) { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + @Override + public void moveEntityCardinal(Entity e, Direction dir) { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + @Override + public void enrollEntity(LocatedEntity e, MapCoord startCoord) { + this.entityCoord.put(e.getEntityId(), startCoord); + } + + } diff --git a/src/main/java/de/welterde/em/Positioned.java b/src/main/java/de/welterde/em/Positioned.java index b8f4f36..42da9a5 100644 --- a/src/main/java/de/welterde/em/Positioned.java +++ b/src/main/java/de/welterde/em/Positioned.java @@ -20,7 +20,7 @@ package de.welterde.em; * * @author welterde */ -public interface Positioned { +public interface Positioned extends LocatedEntity { public PositionTracker getPositionTracker(); - public void setPositionTracker(); + public void setPositionTracker(PositionTracker newTracker); } diff --git a/src/main/java/de/welterde/em/data/LocationBase.java b/src/main/java/de/welterde/em/PositionedEntityBase.java similarity index 68% rename from src/main/java/de/welterde/em/data/LocationBase.java rename to src/main/java/de/welterde/em/PositionedEntityBase.java index ad056ad..556dc68 100644 --- a/src/main/java/de/welterde/em/data/LocationBase.java +++ b/src/main/java/de/welterde/em/PositionedEntityBase.java @@ -14,26 +14,24 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.welterde.em.data; - -import de.welterde.em.Location; +package de.welterde.em; /** * * @author welterde */ -public abstract class LocationBase implements Location { +public class PositionedEntityBase extends LocatedEntityBase implements Positioned { - protected short securityLevel; + protected PositionTracker positionTracker; @Override - public short getSecurityLevel() { - return this.securityLevel; + public PositionTracker getPositionTracker() { + return this.positionTracker; + } + + @Override + public void setPositionTracker(PositionTracker newTracker) { + this.positionTracker = newTracker; } - @Override - public Location setSecurityLevel(short newLevel) { - this.securityLevel = newLevel; - return this; - } } diff --git a/src/main/java/de/welterde/em/data/Tile.java b/src/main/java/de/welterde/em/Tile.java similarity index 90% rename from src/main/java/de/welterde/em/data/Tile.java rename to src/main/java/de/welterde/em/Tile.java index 0dcf655..865f130 100644 --- a/src/main/java/de/welterde/em/data/Tile.java +++ b/src/main/java/de/welterde/em/Tile.java @@ -14,9 +14,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.welterde.em.data; +package de.welterde.em; import de.welterde.em.Location; +import de.welterde.em.data.Direction; +import de.welterde.em.data.Entity; +import de.welterde.em.data.TileType; /** * diff --git a/src/main/java/de/welterde/em/TileMap.java b/src/main/java/de/welterde/em/TileMap.java new file mode 100644 index 0000000..d0967cf --- /dev/null +++ b/src/main/java/de/welterde/em/TileMap.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em; + +import de.welterde.em.data.MapCoord; + +/** + * + * @author welterde + */ +public interface TileMap { + public Tile getTile(MapCoord c); +} diff --git a/src/main/java/de/welterde/em/data/BasicEntityCollection.java b/src/main/java/de/welterde/em/data/BasicEntityCollection.java new file mode 100644 index 0000000..b38ed2e --- /dev/null +++ b/src/main/java/de/welterde/em/data/BasicEntityCollection.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em.data; + +import de.welterde.em.EntityContainer; +import java.util.Arrays; +import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import de.welterde.em.GameContext; + +/** + * + * @author welterde + */ +public class BasicEntityCollection implements EntityContainer { + protected final GameContext ctx; + protected Set entities; + protected final ReadWriteLock structLock; + protected Thread houseKeepingThread; + + protected BlockingQueue taskQ; + + public BasicEntityCollection(GameContext ctx) { + this.ctx = ctx; + this.entities = new TreeSet<>(); + this.structLock = new ReentrantReadWriteLock(); + this.taskQ = new LinkedBlockingDeque<>(); + + this.houseKeepingThread = Thread + .ofVirtual() + .name("entitycollection") + .start(() -> this.housekeep()); + } + + @Override + public void addEntity(de.welterde.em.Entity e) { + this.taskQ.add(new Task(e.getEntityId(), false)); + } + @Override + public Iterable listEntities() { + this.structLock.readLock().lock(); + try { + // create copy of the entity list so we can hand out the iterator + final Integer[] ids = new Integer[this.entities.size()]; + this.entities.toArray(ids); + + final Iterable i = () -> Arrays.stream(ids).map(eid -> (de.welterde.em.Entity) this.ctx.getEntity(eid)).iterator(); + return i; + } finally { + this.structLock.readLock().unlock(); + } + } + @Override + public void removeEntity(de.welterde.em.Entity e) { + this.taskQ.add(new Task(e.getEntityId(), true)); + } + + protected void housekeep() { + while(true) { + Task task; + try { + task = this.taskQ.take(); + } catch (InterruptedException ex) { + System.getLogger(BasicEntityCollection.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex); + continue; + } + + this.structLock.writeLock().lock(); + try { + if(task.remove()) { + this.entities.remove(task.eid()); + } else { + this.entities.add(task.eid()); + } + } finally { + this.structLock.writeLock().unlock(); + } + } + } + + record Task(Integer eid, boolean remove) { + + } +} diff --git a/src/main/java/de/welterde/em/data/EntityPosMgr.java b/src/main/java/de/welterde/em/data/EntityPosMgr.java index 62839e4..160e629 100644 --- a/src/main/java/de/welterde/em/data/EntityPosMgr.java +++ b/src/main/java/de/welterde/em/data/EntityPosMgr.java @@ -16,6 +16,8 @@ */ package de.welterde.em.data; +import de.welterde.em.Tile; + /** * Manages position and occupied tiles by entities * diff --git a/src/main/java/de/welterde/em/data/LocationManager.java b/src/main/java/de/welterde/em/data/LocationManager.java index 0e649b8..2b0645f 100644 --- a/src/main/java/de/welterde/em/data/LocationManager.java +++ b/src/main/java/de/welterde/em/data/LocationManager.java @@ -16,6 +16,8 @@ */ package de.welterde.em.data; +import de.welterde.em.loc.Corridor; + /** * Manages locations like rooms, corridors, sectors * @author welterde diff --git a/src/main/java/de/welterde/em/data/MapCoord.java b/src/main/java/de/welterde/em/data/MapCoord.java index feca9f5..1010e2f 100644 --- a/src/main/java/de/welterde/em/data/MapCoord.java +++ b/src/main/java/de/welterde/em/data/MapCoord.java @@ -44,4 +44,8 @@ public record MapCoord(int z, int x, int y) { public MapCoord add(CoordVector v) { return new MapCoord(z + v.dz(), x + v.dx(), y + v.dy()); } + + public MapCoord add(MapCoord c) { + return new MapCoord(this.z + c.z(), this.x + c.x(), this.y + c.y()); + } } diff --git a/src/main/java/de/welterde/em/data/OutpostMap.java b/src/main/java/de/welterde/em/data/OutpostMap.java index 8c4fcb2..a9e3605 100644 --- a/src/main/java/de/welterde/em/data/OutpostMap.java +++ b/src/main/java/de/welterde/em/data/OutpostMap.java @@ -4,6 +4,7 @@ */ package de.welterde.em.data; +import de.welterde.em.Tile; import de.welterde.em.Location; import java.util.EnumMap; import java.util.HashMap; diff --git a/src/main/java/de/welterde/em/data/TerrainGen.java b/src/main/java/de/welterde/em/data/TerrainGen.java index a8dbefa..41beaae 100644 --- a/src/main/java/de/welterde/em/data/TerrainGen.java +++ b/src/main/java/de/welterde/em/data/TerrainGen.java @@ -16,6 +16,8 @@ */ package de.welterde.em.data; +import de.welterde.em.Tile; + /** * * @author welterde diff --git a/src/main/java/de/welterde/em/data/TileImpl.java b/src/main/java/de/welterde/em/data/TileImpl.java index 05a52d0..f12b8a2 100644 --- a/src/main/java/de/welterde/em/data/TileImpl.java +++ b/src/main/java/de/welterde/em/data/TileImpl.java @@ -16,6 +16,7 @@ */ package de.welterde.em.data; +import de.welterde.em.Tile; import de.welterde.em.Location; import de.welterde.em.CollisionException; diff --git a/src/main/java/de/welterde/em/data/gen/BasicTerrainGen.java b/src/main/java/de/welterde/em/data/gen/BasicTerrainGen.java index f788c9e..da0e2d8 100644 --- a/src/main/java/de/welterde/em/data/gen/BasicTerrainGen.java +++ b/src/main/java/de/welterde/em/data/gen/BasicTerrainGen.java @@ -19,7 +19,7 @@ package de.welterde.em.data.gen; import de.welterde.em.data.MapCoord; import de.welterde.em.data.OutpostMap; import de.welterde.em.data.TerrainGen; -import de.welterde.em.data.Tile; +import de.welterde.em.Tile; import de.welterde.em.data.TileImpl; import de.welterde.em.data.TileType; diff --git a/src/main/java/de/welterde/em/e/Employee.java b/src/main/java/de/welterde/em/e/Employee.java index 35b1b97..ef92210 100644 --- a/src/main/java/de/welterde/em/e/Employee.java +++ b/src/main/java/de/welterde/em/e/Employee.java @@ -19,13 +19,14 @@ package de.welterde.em.e; import de.welterde.em.EntityBase; import de.welterde.em.EntityRef; import de.welterde.em.Location; +import de.welterde.em.PositionedEntityBase; import de.welterde.em.w.Org; /** * * @author welterde */ -public class Employee extends EntityBase { +public class Employee extends PositionedEntityBase { protected String name; protected EntityRef employer; diff --git a/src/main/java/de/welterde/em/entity/ItemBase.java b/src/main/java/de/welterde/em/entity/ItemBase.java index a5f14fe..c677605 100644 --- a/src/main/java/de/welterde/em/entity/ItemBase.java +++ b/src/main/java/de/welterde/em/entity/ItemBase.java @@ -17,7 +17,7 @@ package de.welterde.em.entity; import de.welterde.em.EntityBase; -import de.welterde.em.EntityStorage; +import de.welterde.em.GameContext; /** * @@ -25,7 +25,7 @@ import de.welterde.em.EntityStorage; */ public abstract class ItemBase extends EntityBase { - public ItemBase(EntityStorage ctx, int id) { + public ItemBase(GameContext ctx, int id) { super(ctx, id); } } diff --git a/src/main/java/de/welterde/em/io/EntityRecord.java b/src/main/java/de/welterde/em/io/EntityRecord.java index 8f54d17..47cf683 100644 --- a/src/main/java/de/welterde/em/io/EntityRecord.java +++ b/src/main/java/de/welterde/em/io/EntityRecord.java @@ -16,7 +16,7 @@ */ package de.welterde.em.io; -import de.welterde.em.EntityStorage; +import de.welterde.em.GameContext; /** * @@ -24,5 +24,5 @@ import de.welterde.em.EntityStorage; */ public interface EntityRecord { public int getID(); - public EntityStorage getContext(); + public GameContext getContext(); } diff --git a/src/main/java/de/welterde/em/data/Corridor.java b/src/main/java/de/welterde/em/loc/Corridor.java similarity index 92% rename from src/main/java/de/welterde/em/data/Corridor.java rename to src/main/java/de/welterde/em/loc/Corridor.java index 259c6e7..2de9500 100644 --- a/src/main/java/de/welterde/em/data/Corridor.java +++ b/src/main/java/de/welterde/em/loc/Corridor.java @@ -14,8 +14,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.welterde.em.data; +package de.welterde.em.loc; +import de.welterde.em.loc.LocationBase; import de.welterde.em.Location; /** diff --git a/src/main/java/de/welterde/em/loc/LocationBase.java b/src/main/java/de/welterde/em/loc/LocationBase.java new file mode 100644 index 0000000..4c6311e --- /dev/null +++ b/src/main/java/de/welterde/em/loc/LocationBase.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em.loc; + +import de.welterde.em.Entity; +import de.welterde.em.EntityBase; +import de.welterde.em.EntityContainer; +import de.welterde.em.Location; +import de.welterde.em.data.BasicEntityCollection; +import de.welterde.em.w.Area; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import de.welterde.em.GameContext; + +/** + * + * @author welterde + */ +public abstract class LocationBase extends EntityBase implements Location { + + protected short securityLevel; + protected Area area; + protected final ReadWriteLock structLock; + protected EntityContainer entityContainer; + + public LocationBase() { + this.structLock = new ReentrantReadWriteLock(); + + } + + @Override + public short getSecurityLevel() { + return this.securityLevel; + } + + @Override + public Location setSecurityLevel(short newLevel) { + this.securityLevel = newLevel; + return this; + } + + @Override + public Area getArea() { + return this.area; + } + @Override + public void setArea(Area area) { + this.area = area; + } + + @Override + public void initEntity(GameContext ctx, int id) { + super.initEntity(ctx, id); + this.entityContainer = new BasicEntityCollection(ctx); + } + + @Override + public void addEntity(Entity e) { + entityContainer.addEntity(e); + } + + @Override + public Iterable listEntities() { + return entityContainer.listEntities(); + } + + @Override + public void removeEntity(Entity e) { + entityContainer.removeEntity(e); + } + +} diff --git a/src/main/java/de/welterde/em/data/Room.java b/src/main/java/de/welterde/em/loc/Room.java similarity index 92% rename from src/main/java/de/welterde/em/data/Room.java rename to src/main/java/de/welterde/em/loc/Room.java index 1ff20df..7cd24f9 100644 --- a/src/main/java/de/welterde/em/data/Room.java +++ b/src/main/java/de/welterde/em/loc/Room.java @@ -14,8 +14,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.welterde.em.data; +package de.welterde.em.loc; +import de.welterde.em.loc.LocationBase; import de.welterde.em.Location; /** diff --git a/src/main/java/de/welterde/em/room/RoomType.java b/src/main/java/de/welterde/em/loc/RoomType.java similarity index 95% rename from src/main/java/de/welterde/em/room/RoomType.java rename to src/main/java/de/welterde/em/loc/RoomType.java index 5dde24f..a423698 100644 --- a/src/main/java/de/welterde/em/room/RoomType.java +++ b/src/main/java/de/welterde/em/loc/RoomType.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package de.welterde.em.room; +package de.welterde.em.loc; /** * @@ -24,4 +24,5 @@ public enum RoomType { LAB, OFFICE, COMPUTER_ROOM, + LIBRARY, } diff --git a/src/main/java/de/welterde/em/w/Area.java b/src/main/java/de/welterde/em/w/Area.java index 1c8f557..4d8ba27 100644 --- a/src/main/java/de/welterde/em/w/Area.java +++ b/src/main/java/de/welterde/em/w/Area.java @@ -17,29 +17,38 @@ package de.welterde.em.w; import de.welterde.em.EntityBase; -import de.welterde.em.EntityStorage; import de.welterde.em.Location; +import de.welterde.em.Tile; +import de.welterde.em.TileMap; +import de.welterde.em.data.MapCoord; import de.welterde.em.data.TerrainGen; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import de.welterde.em.GameContext; /** * * @author welterde */ -public class Area extends EntityBase { +public class Area extends EntityBase implements TileMap { protected final ReadWriteLock structLock; protected final AreaMap map; protected final Map locations; - public Area(EntityStorage ctx, int id, TerrainGen gen) { - super(ctx, id); + public Area(AreaSetup setup) { this.structLock = new ReentrantReadWriteLock(); this.map = new AreaMap(gen); this.locations = new HashMap<>(); } + + @Override + public Tile getTile(MapCoord c) { + return map.getTile(c); + } + + } diff --git a/src/main/java/de/welterde/em/w/AreaMap.java b/src/main/java/de/welterde/em/w/AreaMap.java index 5dad232..d4f63fb 100644 --- a/src/main/java/de/welterde/em/w/AreaMap.java +++ b/src/main/java/de/welterde/em/w/AreaMap.java @@ -16,6 +16,8 @@ */ package de.welterde.em.w; +import de.welterde.em.Tile; +import de.welterde.em.TileMap; import de.welterde.em.data.MapCoord; import de.welterde.em.data.TerrainGen; import java.util.HashMap; @@ -27,7 +29,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; * * @author welterde */ -public class AreaMap { +public class AreaMap implements TileMap { protected final Map blockMap; protected final TerrainGen gen; protected final ReadWriteLock structLock; @@ -46,4 +48,11 @@ public class AreaMap { return this.tiles.get(c); } } + + @Override + public Tile getTile(MapCoord c) { + throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody + } + + } diff --git a/src/main/java/de/welterde/em/w/AreaSetup.java b/src/main/java/de/welterde/em/w/AreaSetup.java new file mode 100644 index 0000000..99726b7 --- /dev/null +++ b/src/main/java/de/welterde/em/w/AreaSetup.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2026 welterde + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.welterde.em.w; + +/** + * + * @author welterde + */ +public class AreaSetup { + +} diff --git a/src/main/java/de/welterde/em/w/City.java b/src/main/java/de/welterde/em/w/City.java index 27e499e..4bd0be0 100644 --- a/src/main/java/de/welterde/em/w/City.java +++ b/src/main/java/de/welterde/em/w/City.java @@ -17,14 +17,14 @@ package de.welterde.em.w; import de.welterde.em.EntityBase; -import de.welterde.em.EntityStorage; +import de.welterde.em.GameContext; /** * * @author welterde */ public class City extends EntityBase { - public City(EntityStorage ctx, int id) { + public City(GameContext ctx, int id) { super(ctx, id); } } diff --git a/src/main/java/de/welterde/em/w/Country.java b/src/main/java/de/welterde/em/w/Country.java index 5a409b5..99aa973 100644 --- a/src/main/java/de/welterde/em/w/Country.java +++ b/src/main/java/de/welterde/em/w/Country.java @@ -17,7 +17,7 @@ package de.welterde.em.w; import de.welterde.em.EntityBase; -import de.welterde.em.EntityStorage; +import de.welterde.em.GameContext; /** * @@ -25,7 +25,7 @@ import de.welterde.em.EntityStorage; */ public class Country extends EntityBase { - public Country(EntityStorage ctx, int id) { + public Country(GameContext ctx, int id) { super(ctx, id); } diff --git a/src/main/java/de/welterde/em/w/Dimension.java b/src/main/java/de/welterde/em/w/Dimension.java index 978d6d7..d4baae6 100644 --- a/src/main/java/de/welterde/em/w/Dimension.java +++ b/src/main/java/de/welterde/em/w/Dimension.java @@ -40,12 +40,12 @@ public class Dimension extends EntityBase { this.areas = new HashMap<>(); } - public Area addArea(TerrainGen gen) { + public Area createArea(AreaSetup setup) { this.structLock.writeLock().lock(); try { - var areaId = this.ctx.allocateId(CounterName.AREA_IDX); - var area = new Area(areaId, gen); - this.areas.put(areaId, area); + var area = new Area(setup); + var aid = this.ctx.addEntity(area); + this.areas.put(aid, area); return area; } finally { this.structLock.writeLock().unlock(); diff --git a/src/main/java/de/welterde/em/w/Outpost.java b/src/main/java/de/welterde/em/w/Outpost.java index c77ff55..42d6801 100644 --- a/src/main/java/de/welterde/em/w/Outpost.java +++ b/src/main/java/de/welterde/em/w/Outpost.java @@ -18,8 +18,8 @@ package de.welterde.em.w; import de.welterde.em.EntityBase; import de.welterde.em.EntityRef; -import de.welterde.em.EntityStorage; import java.util.EnumSet; +import de.welterde.em.GameContext; /** * @@ -30,7 +30,7 @@ public class Outpost extends EntityBase { protected final OutpostLocationType locationType; protected EntityRef city; - public Outpost(EntityStorage ctx, int id, OutpostLocationType locationType) { + public Outpost(GameContext ctx, int id, OutpostLocationType locationType) { super(ctx, id); this.flags = EnumSet.noneOf(OutpostFlags.class); this.locationType = locationType; diff --git a/src/main/java/de/welterde/em/w/World.java b/src/main/java/de/welterde/em/w/World.java index 0a0a349..350f53c 100644 --- a/src/main/java/de/welterde/em/w/World.java +++ b/src/main/java/de/welterde/em/w/World.java @@ -16,9 +16,10 @@ */ package de.welterde.em.w; +import de.welterde.em.Entity; import de.welterde.em.EntityBase; +import de.welterde.em.EntityContainer; import de.welterde.em.EntityRef; -import de.welterde.em.EntityStorage; import de.welterde.em.data.CounterName; import java.util.ArrayList; import java.util.EnumMap; @@ -28,15 +29,19 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import de.welterde.em.GameContext; /** * * @author welterde */ -public class World implements EntityStorage { - protected final ArrayList entities; +public class World implements GameContext { + // base backing storage of entities and entity components + protected final ArrayList entities; + protected final Map entityContainers; protected final EnumMap counters; + // direct ref to certain top-level entities protected final ArrayList dimensions; protected final Map countries; protected final Map orgs; @@ -46,10 +51,13 @@ public class World implements EntityStorage { protected final AtomicReference state; public World() { + this.entities = new ArrayList<>(); + this.entityContainers = new HashMap<>(); this.counters = new EnumMap<>(CounterName.class); + this.dimensions = new ArrayList<>(); this.countries = new HashMap<>(); - this.entities = new ArrayList<>(); + this.orgs = new HashMap<>(); this.outposts = new HashMap<>(); @@ -58,6 +66,7 @@ public class World implements EntityStorage { } + @Override public int allocateId(CounterName name) { synchronized(this.counters) { // start counter at zero if not yet a thing @@ -90,12 +99,16 @@ public class World implements EntityStorage { } @Override - public EntityBase getEntity(int entityId) { + public Entity getEntity(int entityId) { return this.entities.get(entityId); } + @Override + public EntityContainer getContainer(int entityId) { + return this.entityContainers.getOrDefault(entityId, null); + } - - public void addEntity(EntityBase e) { + @Override + public int addEntity(EntityBase e) { if(e.isEntityInitialized()) throw new IllegalStateException("Entity already initialized"); @@ -132,4 +145,6 @@ public class World implements EntityStorage { } } } + + }