diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ba30ee1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,19 @@ +## General guide + +[Collaboration guide](https://github.com/simon987/Much-Assembly-Required/wiki/Collaboration-Guide) + +## Before creating a pull request + +Here small unordered list of guidelines to read before creating a pull request +- Use java <= 1.8 features +- Please follow [Google's Java style guide](https://google.github.io/styleguide/javaguide.html) +- Constants (e.g. the energy cost of an in-game action) should be loaded from config.properties +- The project is separated into multiple modules, the `Server` module and its plugins. Plugins should +not depend on another plugin to compile or to run. +(e.g. NPC plugin shouldn't import `net.simon987.biomassplugin` ) +- Use `Logmanager.LOGGER` to log messages to the console. Use `.fine()` for debugging messages and `.info()` for +info for more important messages +that are not too frequently used. +- Do not submit a pull request for a new feature that has not been approved +by [simon987](https://github.com/simon987) in an Issue beforehand +- Please state what tests have been performed in the pull request diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java index 237da0d..459ac77 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java @@ -18,10 +18,11 @@ public class CubotComPort extends CpuHardware { private Cubot cubot; - private static final int COMPORT_SELF_CLEAR = 0; + private static final int COMPORT_BUFFER_CLEAR = 0; private static final int COMPORT_POLL = 1; private static final int COMPORT_FRONT_PORT_OUT = 2; private static final int COMPORT_SELF_OUT = 3; + private static final int COMPORT_CONSOLE_CLEAR = 4; public CubotComPort(Cubot cubot) { this.cubot = cubot; @@ -34,9 +35,12 @@ public class CubotComPort extends CpuHardware { int a = getCpu().getRegisterSet().getRegister("A").getValue(); - if (a == COMPORT_SELF_CLEAR) { + if (a == COMPORT_BUFFER_CLEAR) { cubot.getConsoleMessagesBuffer().clear(); + + } else if (a == COMPORT_CONSOLE_CLEAR) { + cubot.setConsoleMode(Cubot.ConsoleMode.CLEAR); } else if (a == COMPORT_POLL) { diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java index e8e749f..975deab 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java @@ -18,8 +18,7 @@ public class CubotDrill extends CpuHardware { public static final int DEFAULT_ADDRESS = 5; private static final int DRILL_POLL = 1; - private static final int DRILL_GATHER_SLOW = 2; - private static final int DRILL_GATHER_FAST = 3; + private static final int DRILL_GATHER = 2; // simplified gather private Cubot cubot; @@ -40,7 +39,7 @@ public class CubotDrill extends CpuHardware { getCpu().getRegisterSet().getRegister("B").setValue(0); - } else if (a == DRILL_GATHER_SLOW || a == DRILL_GATHER_FAST) { + } else if (a == DRILL_GATHER) { if (cubot.spendEnergy(1400)) { if (cubot.getCurrentAction() == Action.IDLE) { diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java index 1fe5579..396a8e1 100644 --- a/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java +++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/HarvesterNPC.java @@ -3,9 +3,11 @@ package net.simon987.npcplugin; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import net.simon987.server.GameServer; +import net.simon987.server.event.ObjectDeathEvent; import net.simon987.server.game.Direction; import org.json.simple.JSONObject; + public class HarvesterNPC extends NonPlayerCharacter { public static final int ID = 10; @@ -39,11 +41,19 @@ public class HarvesterNPC extends NonPlayerCharacter { //Self-destroy when age limit is reached if (getAge() >= NonPlayerCharacter.LIFETIME) { setDead(true); - getFactory().getNpcs().remove(this); } } } + @Override + public void onDeadCallback() { + + getFactory().getNpcs().remove(this); + + GameServer.INSTANCE.getEventDispatcher().dispatch( + new ObjectDeathEvent(this, ID)); + } + @Override public JSONObject serialise() { JSONObject json = super.serialise(); diff --git a/Plugin Plant/src/main/java/net/simon987/biomassplugin/BiomassPlugin.java b/Plugin Plant/src/main/java/net/simon987/biomassplugin/BiomassPlugin.java index 6465720..fe5ab0a 100644 --- a/Plugin Plant/src/main/java/net/simon987/biomassplugin/BiomassPlugin.java +++ b/Plugin Plant/src/main/java/net/simon987/biomassplugin/BiomassPlugin.java @@ -1,6 +1,7 @@ package net.simon987.biomassplugin; import com.mongodb.DBObject; +import net.simon987.biomassplugin.event.ObjectDeathListener; import net.simon987.biomassplugin.event.WorldCreationListener; import net.simon987.biomassplugin.event.WorldUpdateListener; import net.simon987.server.ServerConfiguration; @@ -16,6 +17,7 @@ public class BiomassPlugin extends ServerPlugin implements GameObjectDeserialize public void init(ServerConfiguration config) { listeners.add(new WorldCreationListener()); listeners.add(new WorldUpdateListener(config)); + listeners.add(new ObjectDeathListener(config)); LogManager.LOGGER.info("Initialised Biomass plugin"); } diff --git a/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java new file mode 100644 index 0000000..036352e --- /dev/null +++ b/Plugin Plant/src/main/java/net/simon987/biomassplugin/event/ObjectDeathListener.java @@ -0,0 +1,66 @@ +package net.simon987.biomassplugin.event; + +import net.simon987.biomassplugin.BiomassBlob; +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.ObjectDeathEvent; +import net.simon987.server.game.GameObject; +import net.simon987.server.game.World; +import net.simon987.server.logging.LogManager; + +/** + * Handles ObjectDeathEvent events + */ +public class ObjectDeathListener implements GameEventListener { + + private int biomassDropCount; + + public ObjectDeathListener(ServerConfiguration config) { + biomassDropCount = config.getInt("harvester_biomass_drop_count"); + + } + + @Override + public Class getListenedEventType() { + return ObjectDeathEvent.class; + } + + @Override + public void handle(GameEvent event) { + // a HarvesterNPC ObjectDeathEvent is received + // TODO: setup enum with all GameObject type IDs + if (((ObjectDeathEvent) event).getSourceObjectId() == 10) { + GameObject dyingHarvesterNPC = (GameObject)event.getSource(); + + // create a new biomass + BiomassBlob newBiomassBlob = createBiomassBlobAt( + dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); + // add it to the world game objects + dyingHarvesterNPC.getWorld().getGameObjects().add(newBiomassBlob); + LogManager.LOGGER.fine("Spawned biomass at (" + newBiomassBlob.getX() + + ", " + newBiomassBlob.getY() + ")"); + } + } + + /** + * Create and return a biomass at the given x, y coordinates and in the world + * @param x x coord of biomass location + * @param y y coord of biomass location + * @param world world in which the biomass will be created in + * @return the new BiomassBlob created + */ + private BiomassBlob createBiomassBlobAt(int x, int y, World world) { + + 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(biomassDropCount); + biomassBlob.setX(x); + biomassBlob.setY(y); + biomassBlob.setWorld(world); + + return biomassBlob; + } +} diff --git a/README.md b/README.md index fb75a06..0affdd2 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,38 @@ cd target java -jar server-1.2a.jar ``` -## Windows -Coming eventually... +## Windows (tested on Windows 10) + +Installation instructions: +1. Download the JDK from [here](http://www.oracle.com/technetwork/java/javase/downloads/index.html). +Install the JDK and update your PATH and JAVA_HOME enviroment variables. +2. Download Maven from [here](https://maven.apache.org/). +Install Maven (following the README) and update your PATH enviroment variable. +3. Download Mongo DB Community from [here](https://www.mongodb.com/download-center#community). +Install Mongo DB following the instructions [here](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/). +Update your PATH enviroment variable. + +Building instructions: +```batch +:: Builds the server +cd Much-Assembly-Required +mvn package +``` + +Running instructions: +1. In one Command Prompt window, run Mongo DB: +```batch +:: Runs Mongo DB +mongod +``` +2. In a second Command Prompt window, run the MAR server: +```batch +:: Runs the MAR server +cd Much-Assembly-Required\target +java -jar server-1.2a.jar +``` +3. Run the frontend, following the instructions that you can find [here](https://github.com/simon987/Much-Assembly-Required-Frontend). + ## Docker ### Requirements diff --git a/Server/Server.iml b/Server/Server.iml index 9c5747d..52af955 100644 --- a/Server/Server.iml +++ b/Server/Server.iml @@ -19,4 +19,4 @@ - \ No newline at end of file + diff --git a/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java b/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java new file mode 100644 index 0000000..8fddae3 --- /dev/null +++ b/Server/src/main/java/net/simon987/server/event/ObjectDeathEvent.java @@ -0,0 +1,18 @@ +package net.simon987.server.event; + +/** + * Event dispatched by a GameObject who has needed callbacks on death + */ +public class ObjectDeathEvent extends GameEvent { + /** + * The GameObject type ID of object that init this event + */ + private int sourceObjectId; + + public ObjectDeathEvent(Object source, int sourceObjectId) { + setSource(source); + this.sourceObjectId = sourceObjectId; + } + + public int getSourceObjectId() { return sourceObjectId; } +} diff --git a/Server/src/main/java/net/simon987/server/game/GameObject.java b/Server/src/main/java/net/simon987/server/game/GameObject.java index f712e78..d7d958e 100755 --- a/Server/src/main/java/net/simon987/server/game/GameObject.java +++ b/Server/src/main/java/net/simon987/server/game/GameObject.java @@ -254,4 +254,9 @@ public abstract class GameObject implements JSONSerialisable, MongoSerialisable public void setDead(boolean dead) { this.dead = dead; } + + /** + * Called before this GameObject is removed from the world - defaults to doing nothing + */ + public void onDeadCallback() { } } \ No newline at end of file diff --git a/Server/src/main/java/net/simon987/server/game/World.java b/Server/src/main/java/net/simon987/server/game/World.java index 33d60d0..2bcca90 100644 --- a/Server/src/main/java/net/simon987/server/game/World.java +++ b/Server/src/main/java/net/simon987/server/game/World.java @@ -104,6 +104,7 @@ public class World implements MongoSerialisable { for (GameObject object : gameObjects_) { //Clean up dead objects if (object.isDead()) { + object.onDeadCallback(); gameObjects.remove(object); //LogManager.LOGGER.fine("Removed object " + object + " id: " + object.getObjectId()); } else if (object instanceof Updatable) { diff --git a/Server/src/main/resources/config.properties b/Server/src/main/resources/config.properties index c26b4d3..1c925dc 100644 --- a/Server/src/main/resources/config.properties +++ b/Server/src/main/resources/config.properties @@ -62,6 +62,8 @@ factory_max_npc_count=16 harvester_hp_max=100 # Harvester hp regeneration per tick harvester_regen=5 +# Number of biomass units dropped on death +harvester_biomass_drop_count=8 # ---------------------------------------------- # Minimum center point count for the WorldGenerator wg_centerPointCountMin=5