Added getCount() method to World

This commit is contained in:
Khalid Ali 2020-09-18 10:07:57 -04:00
parent a92256008c
commit 2ee98a8439
3 changed files with 63 additions and 61 deletions

View File

@ -24,15 +24,7 @@ public class WorldUtils {
// of blobs, // of blobs,
// set the desired amount of blobs to the plain tile count // set the desired amount of blobs to the plain tile count
TileMap m = world.getTileMap(); TileMap m = world.getTileMap();
int plainCount = 0; int plainCount = world.getCount(TilePlain.ID);
for (int y = 0; y < world.getWorldSize(); y++) {
for (int x = 0; x < world.getWorldSize(); x++) {
if (m.getTileIdAt(x, y) == TilePlain.ID) {
plainCount++;
}
}
}
if (blobCount > plainCount) { if (blobCount > plainCount) {
blobCount = plainCount; blobCount = plainCount;

View File

@ -12,7 +12,7 @@ import java.util.Random;
public class RadioactiveWorldUtils { public class RadioactiveWorldUtils {
/** /**
* Generate a list of biomass blobs for a world * Generate a list of radioactive obstacles for a world
*/ */
public static ArrayList<RadioactiveObstacle> generateRadioactiveObstacles(World world, int minCount, int maxCount) { public static ArrayList<RadioactiveObstacle> generateRadioactiveObstacles(World world, int minCount, int maxCount) {
@ -24,15 +24,7 @@ public class RadioactiveWorldUtils {
// of radioactive objects, set the desired amount of radioactive objects to the // of radioactive objects, set the desired amount of radioactive objects to the
// plain tile count // plain tile count
TileMap m = world.getTileMap(); TileMap m = world.getTileMap();
int plainCount = 0; int plainCount = world.getCount(TilePlain.ID);
for (int y = 0; y < world.getWorldSize(); y++) {
for (int x = 0; x < world.getWorldSize(); x++) {
if (m.getTileIdAt(x, y) == TilePlain.ID) {
plainCount++;
}
}
}
if (radioactiveObjCount > plainCount) { if (radioactiveObjCount > plainCount) {
radioactiveObjCount = plainCount; radioactiveObjCount = plainCount;

View File

@ -61,7 +61,8 @@ public class World implements MongoSerializable {
} }
/** /**
* Check if a tile is blocked, either by a game object or an impassable tile type * Check if a tile is blocked, either by a game object or an impassable tile
* type
*/ */
public boolean isTileBlocked(int x, int y) { public boolean isTileBlocked(int x, int y) {
return getGameObjectsBlockingAt(x, y).size() > 0 || tileMap.getTileAt(x, y).isBlocked(); return getGameObjectsBlockingAt(x, y).size() > 0 || tileMap.getTileAt(x, y).isBlocked();
@ -84,7 +85,7 @@ public class World implements MongoSerializable {
* *
* @return long * @return long
*/ */
public String getId(){ public String getId() {
return World.idFromCoordinates(x, y, dimension); return World.idFromCoordinates(x, y, dimension);
} }
@ -136,22 +137,22 @@ public class World implements MongoSerializable {
} }
/** /**
* Update this World and its GameObjects * Update this World and its GameObjects <br>
* <br>
* The update is handled by plugins first * The update is handled by plugins first
*/ */
public void update() { public void update() {
//Dispatch update event // Dispatch update event
GameEvent event = new WorldUpdateEvent(this); GameEvent event = new WorldUpdateEvent(this);
GameServer.INSTANCE.getEventDispatcher().dispatch(event); //Ignore cancellation GameServer.INSTANCE.getEventDispatcher().dispatch(event); // Ignore cancellation
for (GameObject object : gameObjects.values()) { for (GameObject object : gameObjects.values()) {
//Clean up dead objects // Clean up dead objects
if (object.isDead()) { if (object.isDead()) {
if (!object.onDeadCallback()) { if (!object.onDeadCallback()) {
removeObject(object); removeObject(object);
//LogManager.LOGGER.fine("Removed object " + object + " id: " + object.getObjectId()); // LogManager.LOGGER.fine("Removed object " + object + " id: " +
// object.getObjectId());
} else if (object instanceof Updatable) { } else if (object instanceof Updatable) {
((Updatable) object).update(); ((Updatable) object).update();
} }
@ -182,7 +183,7 @@ public class World implements MongoSerializable {
dbObject.put("size", worldSize); dbObject.put("size", worldSize);
dbObject.put("updatable", updatable); dbObject.put("updatable", updatable);
dbObject.put("shouldUpdate",shouldUpdate()); dbObject.put("shouldUpdate", shouldUpdate());
return dbObject; return dbObject;
} }
@ -231,17 +232,17 @@ public class World implements MongoSerializable {
} }
/** /**
* Get a binary representation of the map as an array of 16-bit bit fields, one word for each * Get a binary representation of the map as an array of 16-bit bit fields, one
* tile. * word for each tile.
* <p> * <p>
* Each tile is represented as such: <code>OOOOOOOOTTTTTTTB</code> where O is the object, * Each tile is represented as such: <code>OOOOOOOOTTTTTTTB</code> where O is
* T the tile and B if the tile is blocked or not * the object, T the tile and B if the tile is blocked or not
*/ */
public char[][] getMapInfo() { public char[][] getMapInfo() {
char[][] mapInfo = new char[worldSize][worldSize]; char[][] mapInfo = new char[worldSize][worldSize];
//Tile // Tile
for (int x = 0; x < worldSize; x++) { for (int x = 0; x < worldSize; x++) {
for (int y = 0; y < worldSize; y++) { for (int y = 0; y < worldSize; y++) {
Tile tile = tileMap.getTileAt(x, y); Tile tile = tileMap.getTileAt(x, y);
@ -252,7 +253,8 @@ public class World implements MongoSerializable {
} }
for (GameObject obj : gameObjects.values()) { for (GameObject obj : gameObjects.values()) {
//Overwrite, only the last object on a tile is considered but the blocked bit is kept // Overwrite, only the last object on a tile is considered but the blocked bit
// is kept
mapInfo[obj.getX()][obj.getY()] &= 0x00FE; mapInfo[obj.getX()][obj.getY()] &= 0x00FE;
mapInfo[obj.getX()][obj.getY()] |= obj.getMapInfo(); mapInfo[obj.getX()][obj.getY()] |= obj.getMapInfo();
} }
@ -261,12 +263,11 @@ public class World implements MongoSerializable {
} }
/** /**
* Get a random tile that is empty and passable * Get a random tile that is empty and passable The function ensures that a
* The function ensures that a object spawned there will not be trapped * object spawned there will not be trapped and will be able to leave the World
* and will be able to leave the World
* <br> * <br>
* Note: This function is quite expensive and shouldn't be used * Note: This function is quite expensive and shouldn't be used by some
* by some HardwareModule in its current state * HardwareModule in its current state
* *
* @return random non-blocked tile * @return random non-blocked tile
*/ */
@ -277,7 +278,7 @@ public class World implements MongoSerializable {
while (true) { while (true) {
counter++; counter++;
//Prevent infinite loop // Prevent infinite loop
if (counter >= 1000) { if (counter >= 1000) {
return null; return null;
} }
@ -318,10 +319,9 @@ public class World implements MongoSerializable {
} }
/** /**
* Get the list of game objects that are exactly at a given location * Get the list of game objects that are exactly at a given location <br>
* <br> * Note: Objects like the Factory that are more than 1x1 tiles wide will only be
* Note: Objects like the Factory that are more than 1x1 tiles wide will only be returned * returned when their exact coordinates are specified
* when their exact coordinates are specified
* *
* @param x X coordinate on the World * @param x X coordinate on the World
* @param y Y coordinate on the World * @param y Y coordinate on the World
@ -355,29 +355,28 @@ public class World implements MongoSerializable {
return worldSize; return worldSize;
} }
private GameUniverse universe = null; private GameUniverse universe = null;
public void setUniverse(GameUniverse universe){ public void setUniverse(GameUniverse universe) {
this.universe = universe; this.universe = universe;
} }
private ArrayList<World> getNeighbouringLoadedWorlds() { private ArrayList<World> getNeighbouringLoadedWorlds() {
ArrayList<World> neighbouringWorlds = new ArrayList<>(); ArrayList<World> neighbouringWorlds = new ArrayList<>();
if (universe == null){ if (universe == null) {
return neighbouringWorlds; return neighbouringWorlds;
} }
for (int dx=-1; dx<=+1; dx+=2){ for (int dx = -1; dx <= +1; dx += 2) {
World nw = universe.getLoadedWorld(x + dx, y, dimension); World nw = universe.getLoadedWorld(x + dx, y, dimension);
if (nw != null){ if (nw != null) {
neighbouringWorlds.add(nw); neighbouringWorlds.add(nw);
} }
} }
for (int dy=-1; dy<=+1; dy+=2){ for (int dy = -1; dy <= +1; dy += 2) {
World nw = universe.getLoadedWorld(x, y + dy, dimension); World nw = universe.getLoadedWorld(x, y + dy, dimension);
if (nw != null){ if (nw != null) {
neighbouringWorlds.add(nw); neighbouringWorlds.add(nw);
} }
} }
@ -385,14 +384,14 @@ public class World implements MongoSerializable {
return neighbouringWorlds; return neighbouringWorlds;
} }
public boolean canUnload(){ public boolean canUnload() {
return updatable==0; return updatable == 0;
} }
public boolean shouldUnload(){ public boolean shouldUnload() {
boolean res = canUnload(); boolean res = canUnload();
for (World nw : getNeighbouringLoadedWorlds() ){ for (World nw : getNeighbouringLoadedWorlds()) {
res &= nw.canUnload(); res &= nw.canUnload();
} }
@ -403,6 +402,24 @@ public class World implements MongoSerializable {
return gameObjects.values(); return gameObjects.values();
} }
/**
* Find the number of tiles of a given type on the world.
*
* @param tileId id of tile
* @return number of occurrences
*/
public int getCount(int tileId) {
int tileCount = 0;
for (int y = 0; y < getWorldSize(); y++) {
for (int x = 0; x < getWorldSize(); x++) {
if (tileMap.getTileIdAt(x, y) == tileId) {
tileCount++;
}
}
}
return tileCount;
}
/** /**
* Get a random tile with N adjacent non-blocked tile * Get a random tile with N adjacent non-blocked tile
@ -412,12 +429,12 @@ public class World implements MongoSerializable {
*/ */
public Point getRandomTileWithAdjacent(int n, int tile) { public Point getRandomTileWithAdjacent(int n, int tile) {
int counter = 0; int counter = 0;
int[] xPositions = {1, 0, -1, 0, 1, -1, 1, -1}; int[] xPositions = { 1, 0, -1, 0, 1, -1, 1, -1 };
int[] yPositions = {0, 1, 0, -1, 1, 1, -1, -1}; int[] yPositions = { 0, 1, 0, -1, 1, 1, -1, -1 };
while (true) { while (true) {
counter++; counter++;
//Prevent infinite loop // Prevent infinite loop
if (counter >= 2500) { if (counter >= 2500) {
return null; return null;
} }
@ -428,7 +445,8 @@ public class World implements MongoSerializable {
int adjacentTiles = 0; int adjacentTiles = 0;
for (int idx = 0; idx < xPositions.length; idx++) { for (int idx = 0; idx < xPositions.length; idx++) {
if (tileMap.isInBounds(rTile.x + xPositions[idx], rTile.y + yPositions[idx]) && !isTileBlocked(rTile.x + xPositions[idx], rTile.y + yPositions[idx])) { if (tileMap.isInBounds(rTile.x + xPositions[idx], rTile.y + yPositions[idx])
&& !isTileBlocked(rTile.x + xPositions[idx], rTile.y + yPositions[idx])) {
adjacentTiles++; adjacentTiles++;
} }
} }