diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java
index 1bdf597..f7693d3 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java
@@ -91,25 +91,10 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
*/
private User parent;
- /**
- * Energy units in kJ
- */
- private int energy;
-
- /**
- * Maximum energy units in kJ
- */
- private int maxEnergy;
-
- /**
- * Solar panel multiplier
- *
TODO: Set this constant in dimension
- */
- private static final float SOLAR_PANEL_MULTIPLIER = 1;
/**
* Maximum size of the console buffer (also called 'internal buffer')
*/
- private static final int CONSOLE_BUFFER_MAX_SIZE = 40;
+ public static final int CONSOLE_BUFFER_MAX_SIZE = 40;
/**
* List of attached hardware, 'modules'
@@ -143,10 +128,8 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
hp = document.getInteger("hp");
shield = document.getInteger("shield");
setDirection(Direction.getDirection(document.getInteger("direction")));
- energy = document.getInteger("energy");
ServerConfiguration config = GameServer.INSTANCE.getConfig();
- maxEnergy = config.getInt("battery_max_energy");
maxHp = config.getInt("cubot_max_hp");
maxShield = config.getInt("cubot_max_shield");
@@ -176,8 +159,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
@Override
public void update() {
- storeEnergy((int) (SOLAR_PANEL_MULTIPLIER * GameServer.INSTANCE.getDayNightCycle().getSunIntensity()));
-
if (currentAction == Action.WALKING) {
if (spendEnergy(100)) {
if (!incrementLocation()) {
@@ -225,7 +206,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
json.put("hp", hp);
json.put("shield", shield);
json.put("action", lastAction.ordinal());
- json.put("energy", energy);
if (parent != null) {
json.put("parent", parent.getUsername()); //Only used client-side for now
@@ -249,7 +229,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
dbObject.put("hp", hp);
dbObject.put("shield", shield);
dbObject.put("action", lastAction.ordinal());
- dbObject.put("energy", energy);
if (parent != null) {
dbObject.put("parent", parent.getUsername()); //Only used client-side for now
@@ -279,7 +258,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
setDead(false);
setHp(maxHp);
setShield(0);
- setEnergy(maxEnergy);
+ setEnergy(((CubotBattery) getHardware(CubotBattery.class)).getMaxEnergy());
clearKeyboardBuffer();
consoleMessagesBuffer.clear();
lastConsoleMessagesBuffer.clear();
@@ -354,34 +333,41 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
}
public int getEnergy() {
- return energy;
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+ return battery.getEnergy();
}
public void setEnergy(int energy) {
- this.energy = energy;
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+ battery.setEnergy(energy);
}
public boolean spendEnergy(int amount) {
- if (energy - amount < 0) {
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+
+ if (battery.getEnergy() - amount < 0) {
return false;
} else {
- energy -= amount;
+ battery.setEnergy(battery.getEnergy() - amount);
return true;
}
}
public void storeEnergy(int amount) {
- energy = Math.min(energy + amount, maxEnergy);
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+ battery.setEnergy(Math.min(battery.getEnergy() + amount, battery.getMaxEnergy()));
}
public void setMaxEnergy(int maxEnergy) {
- this.maxEnergy = maxEnergy;
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+ battery.setMaxEnergy(maxEnergy);
}
public int getMaxEnergy() {
- return maxEnergy;
+ CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
+ return battery.getMaxEnergy();
}
public int getShield() {
@@ -422,8 +408,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
@Override
public Memory getFloppyData() {
- //TODO change DEFAULT_ADDRESS to getHW(class) to allow mutable addresses
- CubotFloppyDrive drive = ((CubotFloppyDrive) getHardware(CubotFloppyDrive.DEFAULT_ADDRESS));
+ CubotFloppyDrive drive = (CubotFloppyDrive) getHardware(CubotFloppyDrive.class);
if (drive.getFloppy() != null) {
return drive.getFloppy().getMemory();
@@ -515,6 +500,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
public void setMaxShield(int maxShield) {
this.maxShield = maxShield;
}
+
@Override
public void heal(int amount) {
hp += amount;
@@ -538,11 +524,13 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
}
}
+ @Override
public void attachHardware(HardwareModule hardware, int address) {
hardwareAddresses.put(address, hardware);
hardwareModules.put(hardware.getClass(), address);
}
+ @Override
public void detachHardware(int address) {
hardwareAddresses.remove(address);
@@ -555,6 +543,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
hardwareModules.remove(toRemove);
}
+ @Override
public boolean hardwareInterrupt(int address, Status status) {
HardwareModule hardware = hardwareAddresses.get(address);
@@ -566,6 +555,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
}
}
+ @Override
public int hardwareQuery(int address) {
HardwareModule hardware = hardwareAddresses.get(address);
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotBattery.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotBattery.java
index d345501..4c8b80a 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotBattery.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotBattery.java
@@ -1,10 +1,13 @@
package net.simon987.cubotplugin;
+import net.simon987.server.GameServer;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document;
+import org.json.simple.JSONObject;
-public class CubotBattery extends CubotHardwareModule {
+public class CubotBattery extends HardwareModule {
public static final int DEFAULT_ADDRESS = 0x000A;
@@ -12,16 +15,38 @@ public class CubotBattery extends CubotHardwareModule {
* Hardware ID (Should be unique)
*/
public static final char HWID = 0x000A;
+ /**
+ * Solar panel multiplier
+ *
TODO: Set this constant in dimension
+ */
+ private static final float SOLAR_PANEL_MULTIPLIER = 1;
+
+ /**
+ * Energy units in kJ
+ */
+ private int energy;
+
+ /**
+ * Maximum energy units in kJ
+ */
+ private int maxEnergy;
+
private static final int BATTERY_POLL = 1;
private static final int BATTERY_GET_MAX_CAPACITY = 2;
- public CubotBattery(Cubot cubot) {
- super(cubot);
+ public CubotBattery(ControllableUnit unit) {
+ super(null, unit);
+
+ energy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
+ maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
}
public CubotBattery(Document document, ControllableUnit cubot) {
super(document, cubot);
+
+ energy = document.getInteger("energy");
+ maxEnergy = document.getInteger("max_energy");
}
@Override
@@ -30,16 +55,12 @@ public class CubotBattery extends CubotHardwareModule {
int a = getCpu().getRegisterSet().getRegister("A").getValue();
if (a == BATTERY_POLL) {
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.getEnergy());
+ getCpu().getRegisterSet().getRegister("B").setValue(energy);
} else if (a == BATTERY_GET_MAX_CAPACITY) {
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.getMaxEnergy());
+ getCpu().getRegisterSet().getRegister("B").setValue(maxEnergy);
- //TODO: Remove debug action
- } else if (a == 0xFFFF) {
- cubot.setEnergy(cubot.getMaxEnergy());
}
-
}
@Override
@@ -47,4 +68,53 @@ public class CubotBattery extends CubotHardwareModule {
return HWID;
}
+ @Override
+ public JSONObject jsonSerialise() {
+ JSONObject json = new JSONObject();
+
+ json.put("energy", energy);
+
+ return json;
+ }
+
+ @Override
+ public JSONObject debugJsonSerialise() {
+ JSONObject json = jsonSerialise();
+
+ json.put("max_energy", maxEnergy);
+
+ return json;
+ }
+
+ @Override
+ public Document mongoSerialise() {
+ Document document = super.mongoSerialise();
+
+ document.put("energy", energy);
+ document.put("max_energy", maxEnergy);
+
+ return document;
+ }
+
+ public int getEnergy() {
+ return energy;
+ }
+
+ public void setEnergy(int energy) {
+ this.energy = energy;
+ }
+
+ public int getMaxEnergy() {
+ return maxEnergy;
+ }
+
+ public void setMaxEnergy(int maxEnergy) {
+ this.maxEnergy = maxEnergy;
+ }
+
+ @Override
+ public void update() {
+ energy = Math.min(maxEnergy,
+ energy + (int) (SOLAR_PANEL_MULTIPLIER * GameServer.INSTANCE.getDayNightCycle().getSunIntensity()));
+ }
}
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 c0eb4e6..65efed4 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotComPort.java
@@ -1,5 +1,6 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.objects.GameObject;
@@ -9,7 +10,7 @@ import org.bson.Document;
import java.awt.*;
import java.util.ArrayList;
-public class CubotComPort extends CubotHardwareModule {
+public class CubotComPort extends HardwareModule {
public static final char HWID = 0xD;
public static final int DEFAULT_ADDRESS = 0xD;
@@ -20,8 +21,8 @@ public class CubotComPort extends CubotHardwareModule {
private static final int COMPORT_SELF_OUT = 3;
private static final int COMPORT_CONSOLE_CLEAR = 4;
- public CubotComPort(Cubot cubot) {
- super(cubot);
+ public CubotComPort(ControllableUnit unit) {
+ super(null, unit);
}
public CubotComPort(Document document, ControllableUnit cubot) {
@@ -37,21 +38,23 @@ public class CubotComPort extends CubotHardwareModule {
if (a == COMPORT_BUFFER_CLEAR) {
- cubot.getConsoleMessagesBuffer().clear();
+ unit.getConsoleMessagesBuffer().clear();
} else if (a == COMPORT_CONSOLE_CLEAR) {
-
- cubot.setConsoleMode(Cubot.ConsoleMode.CLEAR);
+
+ if (unit instanceof Cubot) {
+ ((Cubot) unit).setConsoleMode(Cubot.ConsoleMode.CLEAR);
+ }
} else if (a == COMPORT_POLL) {
- if (cubot.spendEnergy(4)) {
+ if (unit.spendEnergy(4)) {
int x = getCpu().getRegisterSet().getRegister("X").getValue();
//Read all messages in the console buffer to memory at X
- for (char[] message : cubot.getConsoleMessagesBuffer()) {
+ for (char[] message : unit.getConsoleMessagesBuffer()) {
if (x + MESSAGE_LENGTH >= getCpu().getMemory().getWords().length) {
//todo set interrupt ?
getCpu().getStatus().setErrorFlag(true);
@@ -61,17 +64,17 @@ public class CubotComPort extends CubotHardwareModule {
}
//Set B = number of messages
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.getConsoleMessagesBuffer().size());
+ getCpu().getRegisterSet().getRegister("B").setValue(unit.getConsoleMessagesBuffer().size());
}
} else if (a == COMPORT_FRONT_PORT_OUT) {
- if (cubot.spendEnergy(5)) {
+ if (unit.spendEnergy(5)) {
//Get object directly in front of the Cubot
- Point frontTile = cubot.getFrontTile();
+ Point frontTile = unit.getFrontTile();
//Todo will have to add getGameObjectsBlockingAt to enable Factory
- ArrayList objects = cubot.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
+ ArrayList objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
if (objects.size() > 0 && objects.get(0) instanceof MessageReceiver) {
@@ -98,7 +101,7 @@ public class CubotComPort extends CubotHardwareModule {
} else if (a == COMPORT_SELF_OUT) {
- if (cubot.spendEnergy(1)) {
+ if (unit.spendEnergy(1)) {
int x = getCpu().getRegisterSet().getRegister("X").getValue();
@@ -111,7 +114,7 @@ public class CubotComPort extends CubotHardwareModule {
//Get MESSAGE_LENGTH-word message pointed by X
char[] message = new char[MESSAGE_LENGTH];
System.arraycopy(getCpu().getMemory().getWords(), x, message, 0, MESSAGE_LENGTH);
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.sendMessage(message) ? 1 : 0);
+ getCpu().getRegisterSet().getRegister("B").setValue(unit.sendMessage(message) ? 1 : 0);
return;
}
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotCore.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotCore.java
index 74a303f..6a8996a 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotCore.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotCore.java
@@ -1,10 +1,11 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document;
-public class CubotCore extends CubotHardwareModule {
+public class CubotCore extends HardwareModule {
public static final int DEFAULT_ADDRESS = 0x000E;
@@ -16,12 +17,12 @@ public class CubotCore extends CubotHardwareModule {
private static final int CORE_STATUS_POLL = 1;
private static final int CORE_HULL_POLL = 2;
- public CubotCore(Cubot cubot) {
- super(cubot);
+ public CubotCore(ControllableUnit unit) {
+ super(null, unit);
}
- public CubotCore(Document document, ControllableUnit cubot) {
- super(document, cubot);
+ public CubotCore(Document document, ControllableUnit unit) {
+ super(document, unit);
}
@Override
@@ -30,9 +31,11 @@ public class CubotCore extends CubotHardwareModule {
int a = getCpu().getRegisterSet().getRegister("A").getValue();
if (a == CORE_STATUS_POLL) {
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.getStatus());
+ if (unit instanceof Cubot) {
+ getCpu().getRegisterSet().getRegister("B").setValue(((Cubot) unit).getStatus());
+ }
} else if (a == CORE_HULL_POLL) {
- getCpu().getRegisterSet().getRegister("B").setValue(cubot.getHp());
+ getCpu().getRegisterSet().getRegister("B").setValue(unit.getHp());
}
}
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 884fe90..88dc0b9 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotDrill.java
@@ -1,5 +1,6 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.item.Item;
import net.simon987.server.game.objects.Action;
@@ -7,7 +8,7 @@ import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.world.Tile;
import org.bson.Document;
-public class CubotDrill extends CubotHardwareModule {
+public class CubotDrill extends HardwareModule {
/**
* Hardware ID (Should be unique)
@@ -19,8 +20,8 @@ public class CubotDrill extends CubotHardwareModule {
private static final int DRILL_POLL = 1;
private static final int DRILL_GATHER = 2; // simplified gather
- public CubotDrill(Cubot cubot) {
- super(cubot);
+ public CubotDrill(ControllableUnit unit) {
+ super(null, unit);
}
public CubotDrill(Document document, ControllableUnit cubot) {
@@ -42,15 +43,15 @@ public class CubotDrill extends CubotHardwareModule {
} else if (a == DRILL_GATHER) {
- if (cubot.spendEnergy(1400)) {
- if (cubot.getCurrentAction() == Action.IDLE) {
+ if (unit.spendEnergy(1400)) {
+ if (unit.getCurrentAction() == Action.IDLE) {
- Tile tile = cubot.getWorld().getTileMap().getTileAt(cubot.getX(), cubot.getY());
+ Tile tile = unit.getWorld().getTileMap().getTileAt(unit.getX(), unit.getY());
Item newItem = tile.drill();
if (newItem != null) {
- cubot.setCurrentAction(Action.DIGGING);
- cubot.giveItem(newItem);
+ unit.setCurrentAction(Action.DIGGING);
+ unit.giveItem(newItem);
}
}
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHardwareModule.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHardwareModule.java
index 4f9a5f5..0df894b 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHardwareModule.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHardwareModule.java
@@ -16,11 +16,4 @@ public abstract class CubotHardwareModule extends HardwareModule {
this.cubot = cubot;
}
- @Override
- public Document mongoSerialise() {
- Document document = new Document();
-
- document.put("type", getClass().getCanonicalName());
- return document;
- }
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHologram.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHologram.java
index 9e291c2..f19e88c 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHologram.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotHologram.java
@@ -1,11 +1,12 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document;
import org.json.simple.JSONObject;
-public class CubotHologram extends CubotHardwareModule {
+public class CubotHologram extends HardwareModule {
/**
* Hardware ID (Should be unique)
@@ -31,8 +32,8 @@ public class CubotHologram extends CubotHardwareModule {
*/
private int displayColor = 0;
- public CubotHologram(Cubot cubot) {
- super(cubot);
+ public CubotHologram(ControllableUnit unit) {
+ super(null, unit);
}
public CubotHologram(Document document, ControllableUnit cubot) {
@@ -80,7 +81,7 @@ public class CubotHologram extends CubotHardwareModule {
} else if (a == HOLO_DISPLAY_COLOR) {
- if (cubot.spendEnergy(4)) {
+ if (unit.spendEnergy(4)) {
int b = getCpu().getRegisterSet().getRegister("B").getValue();
int c = getCpu().getRegisterSet().getRegister("C").getValue();
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java
index 263b9b4..0a344a4 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java
@@ -1,16 +1,16 @@
package net.simon987.cubotplugin;
import net.simon987.server.GameServer;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.item.Item;
-import net.simon987.server.game.item.ItemCopper;
import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document;
import java.util.HashMap;
import java.util.Map;
-public class CubotInventory extends CubotHardwareModule {
+public class CubotInventory extends HardwareModule {
/**
* Hardware ID (Should be unique)
@@ -29,11 +29,10 @@ public class CubotInventory extends CubotHardwareModule {
private int position = 0;
- public CubotInventory(Cubot cubot) {
- super(cubot);
+ public CubotInventory(ControllableUnit unit) {
+ super(null, unit);
inventory = new HashMap<>();
- inventory.put(2, new ItemCopper(new Document())); // TODO: Remove debug value
}
public CubotInventory(Document document, ControllableUnit cubot) {
@@ -56,12 +55,12 @@ public class CubotInventory extends CubotHardwareModule {
private void scanItem() {
int x = getCpu().getRegisterSet().getRegister("X").getValue();
Item item = inventory.get(position);
- item.digitize(cubot.getCpu().getMemory(), x);
+ item.digitize(unit.getCpu().getMemory(), x);
}
public Item clearItem() {
Item item = inventory.get(position);
- item.clear(cubot);
+ item.clear(unit);
inventory.remove(position);
return item;
@@ -100,13 +99,13 @@ public class CubotInventory extends CubotHardwareModule {
getCpu().getRegisterSet().getRegister("B").setValue(result);
} else if (a == INV_CLEAR) {
- if (cubot.spendEnergy(100)) {
+ if (unit.spendEnergy(100)) {
clearItem();
}
} else if (a == INV_SEEK) {
setPosition(getCpu().getRegisterSet().getRegister("X").getValue());
} else if (a == INV_SCAN) {
- if (cubot.spendEnergy(200)) {
+ if (unit.spendEnergy(200)) {
scanItem();
clearItem();
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java
index 186f2e6..040c3ad 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java
@@ -1,6 +1,7 @@
package net.simon987.cubotplugin;
import net.simon987.server.GameServer;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.*;
import org.bson.Document;
@@ -8,7 +9,7 @@ import org.bson.Document;
import java.awt.*;
import java.util.ArrayList;
-public class CubotLaser extends CubotHardwareModule {
+public class CubotLaser extends HardwareModule {
/**
* Hardware ID (Should be unique)
@@ -23,8 +24,8 @@ public class CubotLaser extends CubotHardwareModule {
private static final int LASER_DAMAGE = 25;
- public CubotLaser(Cubot cubot) {
- super(cubot);
+ public CubotLaser(ControllableUnit unit) {
+ super(null, unit);
}
public CubotLaser(Document document, ControllableUnit cubot) {
@@ -46,19 +47,19 @@ public class CubotLaser extends CubotHardwareModule {
if (a == LASER_WITHDRAW) {
- Point frontTile = cubot.getFrontTile();
- ArrayList objects = cubot.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y);
+ Point frontTile = unit.getFrontTile();
+ ArrayList objects = unit.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y);
- if (cubot.getCurrentAction() == Action.IDLE && objects.size() > 0) {
+ if (unit.getCurrentAction() == Action.IDLE && objects.size() > 0) {
//FIXME: Problem here if more than 1 object
if (objects.get(0) instanceof InventoryHolder) {
if (((InventoryHolder) objects.get(0)).canTakeItem(b)) {
- if (cubot.spendEnergy(30)) {
+ if (unit.spendEnergy(30)) {
//Take the item
((InventoryHolder) objects.get(0)).takeItem(b);
- cubot.giveItem(GameServer.INSTANCE.getRegistry().makeItem(b));
- cubot.setCurrentAction(Action.WITHDRAWING);
+ unit.giveItem(GameServer.INSTANCE.getRegistry().makeItem(b));
+ unit.setCurrentAction(Action.WITHDRAWING);
}
}
}
@@ -69,12 +70,12 @@ public class CubotLaser extends CubotHardwareModule {
// TODO
} else if (a == LASER_ATTACK) {
- if (cubot.getCurrentAction() == Action.IDLE) {
- if (cubot.spendEnergy(70)) {
+ if (unit.getCurrentAction() == Action.IDLE) {
+ if (unit.spendEnergy(70)) {
//Get object directly in front of the Cubot
- Point frontTile = cubot.getFrontTile();
- ArrayList objects = cubot.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
+ Point frontTile = unit.getFrontTile();
+ ArrayList objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
//todo: Add option in config to allow PvP
if (objects.size() > 0 && objects.get(0) instanceof Attackable && !(objects.get(0) instanceof Cubot)) {
@@ -83,7 +84,7 @@ public class CubotLaser extends CubotHardwareModule {
}
- cubot.setCurrentAction(Action.ATTACKING);
+ unit.setCurrentAction(Action.ATTACKING);
}
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java
index 99710e1..f91c329 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLeg.java
@@ -1,12 +1,13 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.Action;
import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.objects.Direction;
import org.bson.Document;
-public class CubotLeg extends CubotHardwareModule {
+public class CubotLeg extends HardwareModule {
public static final int DEFAULT_ADDRESS = 1;
@@ -18,12 +19,12 @@ public class CubotLeg extends CubotHardwareModule {
*/
static final char HWID = 0x0001;
- public CubotLeg(Cubot cubot) {
- super(cubot);
+ public CubotLeg(ControllableUnit unit) {
+ super(null, unit);
}
- public CubotLeg(Document document, ControllableUnit cubot) {
- super(document, cubot);
+ public CubotLeg(Document document, ControllableUnit unit) {
+ super(document, unit);
}
@Override
@@ -34,7 +35,7 @@ public class CubotLeg extends CubotHardwareModule {
@Override
public void handleInterrupt(Status status) {
- if (cubot.getCurrentAction() == Action.IDLE) {
+ if (unit.getCurrentAction() == Action.IDLE) {
int a = getCpu().getRegisterSet().getRegister("A").getValue();
int b = getCpu().getRegisterSet().getRegister("B").getValue();
@@ -44,8 +45,8 @@ public class CubotLeg extends CubotHardwareModule {
Direction dir = Direction.getDirection(b);
if (dir != null) {
- if (cubot.spendEnergy(20)) {
- cubot.setDirection(Direction.getDirection(b));
+ if (unit.spendEnergy(20)) {
+ unit.setDirection(Direction.getDirection(b));
status.setErrorFlag(false);
}
} else {
@@ -55,17 +56,17 @@ public class CubotLeg extends CubotHardwareModule {
} else if (a == LEGS_SET_DIR_AND_WALK) {
- if (cubot.getMaxEnergy() >= 100) {
+ if (unit.getMaxEnergy() >= 100) {
Direction dir = Direction.getDirection(b);
if (dir != null) {
- cubot.setDirection(Direction.getDirection(b));
+ unit.setDirection(Direction.getDirection(b));
status.setErrorFlag(false);
} else {
status.setErrorFlag(true);
}
- cubot.setCurrentAction(Action.WALKING);
+ unit.setCurrentAction(Action.WALKING);
}
}
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLidar.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLidar.java
index 04da704..dd5eb0b 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLidar.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLidar.java
@@ -1,5 +1,6 @@
package net.simon987.cubotplugin;
+import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Memory;
import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit;
@@ -9,7 +10,7 @@ import org.bson.Document;
import java.util.ArrayList;
-public class CubotLidar extends CubotHardwareModule {
+public class CubotLidar extends HardwareModule {
/**
* Hardware ID (Should be unique)
@@ -24,12 +25,12 @@ public class CubotLidar extends CubotHardwareModule {
private static final int LIDAR_GET_WORLD_POS = 4;
private static final int LIDAR_GET_WORLD_SIZE = 5;
- public CubotLidar(Cubot cubot) {
- super(cubot);
+ public CubotLidar(ControllableUnit unit) {
+ super(null, unit);
}
- public CubotLidar(Document document, ControllableUnit cubot) {
- super(document, cubot);
+ public CubotLidar(Document document, ControllableUnit unit) {
+ super(document, unit);
}
@Override
@@ -44,18 +45,18 @@ public class CubotLidar extends CubotHardwareModule {
switch (a) {
case LIDAR_GET_POS:
- getCpu().getRegisterSet().getRegister("X").setValue(cubot.getX());
- getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getY());
+ getCpu().getRegisterSet().getRegister("X").setValue(unit.getX());
+ getCpu().getRegisterSet().getRegister("Y").setValue(unit.getY());
break;
case LIDAR_GET_PATH:
- if (cubot.spendEnergy(50)) {
+ if (unit.spendEnergy(50)) {
int c = getCpu().getRegisterSet().getRegister("C").getValue();
int b = getCpu().getRegisterSet().getRegister("B").getValue();
int destX = getCpu().getRegisterSet().getRegister("X").getValue();
int destY = getCpu().getRegisterSet().getRegister("Y").getValue();
//Get path
- ArrayList nodes = Pathfinder.findPath(cubot.getWorld(), cubot.getX(), cubot.getY(),
+ ArrayList nodes = Pathfinder.findPath(unit.getWorld(), unit.getX(), unit.getY(),
destX, destY, b);
//Write to memory
@@ -102,13 +103,13 @@ public class CubotLidar extends CubotHardwareModule {
break;
case LIDAR_GET_MAP:
- if (cubot.spendEnergy(10)) {
- char[][] mapInfo = cubot.getWorld().getMapInfo();
+ if (unit.spendEnergy(10)) {
+ char[][] mapInfo = unit.getWorld().getMapInfo();
//Write map data to the location specified by register X
int i = getCpu().getRegisterSet().getRegister("X").getValue();
- for (int x = 0; x < cubot.getWorld().getWorldSize(); x++) {
- for (int y = 0; y < cubot.getWorld().getWorldSize(); y++) {
+ for (int x = 0; x < unit.getWorld().getWorldSize(); x++) {
+ for (int y = 0; y < unit.getWorld().getWorldSize(); y++) {
getCpu().getMemory().set(i++, mapInfo[x][y]);
}
}
@@ -116,13 +117,13 @@ public class CubotLidar extends CubotHardwareModule {
break;
case LIDAR_GET_WORLD_SIZE:
- getCpu().getRegisterSet().getRegister("X").setValue(cubot.getWorld().getWorldSize());
- getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getWorld().getWorldSize());
+ getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getWorldSize());
+ getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getWorldSize());
break;
case LIDAR_GET_WORLD_POS:
- getCpu().getRegisterSet().getRegister("X").setValue(cubot.getWorld().getX());
- getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getWorld().getY());
+ getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getX());
+ getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getY());
break;
}
diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java
index 08d78e0..c34c085 100644
--- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java
+++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/event/UserCreationListener.java
@@ -50,13 +50,6 @@ public class UserCreationListener implements GameEventListener {
cubot.getWorld().addObject(cubot);
cubot.getWorld().incUpdatable();
- cubot.setEnergy(config.getInt("battery_max_energy"));
- cubot.setMaxEnergy(config.getInt("battery_max_energy"));
-
- cubot.setHp(config.getInt("cubot_max_hp"));
- cubot.setMaxHp(config.getInt("cubot_max_hp"));
- cubot.setMaxShield(config.getInt("cubot_max_shield"));
-
cubot.setParent(user);
user.setControlledUnit(cubot);
@@ -81,6 +74,10 @@ public class UserCreationListener implements GameEventListener {
e.printStackTrace();
}
+ cubot.setHp(config.getInt("cubot_max_hp"));
+ cubot.setMaxHp(config.getInt("cubot_max_hp"));
+ cubot.setMaxShield(config.getInt("cubot_max_shield"));
+
LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)");
}
}
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java
index 0d82c14..175f372 100644
--- a/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/Factory.java
@@ -1,17 +1,19 @@
package net.simon987.npcplugin;
import net.simon987.server.GameServer;
+import net.simon987.server.game.objects.MessageReceiver;
import net.simon987.server.game.objects.Structure;
import net.simon987.server.game.objects.Updatable;
import org.bson.Document;
import org.bson.types.ObjectId;
import java.awt.*;
+import java.util.Arrays;
/**
* Game objects that regularly creates NonPlayerCharacters
*/
-public class Factory extends Structure implements Updatable {
+public class Factory extends Structure implements Updatable, MessageReceiver {
private static final int MAP_INFO = 0x0401;
@@ -30,6 +32,15 @@ public class Factory extends Structure implements Updatable {
*/
private int cooldown = 0;
+ private boolean locked = true;
+
+ /**
+ * If non-null, the next spawned NPC will be a HackedNPC and the program will be
+ * injected in its memory
+ */
+ private char[] program;
+ private int programIndex = 0;
+
public Factory() {
super(2, 2);
}
@@ -57,14 +68,7 @@ public class Factory extends Structure implements Updatable {
Point p = getAdjacentTile();
if (p != null) {
- NonPlayerCharacter npc = new HarvesterNPC();
- npc.setWorld(getWorld());
- npc.setObjectId(new ObjectId());
- npc.setX(p.x);
- npc.setY(p.y);
- getWorld().addObject(npc);
- getWorld().incUpdatable();
-
+ NonPlayerCharacter npc = spawnNPC(p);
settlement.addNpc(npc);
}
}
@@ -75,4 +79,65 @@ public class Factory extends Structure implements Updatable {
cooldown--;
}
}
+
+ private NonPlayerCharacter spawnNPC(Point p) {
+
+ NonPlayerCharacter npc;
+ if (programIndex == 0) {
+ npc = new HarvesterNPC();
+ npc.setWorld(getWorld());
+ npc.setObjectId(new ObjectId());
+ npc.setX(p.x);
+ npc.setY(p.y);
+ getWorld().addObject(npc);
+ getWorld().incUpdatable();
+ } else {
+
+ npc = new HackedNPC(program);
+ npc.setWorld(getWorld());
+ npc.setObjectId(new ObjectId());
+ npc.setX(p.x);
+ npc.setY(p.y);
+ getWorld().addObject(npc);
+ getWorld().incUpdatable();
+
+ System.out.println("NEW HACKED NPC");
+ this.locked = true;
+ }
+
+ return npc;
+ }
+
+ @Override
+ public boolean sendMessage(char[] message) {
+
+ String strMessage = String.valueOf(message);
+
+ System.out.println("Received message " + strMessage);
+ if (locked) {
+ Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId());
+
+ if (Arrays.equals(settlement.getPassword(), message)) {
+ System.out.println("Factory unlock");
+ this.locked = false;
+
+ return true;
+ }
+ System.out.println("Wrong password, " + strMessage + "!=" + String.valueOf(settlement.getPassword()));
+ } else if (programIndex <= 2048) { //todo config
+
+ if (programIndex == 0) {
+ program = new char[2048];
+ }
+
+ System.arraycopy(message, 0, program, programIndex, message.length);
+ System.out.println("Factory append code: " + strMessage);
+ System.out.println("Wrote " + message.length + " chars");
+ programIndex += message.length;
+
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/HackedNPC.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/HackedNPC.java
new file mode 100644
index 0000000..ea85a61
--- /dev/null
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/HackedNPC.java
@@ -0,0 +1,314 @@
+package net.simon987.npcplugin;
+
+import net.simon987.server.GameServer;
+import net.simon987.server.assembly.*;
+import net.simon987.server.game.item.Item;
+import net.simon987.server.game.item.ItemVoid;
+import net.simon987.server.game.objects.Action;
+import net.simon987.server.game.objects.ControllableUnit;
+import net.simon987.server.game.objects.Direction;
+import net.simon987.server.game.objects.HardwareHost;
+import net.simon987.server.user.User;
+import org.bson.Document;
+import org.json.simple.JSONObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, HardwareHost {
+
+ private static final int MEM_SIZE = GameServer.INSTANCE.getConfig().getInt("hacked_npc_mem_size");
+
+ private CPU cpu;
+ /**
+ * List of attached hardware, 'modules'
+ */
+ private Map hardwareAddresses = new HashMap<>();
+ private Map, Integer> hardwareModules = new HashMap<>();
+
+ private Action currentAction = Action.IDLE;
+ private Action lastAction = Action.IDLE;
+ private ArrayList consoleMessagesBuffer = new ArrayList<>(30); //todo load from conf
+ private ArrayList lastConsoleMessagesBuffer = new ArrayList<>(30);
+
+ HackedNPC(char[] program) {
+
+ cpu = new CPU();
+
+ cpu.setMemory(new Memory(MEM_SIZE));
+ cpu.setHardwareHost(this);
+ //Write program
+ boolean write = cpu.getMemory().write(0, program, 0, program.length);
+ System.out.println("Write " + write);
+
+ for (Object serialisedHw : (List) NpcPlugin.DEFAULT_HACKED_NPC.get("hardware")) {
+ HardwareModule hardware = GameServer.INSTANCE.getRegistry().deserializeHardware((Document) serialisedHw, this);
+ hardware.setCpu(cpu);
+ attachHardware(hardware, ((Document) serialisedHw).getInteger("address"));
+ }
+ }
+
+ public HackedNPC(Document document) {
+ super(document);
+
+ setHp(document.getInteger("hp"));
+ setDirection(Direction.getDirection(document.getInteger("direction")));
+
+ cpu = new CPU();
+ cpu.setHardwareHost(this);
+ cpu.setMemory(new Memory((Document) document.get("memory")));
+ cpu.setRegisterSet(RegisterSet.deserialize((Document) document.get("registerSet")));
+
+ ArrayList hardwareList = (ArrayList) document.get("hardware");
+
+ for (Object serialisedHw : hardwareList) {
+ HardwareModule hardware = GameServer.INSTANCE.getRegistry().deserializeHardware((Document) serialisedHw, this);
+ hardware.setCpu(cpu);
+ attachHardware(hardware, ((Document) serialisedHw).getInteger("address"));
+ }
+ }
+
+ @Override
+ public void update() {
+
+
+ System.out.println(Util.toHex(cpu.getMemory().getBytes()));
+
+ //Execute code
+ System.out.println("HACKED NPC " + this.getObjectId());
+ int timeout = Math.min(getEnergy(), 30); //todo get from config
+ cpu.reset();
+ int cost = cpu.execute(timeout);
+ spendEnergy(cost);
+
+ if (currentAction == Action.WALKING) {
+ if (spendEnergy(100)) {
+ if (!incrementLocation()) {
+ //Couldn't walk
+ currentAction = Action.IDLE;
+ }
+ } else {
+ currentAction = Action.IDLE;
+ }
+ }
+
+ /*
+ * CurrentAction is set during the code execution and this function is called right after
+ * If no action as been set, the action sent to the client is the action in currentAction that
+ * was set last tick (IDLE)
+ */
+ lastAction = currentAction;
+ currentAction = Action.IDLE;
+
+ lastConsoleMessagesBuffer = new ArrayList<>(consoleMessagesBuffer);
+ consoleMessagesBuffer.clear();
+
+ for (HardwareModule module : hardwareAddresses.values()) {
+ module.update();
+ }
+ }
+
+ @Override
+ public void setKeyboardBuffer(ArrayList kbBuffer) {
+ }
+
+ @Override
+ public void setParent(User user) {
+ }
+
+ @Override
+ public User getParent() {
+ return null;
+ }
+
+ @Override
+ public ArrayList getKeyboardBuffer() {
+ return null;
+ }
+
+ @Override
+ public Memory getFloppyData() {
+ return null;
+ }
+
+
+ @Override
+ public void setAction(Action action) {
+ currentAction = action;
+ }
+
+ @Override
+ public ArrayList getConsoleMessagesBuffer() {
+ return null;
+ }
+
+ @Override
+ public int getConsoleMode() {
+ return 0;
+ }
+
+ @Override
+ public CPU getCpu() {
+ return cpu;
+ }
+
+ @Override
+ public void giveItem(Item item) {
+ //Overwrite item at current position
+ ((NpcInventory) getHardware(NpcInventory.class)).putItem(item);
+ }
+
+ @Override
+ public void attachHardware(HardwareModule hardware, int address) {
+ hardwareAddresses.put(address, hardware);
+ hardwareModules.put(hardware.getClass(), address);
+ }
+
+ @Override
+ public void detachHardware(int address) {
+ hardwareAddresses.remove(address);
+
+ Class extends HardwareModule> toRemove = null;
+ for (Class extends HardwareModule> clazz : hardwareModules.keySet()) {
+ if (hardwareModules.get(clazz) == address) {
+ toRemove = clazz;
+ }
+ }
+ hardwareModules.remove(toRemove);
+ }
+
+ @Override
+ public boolean hardwareInterrupt(int address, Status status) {
+ HardwareModule hardware = hardwareAddresses.get(address);
+
+ if (hardware != null) {
+ hardware.handleInterrupt(status);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int hardwareQuery(int address) {
+ HardwareModule hardware = hardwareAddresses.get(address);
+
+ if (hardware != null) {
+ return hardware.getId();
+ } else {
+ return 0;
+ }
+ }
+
+ public int getEnergy() {
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+ return battery.getEnergy();
+ }
+
+ public void setEnergy(int energy) {
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+ battery.setEnergy(energy);
+ }
+
+ public boolean spendEnergy(int amount) {
+
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+
+ if (battery.getEnergy() - amount < 0) {
+ return false;
+ } else {
+ battery.setEnergy(battery.getEnergy() - amount);
+ return true;
+ }
+ }
+
+ @Override
+ public Document mongoSerialise() {
+ Document dbObject = super.mongoSerialise();
+
+ dbObject.put("direction", getDirection().ordinal());
+ dbObject.put("hp", getHp());
+ dbObject.put("action", lastAction.ordinal());
+
+ List hardwareList = new ArrayList<>();
+
+ for (Integer address : hardwareAddresses.keySet()) {
+
+ HardwareModule hardware = hardwareAddresses.get(address);
+
+ Document serialisedHw = hardware.mongoSerialise();
+ serialisedHw.put("address", address);
+ hardwareList.add(serialisedHw);
+ }
+
+ dbObject.put("hardware", hardwareList);
+
+ dbObject.put("memory", cpu.getMemory().mongoSerialise());
+
+ dbObject.put("registerSet", cpu.getRegisterSet().mongoSerialise());
+ return dbObject;
+ }
+
+ public void storeEnergy(int amount) {
+
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+ battery.setEnergy(Math.min(battery.getEnergy() + amount, battery.getMaxEnergy()));
+ }
+
+ private HardwareModule getHardware(Class extends HardwareModule> clazz) {
+ return hardwareAddresses.get(hardwareModules.get(clazz));
+ }
+
+ public void setMaxEnergy(int maxEnergy) {
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+ battery.setMaxEnergy(maxEnergy);
+ }
+
+ public int getMaxEnergy() {
+ NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class);
+ return battery.getMaxEnergy();
+ }
+
+ @Override
+ public boolean sendMessage(char[] message) {
+ return false;
+ }
+
+ @Override
+ public void setCurrentAction(Action action) {
+ currentAction = action;
+ }
+
+ @Override
+ public Action getCurrentAction() {
+ return currentAction;
+ }
+
+ @Override
+ public JSONObject jsonSerialise() {
+ JSONObject json = super.jsonSerialise();
+
+ for (HardwareModule module : hardwareAddresses.values()) {
+ JSONObject hwJson = module.jsonSerialise();
+ if (hwJson != null) {
+ json.put(module.getClass().getName(), hwJson);
+ }
+ }
+
+ json.put("direction", getDirection().ordinal());
+ NpcInventory inv = (NpcInventory) getHardware(NpcInventory.class);
+ Item item = inv.getItem();
+ json.put("heldItem", item == null ? new ItemVoid().getId() : item.getId());
+ json.put("hp", getHp());
+ json.put("action", lastAction.ordinal());
+
+ return json;
+ }
+
+ @Override
+ public JSONObject debugJsonSerialise() {
+ return jsonSerialise();
+ }
+}
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcBattery.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcBattery.java
new file mode 100644
index 0000000..d5eb401
--- /dev/null
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcBattery.java
@@ -0,0 +1,109 @@
+package net.simon987.npcplugin;
+
+import net.simon987.server.GameServer;
+import net.simon987.server.assembly.HardwareModule;
+import net.simon987.server.assembly.Status;
+import net.simon987.server.game.objects.ControllableUnit;
+import org.bson.Document;
+import org.json.simple.JSONObject;
+
+public class NpcBattery extends HardwareModule {
+
+ public static final int DEFAULT_ADDRESS = 0x010A;
+
+ /**
+ * Hardware ID (Should be unique)
+ */
+ public static final char HWID = 0x010A;
+
+ /**
+ * Energy units in kJ
+ */
+ private int energy;
+
+ /**
+ * Maximum energy units in kJ
+ */
+ private int maxEnergy;
+
+
+ private static final int BATTERY_POLL = 1;
+ private static final int BATTERY_GET_MAX_CAPACITY = 2;
+
+ public NpcBattery(ControllableUnit unit) {
+ super(null, unit);
+
+ energy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
+ maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy");
+ }
+
+ public NpcBattery(Document document, ControllableUnit cubot) {
+ super(document, cubot);
+
+ energy = document.getInteger("energy");
+ maxEnergy = document.getInteger("max_energy");
+ }
+
+ @Override
+ public void handleInterrupt(Status status) {
+
+ int a = getCpu().getRegisterSet().getRegister("A").getValue();
+
+ if (a == BATTERY_POLL) {
+ getCpu().getRegisterSet().getRegister("B").setValue(unit.getEnergy());
+
+ } else if (a == BATTERY_GET_MAX_CAPACITY) {
+ getCpu().getRegisterSet().getRegister("B").setValue(unit.getMaxEnergy());
+
+ }
+ }
+
+ @Override
+ public char getId() {
+ return HWID;
+ }
+
+ @Override
+ public JSONObject jsonSerialise() {
+ JSONObject json = new JSONObject();
+
+ json.put("energy", energy);
+
+ return json;
+ }
+
+ @Override
+ public JSONObject debugJsonSerialise() {
+ JSONObject json = jsonSerialise();
+
+ json.put("max_energy", maxEnergy);
+
+ return json;
+ }
+
+ @Override
+ public Document mongoSerialise() {
+ Document document = super.mongoSerialise();
+
+ document.put("energy", energy);
+ document.put("max_energy", maxEnergy);
+
+ return document;
+ }
+
+ public int getEnergy() {
+ return energy;
+ }
+
+ public void setEnergy(int energy) {
+ this.energy = energy;
+ }
+
+ public int getMaxEnergy() {
+ return maxEnergy;
+ }
+
+ public void setMaxEnergy(int maxEnergy) {
+ this.maxEnergy = maxEnergy;
+ }
+}
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcInventory.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcInventory.java
new file mode 100644
index 0000000..43477eb
--- /dev/null
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcInventory.java
@@ -0,0 +1,109 @@
+package net.simon987.npcplugin;
+
+import net.simon987.server.GameServer;
+import net.simon987.server.assembly.HardwareModule;
+import net.simon987.server.assembly.Status;
+import net.simon987.server.game.item.Item;
+import net.simon987.server.game.objects.ControllableUnit;
+import org.bson.Document;
+
+
+public class NpcInventory extends HardwareModule {
+
+ /**
+ * Hardware ID (Should be unique)
+ */
+ static final char HWID = 0x0106;
+
+ public static final int DEFAULT_ADDRESS = 0x0106;
+
+ private static final int INV_CLEAR = 0;
+ private static final int INV_POLL = 1;
+ private static final int INV_SCAN = 3;
+
+ private Item item;
+
+ public NpcInventory(ControllableUnit unit) {
+ super(null, unit);
+ }
+
+ public NpcInventory(Document document, ControllableUnit cubot) {
+ super(document, cubot);
+
+ Document itemDoc = (Document) document.get("item");
+ if (itemDoc != null) {
+ item = GameServer.INSTANCE.getRegistry().deserializeItem(itemDoc);
+ }
+ }
+
+ public void putItem(Item item) {
+ this.item = item;
+ }
+
+ private void scanItem() {
+ int x = getCpu().getRegisterSet().getRegister("X").getValue();
+ item.digitize(unit.getCpu().getMemory(), x);
+ }
+
+ public Item clearItem() {
+
+ Item oldItem = item;
+ item.clear(unit);
+ item = null;
+
+ return oldItem;
+ }
+
+ @Override
+ public char getId() {
+ return HWID;
+ }
+
+ public Item getItem() {
+ return item;
+ }
+
+ @Override
+ public void handleInterrupt(Status status) {
+
+ int a = getCpu().getRegisterSet().getRegister("A").getValue();
+
+ if (a == INV_POLL) {
+ char result;
+ if (item == null) {
+ result = 0;
+ } else {
+ result = item.poll();
+ }
+ getCpu().getRegisterSet().getRegister("B").setValue(result);
+
+ } else if (a == INV_CLEAR) {
+ if (unit.spendEnergy(100)) {
+ clearItem();
+ }
+ } else if (a == INV_SCAN) {
+ if (unit.spendEnergy(200)) {
+ scanItem();
+ clearItem();
+ }
+ }
+ }
+
+ @Override
+ public Document mongoSerialise() {
+ Document document = super.mongoSerialise();
+
+ if (item != null) {
+ document.put("item", item.mongoSerialise());
+ } else {
+ document.put("item", null);
+ }
+
+ return document;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("{NpcInventory [%s]}", item);
+ }
+}
\ No newline at end of file
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcPlugin.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcPlugin.java
index 8d6f3ad..e6b790d 100644
--- a/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcPlugin.java
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/NpcPlugin.java
@@ -13,13 +13,17 @@ import net.simon987.server.logging.LogManager;
import net.simon987.server.plugin.ServerPlugin;
import org.bson.Document;
+import java.io.InputStream;
import java.util.Map;
+import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
public class NpcPlugin extends ServerPlugin {
public static Map settlementMap;
+ public static Document DEFAULT_HACKED_NPC;
+
@Override
public void init(GameServer gameServer) {
@@ -39,14 +43,22 @@ public class NpcPlugin extends ServerPlugin {
registry.registerGameObject(ElectricBox.class);
registry.registerGameObject(Portal.class);
registry.registerGameObject(VaultExitPortal.class);
+ registry.registerGameObject(HackedNPC.class);
registry.registerHardware(RadioReceiverHardware.class);
+ registry.registerHardware(NpcBattery.class);
+ registry.registerHardware(NpcInventory.class);
registry.registerTile(TileVaultFloor.ID, TileVaultFloor.class);
registry.registerTile(TileVaultWall.ID, TileVaultWall.class);
settlementMap = new ConcurrentHashMap<>();
+ InputStream is = getClass().getClassLoader().getResourceAsStream("defaultHackedCubotHardware.json");
+ Scanner scanner = new Scanner(is).useDelimiter("\\A");
+ String json = scanner.next();
+ DEFAULT_HACKED_NPC = Document.parse(json);
+
LogManager.LOGGER.info("(NPC Plugin) Initialised NPC plugin");
}
diff --git a/Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java b/Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
index 667329c..0afc06c 100644
--- a/Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
+++ b/Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
@@ -59,6 +59,7 @@ public class Settlement implements MongoSerializable {
this.world = world;
this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ?
+ this.password = "12345678".toCharArray();
outerLoopFactory:
for (int x = 2; x < 12; x++) {
@@ -175,7 +176,7 @@ public class Settlement implements MongoSerializable {
}
document.put("factory", factory.getObjectId());
document.put("difficulty_level", difficultyLevel.ordinal());
- document.put("password", "1234567"); //todo
+ document.put("password", String.valueOf(password));
List npcArray = new ArrayList<>(npcs.size());
diff --git a/Plugin NPC/src/main/resources/defaultHackedCubotHardware.json b/Plugin NPC/src/main/resources/defaultHackedCubotHardware.json
new file mode 100644
index 0000000..1784c2e
--- /dev/null
+++ b/Plugin NPC/src/main/resources/defaultHackedCubotHardware.json
@@ -0,0 +1,62 @@
+{
+ "hardware": [
+ {
+ "type": "net.simon987.cubotplugin.CubotLeg",
+ "address": 1
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotLaser",
+ "address": 2
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotLidar",
+ "address": 3
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotDrill",
+ "address": 5
+ },
+ {
+ "type": "net.simon987.npcplugin.NpcInventory",
+ "item": null,
+ "address": 6
+ },
+ {
+ "type": "net.simon987.mischwplugin.RandomNumberGenerator",
+ "address": 7
+ },
+ {
+ "type": "net.simon987.mischwplugin.Clock",
+ "address": 8
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotHologram",
+ "color": 0,
+ "value": 0,
+ "string": "",
+ "mode": 0,
+ "address": 9
+ },
+ {
+ "type": "net.simon987.npcplugin.NpcBattery",
+ "energy": 60000,
+ "max_energy": 60000,
+ "address": 262
+ },
+ {
+ "type": "net.simon987.npcplugin.RadioReceiverHardware",
+ "cubot": {
+ "$oid": "5c1d43e40d3d2530aba636df"
+ },
+ "address": 12
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotComPort",
+ "address": 13
+ },
+ {
+ "type": "net.simon987.cubotplugin.CubotCore",
+ "address": 14
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Plugin NPC/src/main/resources/plugin.properties b/Plugin NPC/src/main/resources/plugin.properties
index 91f14e5..bfd7fd6 100644
--- a/Plugin NPC/src/main/resources/plugin.properties
+++ b/Plugin NPC/src/main/resources/plugin.properties
@@ -1,3 +1,4 @@
classpath=net.simon987.npcplugin.NpcPlugin
name=NPC Plugin
-version=1.1
\ No newline at end of file
+version=1.1
+depend=Cubot Plugin
\ No newline at end of file
diff --git a/Server/src/main/java/net/simon987/server/assembly/CPU.java b/Server/src/main/java/net/simon987/server/assembly/CPU.java
index 38898bc..c25fc3f 100755
--- a/Server/src/main/java/net/simon987/server/assembly/CPU.java
+++ b/Server/src/main/java/net/simon987/server/assembly/CPU.java
@@ -60,6 +60,41 @@ public class CPU implements MongoSerializable {
private static final char EXECUTION_COST_ADDR = 0x0050;
private static final char EXECUTED_INS_ADDR = 0x0051;
+ public CPU() {
+ instructionSet = new DefaultInstructionSet();
+ registerSet = new DefaultRegisterSet();
+ codeSectionOffset = 0;
+
+ instructionSet.add(new JmpInstruction(this));
+ instructionSet.add(new JnzInstruction(this));
+ instructionSet.add(new JzInstruction(this));
+ instructionSet.add(new JgInstruction(this));
+ instructionSet.add(new JgeInstruction(this));
+ instructionSet.add(new JleInstruction(this));
+ instructionSet.add(new JlInstruction(this));
+ instructionSet.add(new PushInstruction(this));
+ instructionSet.add(new PopInstruction(this));
+ instructionSet.add(new CallInstruction(this));
+ instructionSet.add(new RetInstruction(this));
+ instructionSet.add(new MulInstruction(this));
+ instructionSet.add(new DivInstruction(this));
+ instructionSet.add(new JnsInstruction(this));
+ instructionSet.add(new JsInstruction(this));
+ instructionSet.add(new HwiInstruction(this));
+ instructionSet.add(new HwqInstruction(this));
+ instructionSet.add(new XchgInstruction(this));
+ instructionSet.add(new JcInstruction(this));
+ instructionSet.add(new JncInstruction(this));
+ instructionSet.add(new JnoInstruction(this));
+ instructionSet.add(new JoInstruction(this));
+ instructionSet.add(new PushfInstruction(this));
+ instructionSet.add(new PopfInstruction(this));
+ instructionSet.add(new JnaInstruction(this));
+ instructionSet.add(new JaInstruction(this));
+
+ status = new Status();
+ }
+
/**
* Creates a new CPU
*/
@@ -359,7 +394,6 @@ public class CPU implements MongoSerializable {
cpu.codeSectionOffset = obj.getInteger("codeSegmentOffset");
-
cpu.memory = new Memory((Document) obj.get("memory"));
cpu.registerSet = RegisterSet.deserialize((Document) obj.get("registerSet"));
@@ -379,6 +413,14 @@ public class CPU implements MongoSerializable {
return memory;
}
+ public void setMemory(Memory memory) {
+ this.memory = memory;
+ }
+
+ public void setRegisterSet(RegisterSet registerSet) {
+ this.registerSet = registerSet;
+ }
+
public Status getStatus() {
return status;
}
diff --git a/Server/src/main/java/net/simon987/server/assembly/HardwareModule.java b/Server/src/main/java/net/simon987/server/assembly/HardwareModule.java
index 290365e..b352e6d 100644
--- a/Server/src/main/java/net/simon987/server/assembly/HardwareModule.java
+++ b/Server/src/main/java/net/simon987/server/assembly/HardwareModule.java
@@ -11,13 +11,14 @@ import org.json.simple.JSONObject;
public abstract class HardwareModule implements MongoSerializable, JSONSerializable {
private CPU cpu;
+ protected ControllableUnit unit;
public HardwareModule() {
}
public HardwareModule(Document document, ControllableUnit unit) {
-
+ this.unit = unit;
}
/**
@@ -58,4 +59,12 @@ public abstract class HardwareModule implements MongoSerializable, JSONSerializa
public JSONObject debugJsonSerialise() {
return null;
}
+
+ @Override
+ public Document mongoSerialise() {
+ Document document = new Document();
+
+ document.put("type", getClass().getCanonicalName());
+ return document;
+ }
}
diff --git a/Server/src/main/java/net/simon987/server/game/objects/ControllableUnit.java b/Server/src/main/java/net/simon987/server/game/objects/ControllableUnit.java
index d326da3..989c1f0 100644
--- a/Server/src/main/java/net/simon987/server/game/objects/ControllableUnit.java
+++ b/Server/src/main/java/net/simon987/server/game/objects/ControllableUnit.java
@@ -7,9 +7,10 @@ import net.simon987.server.game.world.World;
import net.simon987.server.user.User;
import org.bson.types.ObjectId;
+import java.awt.*;
import java.util.ArrayList;
-public interface ControllableUnit {
+public interface ControllableUnit extends MessageReceiver, Rechargeable, Attackable {
ObjectId getObjectId();
@@ -31,7 +32,11 @@ public interface ControllableUnit {
int getY();
- void setAction(Action listening);
+ void setAction(Action action);
+
+ void setCurrentAction(Action action);
+
+ Action getCurrentAction();
World getWorld();
@@ -42,4 +47,9 @@ public interface ControllableUnit {
CPU getCpu();
void giveItem(Item item);
+
+ Point getFrontTile();
+
+ void setDirection(Direction direction);
}
+
diff --git a/Server/src/main/resources/config.properties b/Server/src/main/resources/config.properties
index dc7fd82..40806f5 100644
--- a/Server/src/main/resources/config.properties
+++ b/Server/src/main/resources/config.properties
@@ -71,6 +71,7 @@ harvester_hp_max=100
harvester_regen=5
harvester_biomass_drop_count=8
radio_tower_range=3
+hacked_npc_mem_size=5120
#Vaults
vault_door_open_time=4
min_electric_box_count=1
diff --git a/Server/src/main/resources/static/js/mar.js b/Server/src/main/resources/static/js/mar.js
index 1c7ae54..610f2fb 100644
--- a/Server/src/main/resources/static/js/mar.js
+++ b/Server/src/main/resources/static/js/mar.js
@@ -830,6 +830,7 @@ var ObjectType;
ObjectType["OBSTACLE"] = "net.simon987.npcplugin.Obstacle";
ObjectType["ELECTRIC_BOX"] = "net.simon987.npcplugin.ElectricBox";
ObjectType["PORTAL"] = "net.simon987.npcplugin.Portal";
+ ObjectType["HACKED_NPC"] = "net.simon987.npcplugin.HackedNPC";
})(ObjectType || (ObjectType = {}));
var ItemType;
(function (ItemType) {
@@ -873,6 +874,8 @@ var GameObject = (function (_super) {
return new ElectricBox(json);
case ObjectType.PORTAL:
return new Portal(json);
+ case ObjectType.HACKED_NPC:
+ return new HackedNPC(json);
default:
return null;
}
@@ -917,7 +920,7 @@ var Cubot = (function (_super) {
_this.heldItem = json.heldItem;
_this.direction = json.direction;
_this.action = json.action;
- _this.energy = json.energy;
+ _this.energy = _this.getEnergy(json);
_this.cubotSprite = mar.game.make.sprite(0, 0, "sheet", null);
_this.cubotSprite.anchor.set(0.5, 0);
_this.addChild(_this.cubotSprite);
@@ -949,6 +952,10 @@ var Cubot = (function (_super) {
_this.setShield(false);
return _this;
}
+
+ Cubot.prototype.getEnergy = function (json) {
+ return json["net.simon987.cubotplugin.CubotBattery"].energy;
+ };
Cubot.prototype.setShield = function (shield) {
this.shieldBackSprite.visible = shield;
this.shieldFrontSprite.visible = shield;
@@ -1012,7 +1019,7 @@ var Cubot = (function (_super) {
console.log("Updating Cubot object");
}
this.action = json.action;
- this.energy = json.energy;
+ this.energy = this.getEnergy(json);
this.direction = json.direction;
this.shield = json.shield;
this.createInventory([json.heldItem]);
@@ -1207,6 +1214,13 @@ var HarvesterNPC = (function (_super) {
break;
}
};
+ HarvesterNPC.prototype.getEnergy = function (json) {
+ if (json.hasOwnProperty("net.simon987.npcplugin.NpcBattery")) {
+ return json["net.simon987.npcplugin.NpcBattery"].energy;
+ } else {
+ return 0;
+ }
+ };
HarvesterNPC.prototype.updateObject = function (json) {
if (DEBUG) {
console.log("Updating Harvester NPC object");
@@ -1226,6 +1240,28 @@ var HarvesterNPC = (function (_super) {
};
return HarvesterNPC;
}(Cubot));
+var HackedNPC = (function (_super) {
+ __extends(HackedNPC, _super);
+
+ function HackedNPC(json) {
+ var _this = _super.call(this, json) || this;
+ _this.updateDirection();
+ _this.setText("Hacked NPC");
+ _this.text.visible = false;
+ _this.tint = 0xE040FB;
+ return _this;
+ }
+
+ HackedNPC.prototype.updateObject = function (json) {
+ _super.prototype.updateObject.call(this, json);
+ var holoHw = json["net.simon987.cubotplugin.CubotHologram"];
+ this.updateHologram(holoHw.mode, holoHw.color, holoHw.value, holoHw.string);
+ };
+ HackedNPC.prototype.getEnergy = function (json) {
+ return json["net.simon987.npcplugin.NpcBattery"].energy;
+ };
+ return HackedNPC;
+}(HarvesterNPC));
var BiomassBlob = (function (_super) {
__extends(BiomassBlob, _super);
function BiomassBlob(json) {
diff --git a/Server/src/main/typescript/GameObject.ts b/Server/src/main/typescript/GameObject.ts
index f649d9a..ff106c1 100644
--- a/Server/src/main/typescript/GameObject.ts
+++ b/Server/src/main/typescript/GameObject.ts
@@ -7,7 +7,8 @@ enum ObjectType {
VAULT_DOOR = "net.simon987.npcplugin.VaultDoor",
OBSTACLE = "net.simon987.npcplugin.Obstacle",
ELECTRIC_BOX = "net.simon987.npcplugin.ElectricBox",
- PORTAL = "net.simon987.npcplugin.Portal"
+ PORTAL = "net.simon987.npcplugin.Portal",
+ HACKED_NPC = "net.simon987.npcplugin.HackedNPC"
}
enum ItemType {
@@ -59,7 +60,6 @@ abstract class GameObject extends Phaser.Plugin.Isometric.IsoSprite {
switch (json.t) {
case ObjectType.CUBOT:
return new Cubot(json);
-
case ObjectType.BIOMASS:
return new BiomassBlob(json);
case ObjectType.HARVESTER_NPC:
@@ -76,6 +76,8 @@ abstract class GameObject extends Phaser.Plugin.Isometric.IsoSprite {
return new ElectricBox(json);
case ObjectType.PORTAL:
return new Portal(json);
+ case ObjectType.HACKED_NPC:
+ return new HackedNPC(json);
default:
return null;
@@ -155,7 +157,7 @@ class Cubot extends GameObject {
this.heldItem = json.heldItem;
this.direction = json.direction;
this.action = json.action;
- this.energy = json.energy;
+ this.energy = this.getEnergy(json);
this.cubotSprite = mar.game.make.sprite(0, 0, "sheet", null);
this.cubotSprite.anchor.set(0.5, 0);
@@ -197,6 +199,10 @@ class Cubot extends GameObject {
this.setShield(false);
}
+ protected getEnergy(json): number {
+ return json["net.simon987.cubotplugin.CubotBattery"].energy
+ }
+
public setShield(shield: boolean) {
this.shieldBackSprite.visible = shield;
this.shieldFrontSprite.visible = shield;
@@ -277,7 +283,7 @@ class Cubot extends GameObject {
}
this.action = json.action;
- this.energy = json.energy;
+ this.energy = this.getEnergy(json);
this.direction = json.direction;
this.shield = json.shield;
@@ -333,7 +339,7 @@ class Cubot extends GameObject {
this.setShield(this.shield > 0)
}
- private updateHologram(holoMode: HologramMode, holoColor: number, holoValue: number, holoStr: string): void {
+ protected updateHologram(holoMode: HologramMode, holoColor: number, holoValue: number, holoStr: string): void {
let fillColor: string = (holoColor & 0xFFFFFF).toString(16);
fillColor = "#" + ("000000".substr(fillColor.length) + fillColor);
@@ -548,6 +554,14 @@ class HarvesterNPC extends Cubot {
}
}
+ protected getEnergy(json): number {
+ if (json.hasOwnProperty("net.simon987.npcplugin.NpcBattery")) {
+ return json["net.simon987.npcplugin.NpcBattery"].energy;
+ } else {
+ return 0;
+ }
+ }
+
updateObject(json) {
if (DEBUG) {
console.log("Updating Harvester NPC object")
@@ -578,6 +592,30 @@ class HarvesterNPC extends Cubot {
}
+class HackedNPC extends HarvesterNPC {
+
+ constructor(json) {
+ super(json);
+
+ this.updateDirection();
+ this.setText("Hacked NPC");
+ this.text.visible = false;
+ this.tint = 0xE040FB;
+ }
+
+ updateObject(json) {
+ super.updateObject(json);
+
+ let holoHw = json["net.simon987.cubotplugin.CubotHologram"];
+ this.updateHologram(holoHw.mode, holoHw.color, holoHw.value, holoHw.string);
+ }
+
+ protected getEnergy(json): number {
+ return json["net.simon987.npcplugin.NpcBattery"].energy
+ }
+
+}
+
class BiomassBlob extends GameObject {