Added biomass respawn feature #22

This commit is contained in:
simon
2017-12-02 10:26:59 -05:00
parent 29cac77e79
commit be45979ed0
20 changed files with 309 additions and 189 deletions

View File

@@ -1,19 +1,20 @@
package net.simon987.plantplugin;
package net.simon987.biomassplugin;
import net.simon987.server.game.GameObject;
import net.simon987.server.game.InventoryHolder;
import org.json.simple.JSONObject;
public class Plant extends GameObject implements InventoryHolder {
public class BiomassBlob extends GameObject implements InventoryHolder {
private static final char MAP_INFO = 0x4000;
public static final int ID = 2;
/**
* Yield of the plant, in biomass units
* Yield of the blob, in biomass units
*/
private int biomassCount;
/**
* Style of the plant (Only visual)
* Style of the blob (Only visual)
*/
private int style;
@@ -56,28 +57,28 @@ public class Plant extends GameObject implements InventoryHolder {
this.style = style;
}
public static Plant deserialize(JSONObject json) {
public static BiomassBlob deserialize(JSONObject json) {
Plant plant = new Plant();
BiomassBlob biomassBlob = new BiomassBlob();
plant.setObjectId((int) (long) json.get("id"));
plant.setX((int) (long) json.get("x"));
plant.setY((int) (long) json.get("y"));
plant.style = (int) (long) json.get("style");
plant.biomassCount = (int) (long) json.get("biomassCount");
biomassBlob.setObjectId((int) (long) json.get("id"));
biomassBlob.setX((int) (long) json.get("x"));
biomassBlob.setY((int) (long) json.get("y"));
biomassBlob.style = (int) (long) json.get("style");
biomassBlob.biomassCount = (int) (long) json.get("biomassCount");
return plant;
return biomassBlob;
}
/**
* Called when an object attempts to place an item in this Plant
* Called when an object attempts to place an item in this BiomassBlob
*
* @param item item id (see MarConstants.ITEM_*)
* @return Always returns false
*/
@Override
public boolean placeItem(int item) {
//Why would you want to place an item in a plant?
//Why would you want to place an item in a blob?
return false;
}
@@ -87,7 +88,7 @@ public class Plant extends GameObject implements InventoryHolder {
}
/**
* Called when an object attempts to take an item from this Plant.
* Called when an object attempts to take an item from this BiomassBlob.
* If the object requests biomass, it will be subtracted from biomassCount, and
* if it reaches 0, the plant is deleted
*

View File

@@ -0,0 +1,35 @@
package net.simon987.biomassplugin;
import net.simon987.biomassplugin.event.WorldCreationListener;
import net.simon987.biomassplugin.event.WorldUpdateListener;
import net.simon987.server.ServerConfiguration;
import net.simon987.server.game.GameObject;
import net.simon987.server.io.GameObjectDeserializer;
import net.simon987.server.logging.LogManager;
import net.simon987.server.plugin.ServerPlugin;
import org.json.simple.JSONObject;
public class BiomassPlugin extends ServerPlugin implements GameObjectDeserializer {
@Override
public void init(ServerConfiguration config) {
listeners.add(new WorldCreationListener());
listeners.add(new WorldUpdateListener(config));
LogManager.LOGGER.info("Initialised Biomass plugin");
}
@Override
public GameObject deserializeObject(JSONObject object) {
int objType = (int) (long) object.get("type");
if (objType == BiomassBlob.ID) {
return BiomassBlob.deserialize(object);
}
return null;
}
}

View File

@@ -0,0 +1,83 @@
package net.simon987.biomassplugin;
import net.simon987.server.GameServer;
import net.simon987.server.game.World;
import net.simon987.server.logging.LogManager;
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;
public class WorldUtils {
/**
* Generate a list of biomass blobs for a world
*/
public static ArrayList<BiomassBlob> generateBlobs(World world, int minCount, int maxCount, int yield) {
System.out.println("Generating blobs...");
Random random = new Random();
int blobCount = random.nextInt(maxCount - minCount) + minCount;
ArrayList<BiomassBlob> biomassBlobs = new ArrayList<>(maxCount);
//Count number of plain tiles. If there is less plain tiles than desired amount of blobs,
//set the desired amount of blobs to the plain tile count
int[][] tiles = world.getTileMap().getTiles();
int plainCount = 0;
for (int y = 0; y < World.WORLD_SIZE; y++) {
for (int x = 0; x < World.WORLD_SIZE; x++) {
if (tiles[x][y] == 0) {
plainCount++;
}
}
}
if (blobCount > plainCount) {
blobCount = plainCount;
}
outerLoop:
for (int i = 0; i < blobCount; i++) {
Point p = world.getTileMap().getRandomPlainTile();
if (p != null) {
//Don't block worlds
int counter = 0;
while (p.x == 0 || p.y == 0 || p.x == World.WORLD_SIZE - 1 || p.y == World.WORLD_SIZE - 1 ||
world.isTileBlocked(p.x, p.y)) {
p = world.getTileMap().getRandomPlainTile();
counter++;
if (counter > 25) {
continue outerLoop;
}
}
for (BiomassBlob biomassBlob : biomassBlobs) {
if (biomassBlob.getX() == p.x && biomassBlob.getY() == p.y) {
//There is already a blob here
continue outerLoop;
}
}
BiomassBlob biomassBlob = new BiomassBlob();
biomassBlob.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
biomassBlob.setStyle(0); //TODO: set style depending on difficulty level? or random? from config?
biomassBlob.setBiomassCount(yield);
biomassBlob.setX(p.x);
biomassBlob.setY(p.y);
biomassBlob.setWorld(world);
biomassBlobs.add(biomassBlob);
}
}
LogManager.LOGGER.info("Generated " + biomassBlobs.size() + " biomassBlobs for World (" + world.getX() + ',' +
world.getY() + ')');
return biomassBlobs;
}
}

View File

@@ -0,0 +1,31 @@
package net.simon987.biomassplugin.event;
import net.simon987.biomassplugin.BiomassBlob;
import net.simon987.biomassplugin.WorldUtils;
import net.simon987.server.GameServer;
import net.simon987.server.event.GameEvent;
import net.simon987.server.event.GameEventListener;
import net.simon987.server.event.WorldGenerationEvent;
import java.util.ArrayList;
public class WorldCreationListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return WorldGenerationEvent.class;
}
@Override
public void handle(GameEvent event) {
int minCount = GameServer.INSTANCE.getConfig().getInt("minBiomassCount");
int maxCount = GameServer.INSTANCE.getConfig().getInt("maxBiomassCount");
int yield = GameServer.INSTANCE.getConfig().getInt("biomass_yield");
ArrayList<BiomassBlob> biomassBlobs = WorldUtils.generateBlobs(((WorldGenerationEvent) event).getWorld(),
minCount, maxCount, yield);
((WorldGenerationEvent) event).getWorld().getGameObjects().addAll(biomassBlobs);
}
}

