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