Hacked NPC minimum viable

This commit is contained in:
simon 2018-12-22 11:26:34 -05:00
parent 955d61ce99
commit e4a06e79d4
26 changed files with 1030 additions and 161 deletions

View File

@ -91,25 +91,10 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
*/ */
private User parent; private User parent;
/**
* Energy units in kJ
*/
private int energy;
/**
* Maximum energy units in kJ
*/
private int maxEnergy;
/**
* Solar panel multiplier
* <br>TODO: Set this constant in dimension
*/
private static final float SOLAR_PANEL_MULTIPLIER = 1;
/** /**
* Maximum size of the console buffer (also called 'internal buffer') * 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' * List of attached hardware, 'modules'
@ -143,10 +128,8 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
hp = document.getInteger("hp"); hp = document.getInteger("hp");
shield = document.getInteger("shield"); shield = document.getInteger("shield");
setDirection(Direction.getDirection(document.getInteger("direction"))); setDirection(Direction.getDirection(document.getInteger("direction")));
energy = document.getInteger("energy");
ServerConfiguration config = GameServer.INSTANCE.getConfig(); ServerConfiguration config = GameServer.INSTANCE.getConfig();
maxEnergy = config.getInt("battery_max_energy");
maxHp = config.getInt("cubot_max_hp"); maxHp = config.getInt("cubot_max_hp");
maxShield = config.getInt("cubot_max_shield"); maxShield = config.getInt("cubot_max_shield");
@ -176,8 +159,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
@Override @Override
public void update() { public void update() {
storeEnergy((int) (SOLAR_PANEL_MULTIPLIER * GameServer.INSTANCE.getDayNightCycle().getSunIntensity()));
if (currentAction == Action.WALKING) { if (currentAction == Action.WALKING) {
if (spendEnergy(100)) { if (spendEnergy(100)) {
if (!incrementLocation()) { if (!incrementLocation()) {
@ -225,7 +206,6 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
json.put("hp", hp); json.put("hp", hp);
json.put("shield", shield); json.put("shield", shield);
json.put("action", lastAction.ordinal()); json.put("action", lastAction.ordinal());
json.put("energy", energy);
if (parent != null) { if (parent != null) {
json.put("parent", parent.getUsername()); //Only used client-side for now 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("hp", hp);
dbObject.put("shield", shield); dbObject.put("shield", shield);
dbObject.put("action", lastAction.ordinal()); dbObject.put("action", lastAction.ordinal());
dbObject.put("energy", energy);
if (parent != null) { if (parent != null) {
dbObject.put("parent", parent.getUsername()); //Only used client-side for now 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); setDead(false);
setHp(maxHp); setHp(maxHp);
setShield(0); setShield(0);
setEnergy(maxEnergy); setEnergy(((CubotBattery) getHardware(CubotBattery.class)).getMaxEnergy());
clearKeyboardBuffer(); clearKeyboardBuffer();
consoleMessagesBuffer.clear(); consoleMessagesBuffer.clear();
lastConsoleMessagesBuffer.clear(); lastConsoleMessagesBuffer.clear();
@ -354,34 +333,41 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
} }
public int getEnergy() { public int getEnergy() {
return energy; CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
return battery.getEnergy();
} }
public void setEnergy(int energy) { public void setEnergy(int energy) {
this.energy = energy; CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
battery.setEnergy(energy);
} }
public boolean spendEnergy(int amount) { public boolean spendEnergy(int amount) {
if (energy - amount < 0) { CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
if (battery.getEnergy() - amount < 0) {
return false; return false;
} else { } else {
energy -= amount; battery.setEnergy(battery.getEnergy() - amount);
return true; return true;
} }
} }
public void storeEnergy(int amount) { 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) { public void setMaxEnergy(int maxEnergy) {
this.maxEnergy = maxEnergy; CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
battery.setMaxEnergy(maxEnergy);
} }
public int getMaxEnergy() { public int getMaxEnergy() {
return maxEnergy; CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class);
return battery.getMaxEnergy();
} }
public int getShield() { public int getShield() {
@ -422,8 +408,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
@Override @Override
public Memory getFloppyData() { public Memory getFloppyData() {
//TODO change DEFAULT_ADDRESS to getHW(class) to allow mutable addresses CubotFloppyDrive drive = (CubotFloppyDrive) getHardware(CubotFloppyDrive.class);
CubotFloppyDrive drive = ((CubotFloppyDrive) getHardware(CubotFloppyDrive.DEFAULT_ADDRESS));
if (drive.getFloppy() != null) { if (drive.getFloppy() != null) {
return drive.getFloppy().getMemory(); return drive.getFloppy().getMemory();
@ -515,6 +500,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
public void setMaxShield(int maxShield) { public void setMaxShield(int maxShield) {
this.maxShield = maxShield; this.maxShield = maxShield;
} }
@Override @Override
public void heal(int amount) { public void heal(int amount) {
hp += amount; hp += amount;
@ -538,11 +524,13 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
} }
} }
@Override
public void attachHardware(HardwareModule hardware, int address) { public void attachHardware(HardwareModule hardware, int address) {
hardwareAddresses.put(address, hardware); hardwareAddresses.put(address, hardware);
hardwareModules.put(hardware.getClass(), address); hardwareModules.put(hardware.getClass(), address);
} }
@Override
public void detachHardware(int address) { public void detachHardware(int address) {
hardwareAddresses.remove(address); hardwareAddresses.remove(address);
@ -555,6 +543,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
hardwareModules.remove(toRemove); hardwareModules.remove(toRemove);
} }
@Override
public boolean hardwareInterrupt(int address, Status status) { public boolean hardwareInterrupt(int address, Status status) {
HardwareModule hardware = hardwareAddresses.get(address); HardwareModule hardware = hardwareAddresses.get(address);
@ -566,6 +555,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me
} }
} }
@Override
public int hardwareQuery(int address) { public int hardwareQuery(int address) {
HardwareModule hardware = hardwareAddresses.get(address); HardwareModule hardware = hardwareAddresses.get(address);

View File

@ -1,10 +1,13 @@
package net.simon987.cubotplugin; 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.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document; 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; public static final int DEFAULT_ADDRESS = 0x000A;
@ -12,16 +15,38 @@ public class CubotBattery extends CubotHardwareModule {
* Hardware ID (Should be unique) * Hardware ID (Should be unique)
*/ */
public static final char HWID = 0x000A; public static final char HWID = 0x000A;
/**
* Solar panel multiplier
* <br>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_POLL = 1;
private static final int BATTERY_GET_MAX_CAPACITY = 2; private static final int BATTERY_GET_MAX_CAPACITY = 2;
public CubotBattery(Cubot cubot) { public CubotBattery(ControllableUnit unit) {
super(cubot); 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) { public CubotBattery(Document document, ControllableUnit cubot) {
super(document, cubot); super(document, cubot);
energy = document.getInteger("energy");
maxEnergy = document.getInteger("max_energy");
} }
@Override @Override
@ -30,16 +55,12 @@ public class CubotBattery extends CubotHardwareModule {
int a = getCpu().getRegisterSet().getRegister("A").getValue(); int a = getCpu().getRegisterSet().getRegister("A").getValue();
if (a == BATTERY_POLL) { if (a == BATTERY_POLL) {
getCpu().getRegisterSet().getRegister("B").setValue(cubot.getEnergy()); getCpu().getRegisterSet().getRegister("B").setValue(energy);
} else if (a == BATTERY_GET_MAX_CAPACITY) { } 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 @Override
@ -47,4 +68,53 @@ public class CubotBattery extends CubotHardwareModule {
return HWID; 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()));
}
} }

View File

@ -1,5 +1,6 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.objects.GameObject; import net.simon987.server.game.objects.GameObject;
@ -9,7 +10,7 @@ import org.bson.Document;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
public class CubotComPort extends CubotHardwareModule { public class CubotComPort extends HardwareModule {
public static final char HWID = 0xD; public static final char HWID = 0xD;
public static final int DEFAULT_ADDRESS = 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_SELF_OUT = 3;
private static final int COMPORT_CONSOLE_CLEAR = 4; private static final int COMPORT_CONSOLE_CLEAR = 4;
public CubotComPort(Cubot cubot) { public CubotComPort(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotComPort(Document document, ControllableUnit cubot) { public CubotComPort(Document document, ControllableUnit cubot) {
@ -37,21 +38,23 @@ public class CubotComPort extends CubotHardwareModule {
if (a == COMPORT_BUFFER_CLEAR) { if (a == COMPORT_BUFFER_CLEAR) {
cubot.getConsoleMessagesBuffer().clear(); unit.getConsoleMessagesBuffer().clear();
} else if (a == COMPORT_CONSOLE_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) { } else if (a == COMPORT_POLL) {
if (cubot.spendEnergy(4)) { if (unit.spendEnergy(4)) {
int x = getCpu().getRegisterSet().getRegister("X").getValue(); int x = getCpu().getRegisterSet().getRegister("X").getValue();
//Read all messages in the console buffer to memory at X //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) { if (x + MESSAGE_LENGTH >= getCpu().getMemory().getWords().length) {
//todo set interrupt ? //todo set interrupt ?
getCpu().getStatus().setErrorFlag(true); getCpu().getStatus().setErrorFlag(true);
@ -61,17 +64,17 @@ public class CubotComPort extends CubotHardwareModule {
} }
//Set B = number of messages //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) { } else if (a == COMPORT_FRONT_PORT_OUT) {
if (cubot.spendEnergy(5)) { if (unit.spendEnergy(5)) {
//Get object directly in front of the Cubot //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 //Todo will have to add getGameObjectsBlockingAt to enable Factory
ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsAt(frontTile.x, frontTile.y); ArrayList<GameObject> objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
if (objects.size() > 0 && objects.get(0) instanceof MessageReceiver) { if (objects.size() > 0 && objects.get(0) instanceof MessageReceiver) {
@ -98,7 +101,7 @@ public class CubotComPort extends CubotHardwareModule {
} else if (a == COMPORT_SELF_OUT) { } else if (a == COMPORT_SELF_OUT) {
if (cubot.spendEnergy(1)) { if (unit.spendEnergy(1)) {
int x = getCpu().getRegisterSet().getRegister("X").getValue(); int x = getCpu().getRegisterSet().getRegister("X").getValue();
@ -111,7 +114,7 @@ public class CubotComPort extends CubotHardwareModule {
//Get MESSAGE_LENGTH-word message pointed by X //Get MESSAGE_LENGTH-word message pointed by X
char[] message = new char[MESSAGE_LENGTH]; char[] message = new char[MESSAGE_LENGTH];
System.arraycopy(getCpu().getMemory().getWords(), x, message, 0, 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; return;
} }
} }

View File

@ -1,10 +1,11 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document; import org.bson.Document;
public class CubotCore extends CubotHardwareModule { public class CubotCore extends HardwareModule {
public static final int DEFAULT_ADDRESS = 0x000E; 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_STATUS_POLL = 1;
private static final int CORE_HULL_POLL = 2; private static final int CORE_HULL_POLL = 2;
public CubotCore(Cubot cubot) { public CubotCore(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotCore(Document document, ControllableUnit cubot) { public CubotCore(Document document, ControllableUnit unit) {
super(document, cubot); super(document, unit);
} }
@Override @Override
@ -30,9 +31,11 @@ public class CubotCore extends CubotHardwareModule {
int a = getCpu().getRegisterSet().getRegister("A").getValue(); int a = getCpu().getRegisterSet().getRegister("A").getValue();
if (a == CORE_STATUS_POLL) { 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) { } else if (a == CORE_HULL_POLL) {
getCpu().getRegisterSet().getRegister("B").setValue(cubot.getHp()); getCpu().getRegisterSet().getRegister("B").setValue(unit.getHp());
} }
} }

View File

@ -1,5 +1,6 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.item.Item; import net.simon987.server.game.item.Item;
import net.simon987.server.game.objects.Action; 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 net.simon987.server.game.world.Tile;
import org.bson.Document; import org.bson.Document;
public class CubotDrill extends CubotHardwareModule { public class CubotDrill extends HardwareModule {
/** /**
* Hardware ID (Should be unique) * 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_POLL = 1;
private static final int DRILL_GATHER = 2; // simplified gather private static final int DRILL_GATHER = 2; // simplified gather
public CubotDrill(Cubot cubot) { public CubotDrill(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotDrill(Document document, ControllableUnit cubot) { public CubotDrill(Document document, ControllableUnit cubot) {
@ -42,15 +43,15 @@ public class CubotDrill extends CubotHardwareModule {
} else if (a == DRILL_GATHER) { } else if (a == DRILL_GATHER) {
if (cubot.spendEnergy(1400)) { if (unit.spendEnergy(1400)) {
if (cubot.getCurrentAction() == Action.IDLE) { 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(); Item newItem = tile.drill();
if (newItem != null) { if (newItem != null) {
cubot.setCurrentAction(Action.DIGGING); unit.setCurrentAction(Action.DIGGING);
cubot.giveItem(newItem); unit.giveItem(newItem);
} }
} }
} }

View File

@ -16,11 +16,4 @@ public abstract class CubotHardwareModule extends HardwareModule {
this.cubot = cubot; this.cubot = cubot;
} }
@Override
public Document mongoSerialise() {
Document document = new Document();
document.put("type", getClass().getCanonicalName());
return document;
}
} }

View File

@ -1,11 +1,12 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document; import org.bson.Document;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
public class CubotHologram extends CubotHardwareModule { public class CubotHologram extends HardwareModule {
/** /**
* Hardware ID (Should be unique) * Hardware ID (Should be unique)
@ -31,8 +32,8 @@ public class CubotHologram extends CubotHardwareModule {
*/ */
private int displayColor = 0; private int displayColor = 0;
public CubotHologram(Cubot cubot) { public CubotHologram(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotHologram(Document document, ControllableUnit cubot) { public CubotHologram(Document document, ControllableUnit cubot) {
@ -80,7 +81,7 @@ public class CubotHologram extends CubotHardwareModule {
} else if (a == HOLO_DISPLAY_COLOR) { } else if (a == HOLO_DISPLAY_COLOR) {
if (cubot.spendEnergy(4)) { if (unit.spendEnergy(4)) {
int b = getCpu().getRegisterSet().getRegister("B").getValue(); int b = getCpu().getRegisterSet().getRegister("B").getValue();
int c = getCpu().getRegisterSet().getRegister("C").getValue(); int c = getCpu().getRegisterSet().getRegister("C").getValue();

View File

@ -1,16 +1,16 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.GameServer; import net.simon987.server.GameServer;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.item.Item; import net.simon987.server.game.item.Item;
import net.simon987.server.game.item.ItemCopper;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import org.bson.Document; import org.bson.Document;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class CubotInventory extends CubotHardwareModule { public class CubotInventory extends HardwareModule {
/** /**
* Hardware ID (Should be unique) * Hardware ID (Should be unique)
@ -29,11 +29,10 @@ public class CubotInventory extends CubotHardwareModule {
private int position = 0; private int position = 0;
public CubotInventory(Cubot cubot) { public CubotInventory(ControllableUnit unit) {
super(cubot); super(null, unit);
inventory = new HashMap<>(); inventory = new HashMap<>();
inventory.put(2, new ItemCopper(new Document())); // TODO: Remove debug value
} }
public CubotInventory(Document document, ControllableUnit cubot) { public CubotInventory(Document document, ControllableUnit cubot) {
@ -56,12 +55,12 @@ public class CubotInventory extends CubotHardwareModule {
private void scanItem() { private void scanItem() {
int x = getCpu().getRegisterSet().getRegister("X").getValue(); int x = getCpu().getRegisterSet().getRegister("X").getValue();
Item item = inventory.get(position); Item item = inventory.get(position);
item.digitize(cubot.getCpu().getMemory(), x); item.digitize(unit.getCpu().getMemory(), x);
} }
public Item clearItem() { public Item clearItem() {
Item item = inventory.get(position); Item item = inventory.get(position);
item.clear(cubot); item.clear(unit);
inventory.remove(position); inventory.remove(position);
return item; return item;
@ -100,13 +99,13 @@ public class CubotInventory extends CubotHardwareModule {
getCpu().getRegisterSet().getRegister("B").setValue(result); getCpu().getRegisterSet().getRegister("B").setValue(result);
} else if (a == INV_CLEAR) { } else if (a == INV_CLEAR) {
if (cubot.spendEnergy(100)) { if (unit.spendEnergy(100)) {
clearItem(); clearItem();
} }
} else if (a == INV_SEEK) { } else if (a == INV_SEEK) {
setPosition(getCpu().getRegisterSet().getRegister("X").getValue()); setPosition(getCpu().getRegisterSet().getRegister("X").getValue());
} else if (a == INV_SCAN) { } else if (a == INV_SCAN) {
if (cubot.spendEnergy(200)) { if (unit.spendEnergy(200)) {
scanItem(); scanItem();
clearItem(); clearItem();
} }

View File

@ -1,6 +1,7 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.GameServer; import net.simon987.server.GameServer;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.*; import net.simon987.server.game.objects.*;
import org.bson.Document; import org.bson.Document;
@ -8,7 +9,7 @@ import org.bson.Document;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
public class CubotLaser extends CubotHardwareModule { public class CubotLaser extends HardwareModule {
/** /**
* Hardware ID (Should be unique) * Hardware ID (Should be unique)
@ -23,8 +24,8 @@ public class CubotLaser extends CubotHardwareModule {
private static final int LASER_DAMAGE = 25; private static final int LASER_DAMAGE = 25;
public CubotLaser(Cubot cubot) { public CubotLaser(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotLaser(Document document, ControllableUnit cubot) { public CubotLaser(Document document, ControllableUnit cubot) {
@ -46,19 +47,19 @@ public class CubotLaser extends CubotHardwareModule {
if (a == LASER_WITHDRAW) { if (a == LASER_WITHDRAW) {
Point frontTile = cubot.getFrontTile(); Point frontTile = unit.getFrontTile();
ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); ArrayList<GameObject> 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 //FIXME: Problem here if more than 1 object
if (objects.get(0) instanceof InventoryHolder) { if (objects.get(0) instanceof InventoryHolder) {
if (((InventoryHolder) objects.get(0)).canTakeItem(b)) { if (((InventoryHolder) objects.get(0)).canTakeItem(b)) {
if (cubot.spendEnergy(30)) { if (unit.spendEnergy(30)) {
//Take the item //Take the item
((InventoryHolder) objects.get(0)).takeItem(b); ((InventoryHolder) objects.get(0)).takeItem(b);
cubot.giveItem(GameServer.INSTANCE.getRegistry().makeItem(b)); unit.giveItem(GameServer.INSTANCE.getRegistry().makeItem(b));
cubot.setCurrentAction(Action.WITHDRAWING); unit.setCurrentAction(Action.WITHDRAWING);
} }
} }
} }
@ -69,12 +70,12 @@ public class CubotLaser extends CubotHardwareModule {
// TODO // TODO
} else if (a == LASER_ATTACK) { } else if (a == LASER_ATTACK) {
if (cubot.getCurrentAction() == Action.IDLE) { if (unit.getCurrentAction() == Action.IDLE) {
if (cubot.spendEnergy(70)) { if (unit.spendEnergy(70)) {
//Get object directly in front of the Cubot //Get object directly in front of the Cubot
Point frontTile = cubot.getFrontTile(); Point frontTile = unit.getFrontTile();
ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsAt(frontTile.x, frontTile.y); ArrayList<GameObject> objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y);
//todo: Add option in config to allow PvP //todo: Add option in config to allow PvP
if (objects.size() > 0 && objects.get(0) instanceof Attackable && !(objects.get(0) instanceof Cubot)) { 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);
} }
} }

View File

@ -1,12 +1,13 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.Action; import net.simon987.server.game.objects.Action;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
import net.simon987.server.game.objects.Direction; import net.simon987.server.game.objects.Direction;
import org.bson.Document; import org.bson.Document;
public class CubotLeg extends CubotHardwareModule { public class CubotLeg extends HardwareModule {
public static final int DEFAULT_ADDRESS = 1; public static final int DEFAULT_ADDRESS = 1;
@ -18,12 +19,12 @@ public class CubotLeg extends CubotHardwareModule {
*/ */
static final char HWID = 0x0001; static final char HWID = 0x0001;
public CubotLeg(Cubot cubot) { public CubotLeg(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotLeg(Document document, ControllableUnit cubot) { public CubotLeg(Document document, ControllableUnit unit) {
super(document, cubot); super(document, unit);
} }
@Override @Override
@ -34,7 +35,7 @@ public class CubotLeg extends CubotHardwareModule {
@Override @Override
public void handleInterrupt(Status status) { public void handleInterrupt(Status status) {
if (cubot.getCurrentAction() == Action.IDLE) { if (unit.getCurrentAction() == Action.IDLE) {
int a = getCpu().getRegisterSet().getRegister("A").getValue(); int a = getCpu().getRegisterSet().getRegister("A").getValue();
int b = getCpu().getRegisterSet().getRegister("B").getValue(); int b = getCpu().getRegisterSet().getRegister("B").getValue();
@ -44,8 +45,8 @@ public class CubotLeg extends CubotHardwareModule {
Direction dir = Direction.getDirection(b); Direction dir = Direction.getDirection(b);
if (dir != null) { if (dir != null) {
if (cubot.spendEnergy(20)) { if (unit.spendEnergy(20)) {
cubot.setDirection(Direction.getDirection(b)); unit.setDirection(Direction.getDirection(b));
status.setErrorFlag(false); status.setErrorFlag(false);
} }
} else { } else {
@ -55,17 +56,17 @@ public class CubotLeg extends CubotHardwareModule {
} else if (a == LEGS_SET_DIR_AND_WALK) { } else if (a == LEGS_SET_DIR_AND_WALK) {
if (cubot.getMaxEnergy() >= 100) { if (unit.getMaxEnergy() >= 100) {
Direction dir = Direction.getDirection(b); Direction dir = Direction.getDirection(b);
if (dir != null) { if (dir != null) {
cubot.setDirection(Direction.getDirection(b)); unit.setDirection(Direction.getDirection(b));
status.setErrorFlag(false); status.setErrorFlag(false);
} else { } else {
status.setErrorFlag(true); status.setErrorFlag(true);
} }
cubot.setCurrentAction(Action.WALKING); unit.setCurrentAction(Action.WALKING);
} }
} }
} }

View File

@ -1,5 +1,6 @@
package net.simon987.cubotplugin; package net.simon987.cubotplugin;
import net.simon987.server.assembly.HardwareModule;
import net.simon987.server.assembly.Memory; import net.simon987.server.assembly.Memory;
import net.simon987.server.assembly.Status; import net.simon987.server.assembly.Status;
import net.simon987.server.game.objects.ControllableUnit; import net.simon987.server.game.objects.ControllableUnit;
@ -9,7 +10,7 @@ import org.bson.Document;
import java.util.ArrayList; import java.util.ArrayList;
public class CubotLidar extends CubotHardwareModule { public class CubotLidar extends HardwareModule {
/** /**
* Hardware ID (Should be unique) * 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_POS = 4;
private static final int LIDAR_GET_WORLD_SIZE = 5; private static final int LIDAR_GET_WORLD_SIZE = 5;
public CubotLidar(Cubot cubot) { public CubotLidar(ControllableUnit unit) {
super(cubot); super(null, unit);
} }
public CubotLidar(Document document, ControllableUnit cubot) { public CubotLidar(Document document, ControllableUnit unit) {
super(document, cubot); super(document, unit);
} }
@Override @Override
@ -44,18 +45,18 @@ public class CubotLidar extends CubotHardwareModule {
switch (a) { switch (a) {
case LIDAR_GET_POS: case LIDAR_GET_POS:
getCpu().getRegisterSet().getRegister("X").setValue(cubot.getX()); getCpu().getRegisterSet().getRegister("X").setValue(unit.getX());
getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getY()); getCpu().getRegisterSet().getRegister("Y").setValue(unit.getY());
break; break;
case LIDAR_GET_PATH: case LIDAR_GET_PATH:
if (cubot.spendEnergy(50)) { if (unit.spendEnergy(50)) {
int c = getCpu().getRegisterSet().getRegister("C").getValue(); int c = getCpu().getRegisterSet().getRegister("C").getValue();
int b = getCpu().getRegisterSet().getRegister("B").getValue(); int b = getCpu().getRegisterSet().getRegister("B").getValue();
int destX = getCpu().getRegisterSet().getRegister("X").getValue(); int destX = getCpu().getRegisterSet().getRegister("X").getValue();
int destY = getCpu().getRegisterSet().getRegister("Y").getValue(); int destY = getCpu().getRegisterSet().getRegister("Y").getValue();
//Get path //Get path
ArrayList<Node> nodes = Pathfinder.findPath(cubot.getWorld(), cubot.getX(), cubot.getY(), ArrayList<Node> nodes = Pathfinder.findPath(unit.getWorld(), unit.getX(), unit.getY(),
destX, destY, b); destX, destY, b);
//Write to memory //Write to memory
@ -102,13 +103,13 @@ public class CubotLidar extends CubotHardwareModule {
break; break;
case LIDAR_GET_MAP: case LIDAR_GET_MAP:
if (cubot.spendEnergy(10)) { if (unit.spendEnergy(10)) {
char[][] mapInfo = cubot.getWorld().getMapInfo(); char[][] mapInfo = unit.getWorld().getMapInfo();
//Write map data to the location specified by register X //Write map data to the location specified by register X
int i = getCpu().getRegisterSet().getRegister("X").getValue(); int i = getCpu().getRegisterSet().getRegister("X").getValue();
for (int x = 0; x < cubot.getWorld().getWorldSize(); x++) { for (int x = 0; x < unit.getWorld().getWorldSize(); x++) {
for (int y = 0; y < cubot.getWorld().getWorldSize(); y++) { for (int y = 0; y < unit.getWorld().getWorldSize(); y++) {
getCpu().getMemory().set(i++, mapInfo[x][y]); getCpu().getMemory().set(i++, mapInfo[x][y]);
} }
} }
@ -116,13 +117,13 @@ public class CubotLidar extends CubotHardwareModule {
break; break;
case LIDAR_GET_WORLD_SIZE: case LIDAR_GET_WORLD_SIZE:
getCpu().getRegisterSet().getRegister("X").setValue(cubot.getWorld().getWorldSize()); getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getWorldSize());
getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getWorld().getWorldSize()); getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getWorldSize());
break; break;
case LIDAR_GET_WORLD_POS: case LIDAR_GET_WORLD_POS:
getCpu().getRegisterSet().getRegister("X").setValue(cubot.getWorld().getX()); getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getX());
getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getWorld().getY()); getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getY());
break; break;
} }

View File

@ -50,13 +50,6 @@ public class UserCreationListener implements GameEventListener {
cubot.getWorld().addObject(cubot); cubot.getWorld().addObject(cubot);
cubot.getWorld().incUpdatable(); 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); cubot.setParent(user);
user.setControlledUnit(cubot); user.setControlledUnit(cubot);
@ -81,6 +74,10 @@ public class UserCreationListener implements GameEventListener {
e.printStackTrace(); 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)"); LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)");
} }
} }

View File

@ -1,17 +1,19 @@
package net.simon987.npcplugin; package net.simon987.npcplugin;
import net.simon987.server.GameServer; 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.Structure;
import net.simon987.server.game.objects.Updatable; import net.simon987.server.game.objects.Updatable;
import org.bson.Document; import org.bson.Document;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import java.awt.*; import java.awt.*;
import java.util.Arrays;
/** /**
* Game objects that regularly creates NonPlayerCharacters * 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; private static final int MAP_INFO = 0x0401;
@ -30,6 +32,15 @@ public class Factory extends Structure implements Updatable {
*/ */
private int cooldown = 0; 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() { public Factory() {
super(2, 2); super(2, 2);
} }
@ -57,14 +68,7 @@ public class Factory extends Structure implements Updatable {
Point p = getAdjacentTile(); Point p = getAdjacentTile();
if (p != null) { if (p != null) {
NonPlayerCharacter npc = new HarvesterNPC(); NonPlayerCharacter npc = spawnNPC(p);
npc.setWorld(getWorld());
npc.setObjectId(new ObjectId());
npc.setX(p.x);
npc.setY(p.y);
getWorld().addObject(npc);
getWorld().incUpdatable();
settlement.addNpc(npc); settlement.addNpc(npc);
} }
} }
@ -75,4 +79,65 @@ public class Factory extends Structure implements Updatable {
cooldown--; 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;
}
} }

View File

@ -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<Integer, HardwareModule> hardwareAddresses = new HashMap<>();
private Map<Class<? extends HardwareModule>, Integer> hardwareModules = new HashMap<>();
private Action currentAction = Action.IDLE;
private Action lastAction = Action.IDLE;
private ArrayList<char[]> consoleMessagesBuffer = new ArrayList<>(30); //todo load from conf
private ArrayList<char[]> 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<Integer> kbBuffer) {
}
@Override
public void setParent(User user) {
}
@Override
public User getParent() {
return null;
}
@Override
public ArrayList<Integer> getKeyboardBuffer() {
return null;
}
@Override
public Memory getFloppyData() {
return null;
}
@Override
public void setAction(Action action) {
currentAction = action;
}
@Override
public ArrayList<char[]> 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<Document> 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();
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -13,13 +13,17 @@ import net.simon987.server.logging.LogManager;
import net.simon987.server.plugin.ServerPlugin; import net.simon987.server.plugin.ServerPlugin;
import org.bson.Document; import org.bson.Document;
import java.io.InputStream;
import java.util.Map; import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class NpcPlugin extends ServerPlugin { public class NpcPlugin extends ServerPlugin {
public static Map<String, Settlement> settlementMap; public static Map<String, Settlement> settlementMap;
public static Document DEFAULT_HACKED_NPC;
@Override @Override
public void init(GameServer gameServer) { public void init(GameServer gameServer) {
@ -39,14 +43,22 @@ public class NpcPlugin extends ServerPlugin {
registry.registerGameObject(ElectricBox.class); registry.registerGameObject(ElectricBox.class);
registry.registerGameObject(Portal.class); registry.registerGameObject(Portal.class);
registry.registerGameObject(VaultExitPortal.class); registry.registerGameObject(VaultExitPortal.class);
registry.registerGameObject(HackedNPC.class);
registry.registerHardware(RadioReceiverHardware.class); registry.registerHardware(RadioReceiverHardware.class);
registry.registerHardware(NpcBattery.class);
registry.registerHardware(NpcInventory.class);
registry.registerTile(TileVaultFloor.ID, TileVaultFloor.class); registry.registerTile(TileVaultFloor.ID, TileVaultFloor.class);
registry.registerTile(TileVaultWall.ID, TileVaultWall.class); registry.registerTile(TileVaultWall.ID, TileVaultWall.class);
settlementMap = new ConcurrentHashMap<>(); 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"); LogManager.LOGGER.info("(NPC Plugin) Initialised NPC plugin");
} }

View File

@ -59,6 +59,7 @@ public class Settlement implements MongoSerializable {
this.world = world; this.world = world;
this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ? this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ?
this.password = "12345678".toCharArray();
outerLoopFactory: outerLoopFactory:
for (int x = 2; x < 12; x++) { for (int x = 2; x < 12; x++) {
@ -175,7 +176,7 @@ public class Settlement implements MongoSerializable {
} }
document.put("factory", factory.getObjectId()); document.put("factory", factory.getObjectId());
document.put("difficulty_level", difficultyLevel.ordinal()); document.put("difficulty_level", difficultyLevel.ordinal());
document.put("password", "1234567"); //todo document.put("password", String.valueOf(password));
List<ObjectId> npcArray = new ArrayList<>(npcs.size()); List<ObjectId> npcArray = new ArrayList<>(npcs.size());

View File

@ -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
}
]
}

View File

@ -1,3 +1,4 @@
classpath=net.simon987.npcplugin.NpcPlugin classpath=net.simon987.npcplugin.NpcPlugin
name=NPC Plugin name=NPC Plugin
version=1.1 version=1.1
depend=Cubot Plugin

View File

@ -60,6 +60,41 @@ public class CPU implements MongoSerializable {
private static final char EXECUTION_COST_ADDR = 0x0050; private static final char EXECUTION_COST_ADDR = 0x0050;
private static final char EXECUTED_INS_ADDR = 0x0051; 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 * Creates a new CPU
*/ */
@ -359,7 +394,6 @@ public class CPU implements MongoSerializable {
cpu.codeSectionOffset = obj.getInteger("codeSegmentOffset"); cpu.codeSectionOffset = obj.getInteger("codeSegmentOffset");
cpu.memory = new Memory((Document) obj.get("memory")); cpu.memory = new Memory((Document) obj.get("memory"));
cpu.registerSet = RegisterSet.deserialize((Document) obj.get("registerSet")); cpu.registerSet = RegisterSet.deserialize((Document) obj.get("registerSet"));
@ -379,6 +413,14 @@ public class CPU implements MongoSerializable {
return memory; return memory;
} }
public void setMemory(Memory memory) {
this.memory = memory;
}
public void setRegisterSet(RegisterSet registerSet) {
this.registerSet = registerSet;
}
public Status getStatus() { public Status getStatus() {
return status; return status;
} }

View File

@ -11,13 +11,14 @@ import org.json.simple.JSONObject;
public abstract class HardwareModule implements MongoSerializable, JSONSerializable { public abstract class HardwareModule implements MongoSerializable, JSONSerializable {
private CPU cpu; private CPU cpu;
protected ControllableUnit unit;
public HardwareModule() { public HardwareModule() {
} }
public HardwareModule(Document document, ControllableUnit unit) { public HardwareModule(Document document, ControllableUnit unit) {
this.unit = unit;
} }
/** /**
@ -58,4 +59,12 @@ public abstract class HardwareModule implements MongoSerializable, JSONSerializa
public JSONObject debugJsonSerialise() { public JSONObject debugJsonSerialise() {
return null; return null;
} }
@Override
public Document mongoSerialise() {
Document document = new Document();
document.put("type", getClass().getCanonicalName());
return document;
}
} }

View File

@ -7,9 +7,10 @@ import net.simon987.server.game.world.World;
import net.simon987.server.user.User; import net.simon987.server.user.User;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
public interface ControllableUnit { public interface ControllableUnit extends MessageReceiver, Rechargeable, Attackable {
ObjectId getObjectId(); ObjectId getObjectId();
@ -31,7 +32,11 @@ public interface ControllableUnit {
int getY(); int getY();
void setAction(Action listening); void setAction(Action action);
void setCurrentAction(Action action);
Action getCurrentAction();
World getWorld(); World getWorld();
@ -42,4 +47,9 @@ public interface ControllableUnit {
CPU getCpu(); CPU getCpu();
void giveItem(Item item); void giveItem(Item item);
Point getFrontTile();
void setDirection(Direction direction);
} }

View File

@ -71,6 +71,7 @@ harvester_hp_max=100
harvester_regen=5 harvester_regen=5
harvester_biomass_drop_count=8 harvester_biomass_drop_count=8
radio_tower_range=3 radio_tower_range=3
hacked_npc_mem_size=5120
#Vaults #Vaults
vault_door_open_time=4 vault_door_open_time=4
min_electric_box_count=1 min_electric_box_count=1

View File

@ -830,6 +830,7 @@ var ObjectType;
ObjectType["OBSTACLE"] = "net.simon987.npcplugin.Obstacle"; ObjectType["OBSTACLE"] = "net.simon987.npcplugin.Obstacle";
ObjectType["ELECTRIC_BOX"] = "net.simon987.npcplugin.ElectricBox"; ObjectType["ELECTRIC_BOX"] = "net.simon987.npcplugin.ElectricBox";
ObjectType["PORTAL"] = "net.simon987.npcplugin.Portal"; ObjectType["PORTAL"] = "net.simon987.npcplugin.Portal";
ObjectType["HACKED_NPC"] = "net.simon987.npcplugin.HackedNPC";
})(ObjectType || (ObjectType = {})); })(ObjectType || (ObjectType = {}));
var ItemType; var ItemType;
(function (ItemType) { (function (ItemType) {
@ -873,6 +874,8 @@ var GameObject = (function (_super) {
return new ElectricBox(json); return new ElectricBox(json);
case ObjectType.PORTAL: case ObjectType.PORTAL:
return new Portal(json); return new Portal(json);
case ObjectType.HACKED_NPC:
return new HackedNPC(json);
default: default:
return null; return null;
} }
@ -917,7 +920,7 @@ var Cubot = (function (_super) {
_this.heldItem = json.heldItem; _this.heldItem = json.heldItem;
_this.direction = json.direction; _this.direction = json.direction;
_this.action = json.action; _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 = mar.game.make.sprite(0, 0, "sheet", null);
_this.cubotSprite.anchor.set(0.5, 0); _this.cubotSprite.anchor.set(0.5, 0);
_this.addChild(_this.cubotSprite); _this.addChild(_this.cubotSprite);
@ -949,6 +952,10 @@ var Cubot = (function (_super) {
_this.setShield(false); _this.setShield(false);
return _this; return _this;
} }
Cubot.prototype.getEnergy = function (json) {
return json["net.simon987.cubotplugin.CubotBattery"].energy;
};
Cubot.prototype.setShield = function (shield) { Cubot.prototype.setShield = function (shield) {
this.shieldBackSprite.visible = shield; this.shieldBackSprite.visible = shield;
this.shieldFrontSprite.visible = shield; this.shieldFrontSprite.visible = shield;
@ -1012,7 +1019,7 @@ var Cubot = (function (_super) {
console.log("Updating Cubot object"); console.log("Updating Cubot object");
} }
this.action = json.action; this.action = json.action;
this.energy = json.energy; this.energy = this.getEnergy(json);
this.direction = json.direction; this.direction = json.direction;
this.shield = json.shield; this.shield = json.shield;
this.createInventory([json.heldItem]); this.createInventory([json.heldItem]);
@ -1207,6 +1214,13 @@ var HarvesterNPC = (function (_super) {
break; 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) { HarvesterNPC.prototype.updateObject = function (json) {
if (DEBUG) { if (DEBUG) {
console.log("Updating Harvester NPC object"); console.log("Updating Harvester NPC object");
@ -1226,6 +1240,28 @@ var HarvesterNPC = (function (_super) {
}; };
return HarvesterNPC; return HarvesterNPC;
}(Cubot)); }(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) { var BiomassBlob = (function (_super) {
__extends(BiomassBlob, _super); __extends(BiomassBlob, _super);
function BiomassBlob(json) { function BiomassBlob(json) {

View File

@ -7,7 +7,8 @@ enum ObjectType {
VAULT_DOOR = "net.simon987.npcplugin.VaultDoor", VAULT_DOOR = "net.simon987.npcplugin.VaultDoor",
OBSTACLE = "net.simon987.npcplugin.Obstacle", OBSTACLE = "net.simon987.npcplugin.Obstacle",
ELECTRIC_BOX = "net.simon987.npcplugin.ElectricBox", ELECTRIC_BOX = "net.simon987.npcplugin.ElectricBox",
PORTAL = "net.simon987.npcplugin.Portal" PORTAL = "net.simon987.npcplugin.Portal",
HACKED_NPC = "net.simon987.npcplugin.HackedNPC"
} }
enum ItemType { enum ItemType {
@ -59,7 +60,6 @@ abstract class GameObject extends Phaser.Plugin.Isometric.IsoSprite {
switch (json.t) { switch (json.t) {
case ObjectType.CUBOT: case ObjectType.CUBOT:
return new Cubot(json); return new Cubot(json);
case ObjectType.BIOMASS: case ObjectType.BIOMASS:
return new BiomassBlob(json); return new BiomassBlob(json);
case ObjectType.HARVESTER_NPC: case ObjectType.HARVESTER_NPC:
@ -76,6 +76,8 @@ abstract class GameObject extends Phaser.Plugin.Isometric.IsoSprite {
return new ElectricBox(json); return new ElectricBox(json);
case ObjectType.PORTAL: case ObjectType.PORTAL:
return new Portal(json); return new Portal(json);
case ObjectType.HACKED_NPC:
return new HackedNPC(json);
default: default:
return null; return null;
@ -155,7 +157,7 @@ class Cubot extends GameObject {
this.heldItem = json.heldItem; this.heldItem = json.heldItem;
this.direction = json.direction; this.direction = json.direction;
this.action = json.action; 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 = mar.game.make.sprite(0, 0, "sheet", null);
this.cubotSprite.anchor.set(0.5, 0); this.cubotSprite.anchor.set(0.5, 0);
@ -197,6 +199,10 @@ class Cubot extends GameObject {
this.setShield(false); this.setShield(false);
} }
protected getEnergy(json): number {
return json["net.simon987.cubotplugin.CubotBattery"].energy
}
public setShield(shield: boolean) { public setShield(shield: boolean) {
this.shieldBackSprite.visible = shield; this.shieldBackSprite.visible = shield;
this.shieldFrontSprite.visible = shield; this.shieldFrontSprite.visible = shield;
@ -277,7 +283,7 @@ class Cubot extends GameObject {
} }
this.action = json.action; this.action = json.action;
this.energy = json.energy; this.energy = this.getEnergy(json);
this.direction = json.direction; this.direction = json.direction;
this.shield = json.shield; this.shield = json.shield;
@ -333,7 +339,7 @@ class Cubot extends GameObject {
this.setShield(this.shield > 0) 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); let fillColor: string = (holoColor & 0xFFFFFF).toString(16);
fillColor = "#" + ("000000".substr(fillColor.length) + fillColor); 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) { updateObject(json) {
if (DEBUG) { if (DEBUG) {
console.log("Updating Harvester NPC object") 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 { class BiomassBlob extends GameObject {