View File

@@ -0,0 +1,72 @@
package net.simon987.biomassplugin.event;
import net.simon987.biomassplugin.BiomassBlob;
import net.simon987.biomassplugin.WorldUtils;
import net.simon987.server.GameServer;
import net.simon987.server.ServerConfiguration;
import net.simon987.server.event.GameEvent;
import net.simon987.server.event.GameEventListener;
import net.simon987.server.event.WorldUpdateEvent;
import net.simon987.server.game.World;
import java.util.ArrayList;
import java.util.HashMap;
public class WorldUpdateListener implements GameEventListener {
private HashMap<World, Long> worldWaitMap = new HashMap<>(200);
private int minBlobCount;
private int maxBlobCount;
private int blobYield;
private int waitTime;
private int blobThreshold;
public WorldUpdateListener(ServerConfiguration config) {
minBlobCount = config.getInt("minBiomassRespawnCount");
maxBlobCount = config.getInt("maxBiomassRespawnCount");
waitTime = config.getInt("biomassRespawnTime");
blobThreshold = config.getInt("biomassRespawnThreshold");
blobYield = config.getInt("biomass_yield");
}
@Override
public Class getListenedEventType() {
return WorldUpdateEvent.class;
}
@Override
public void handle(GameEvent event) {
World world = ((WorldUpdateEvent) event).getWorld();
//If there is less than the respawn threshold,
if (world.getGameObjects(BiomassBlob.class).size() < blobThreshold) {
//Set a timer for respawn_time ticks
if (!worldWaitMap.containsKey(world) || worldWaitMap.get(world) == 0L) {
worldWaitMap.put(world, GameServer.INSTANCE.getGameUniverse().getTime() + waitTime);
} else {
long waitUntil = worldWaitMap.get(world);
if (GameServer.INSTANCE.getGameUniverse().getTime() >= waitUntil) {
//If the timer was set less than respawn_time ticks ago, respawn the blobs
ArrayList<BiomassBlob> newBlobs = WorldUtils.generateBlobs(world, minBlobCount,
maxBlobCount, blobYield);
world.getGameObjects().addAll(newBlobs);
//Set the 'waitUntil' time to 0 to indicate that we are not waiting
worldWaitMap.replace(world, 0L);
}
}
}
}
}

View File

@@ -1,31 +0,0 @@
package net.simon987.plantplugin;
import net.simon987.plantplugin.event.WorldCreationListener;
import net.simon987.server.game.GameObject;
import net.simon987.server.io.GameObjectDeserializer;
import net.simon987.server.logging.LogManager;
import net.simon987.server.plugin.ServerPlugin;
import org.json.simple.JSONObject;
public class PlantPlugin extends ServerPlugin implements GameObjectDeserializer {
@Override
public void init() {
listeners.add(new WorldCreationListener());
LogManager.LOGGER.info("Initialised Plant plugin");
}
@Override
public GameObject deserializeObject(JSONObject object) {
int objType = (int) (long) object.get("type");
if (objType == Plant.ID) {
return Plant.deserialize(object);
}
return null;
}
}

View File

@@ -1,95 +0,0 @@
package net.simon987.plantplugin.event;
import net.simon987.plantplugin.Plant;
import net.simon987.server.GameServer;
import net.simon987.server.event.GameEvent;
import net.simon987.server.event.GameEventListener;
import net.simon987.server.event.WorldGenerationEvent;
import net.simon987.server.game.World;
import net.simon987.server.logging.LogManager;
import java.awt.*;
import java.util.ArrayList;
import java.util.Random;
public class WorldCreationListener implements GameEventListener {
@Override
public Class getListenedEventType() {
return WorldGenerationEvent.class;
}
@Override
public void handle(GameEvent event) {
ArrayList<Plant> plants = generatePlants(((WorldGenerationEvent) event).getWorld());
((WorldGenerationEvent) event).getWorld().getGameObjects().addAll(plants);
}
/**
* Generate a list of plants for a world
*/
public ArrayList<Plant> generatePlants(World world) {
int minTreeCount = GameServer.INSTANCE.getConfig().getInt("minTreeCount");
int maxTreeCount = GameServer.INSTANCE.getConfig().getInt("maxTreeCount");
int plant_yield = GameServer.INSTANCE.getConfig().getInt("plant_yield");
Random random = new Random();
int treeCount = random.nextInt(maxTreeCount - minTreeCount) + minTreeCount;
ArrayList<Plant> plants = new ArrayList<>(maxTreeCount);
//Count number of plain tiles. If there is less plain tiles than desired amount of trees,
//set the desired amount of trees to the plain tile count
int[][] tiles = world.getTileMap().getTiles();
int plainCount = 0;
for (int y = 0; y < World.WORLD_SIZE; y++) {
for (int x = 0; x < World.WORLD_SIZE; x++) {
if (tiles[x][y] == 0) {
plainCount++;
}
}
}
if (treeCount > plainCount) {
treeCount = plainCount;
}
outerLoop:
for (int i = 0; i < treeCount; i++) {
Point p = world.getTileMap().getRandomPlainTile();
if (p != null) {
//Don't block worlds
while (p.x == 0 || p.y == 0 || p.x == World.WORLD_SIZE - 1 || p.y == World.WORLD_SIZE - 1) {
p = world.getTileMap().getRandomPlainTile();
}
for (Plant plant : plants) {
if (plant.getX() == p.x && plant.getY() == p.y) {
//There is already a plant here
continue outerLoop;
}
}
Plant plant = new Plant();
plant.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
plant.setStyle(0); //TODO: set style depending on difficulty level? or random? from config?
plant.setBiomassCount(plant_yield);
plant.setX(p.x);
plant.setY(p.y);
plant.setWorld(world);
plants.add(plant);
}
}
LogManager.LOGGER.info("Generated " + plants.size() + " plants for World (" + world.getX() + ',' +
world.getY() + ')');
return plants;
}
}

View File

@@ -1,3 +1,3 @@
classpath=net.simon987.plantplugin.PlantPlugin
name=Plant Plugin
classpath=net.simon987.biomassplugin.BiomassPlugin
name=Biomass Plugin
version=1.0