mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-10-31 16:26:51 +00:00 
			
		
		
		
	Merge pull request #179 from simon987/factory-rewrite
NPCPlugin refactor, Added HackedNPC
This commit is contained in:
		
						commit
						0973548b71
					
				| @ -20,7 +20,9 @@ | |||||||
|     <orderEntry type="module" module-name="Server" /> |     <orderEntry type="module" module-name="Server" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.7.0" level="project" /> |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> | ||||||
|  | |||||||
| @ -18,8 +18,7 @@ import java.awt.*; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.*; | import java.util.*; | ||||||
| 
 | 
 | ||||||
| public class Cubot extends GameObject implements Updatable, ControllableUnit, MessageReceiver, | public class Cubot extends GameObject implements Updatable, ControllableUnit, MessageReceiver { | ||||||
|         Attackable, Rechargeable, HardwareHost { |  | ||||||
| 
 | 
 | ||||||
|     private static final char MAP_INFO = 0x0200; |     private static final char MAP_INFO = 0x0200; | ||||||
| 
 | 
 | ||||||
| @ -91,25 +90,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 +127,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 +158,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 +205,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 +228,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 +257,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 +332,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 +407,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 +499,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 +523,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 +542,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 +554,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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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())); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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(20)) { |             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; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -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()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -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; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -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(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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(); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -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); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -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)"); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -19,7 +19,9 @@ | |||||||
|     <orderEntry type="module" module-name="Server" /> |     <orderEntry type="module" module-name="Server" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.7.0" level="project" /> |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> | ||||||
|  | |||||||
| @ -22,7 +22,9 @@ | |||||||
|     <orderEntry type="module" module-name="Server" /> |     <orderEntry type="module" module-name="Server" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.7.0" level="project" /> |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> | ||||||
|  | |||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package net.simon987.npcplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.game.objects.Action; | ||||||
|  | 
 | ||||||
|  | public class ExecuteCpuTask extends NPCTask { | ||||||
|  | 
 | ||||||
|  |     private static final int MAX_EXEC_TIME = GameServer.INSTANCE.getConfig().getInt("npc_exec_time"); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public boolean checkCompleted() { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void tick(NonPlayerCharacter npc) { | ||||||
|  | 
 | ||||||
|  |         HackedNPC hNpc = (HackedNPC) npc; | ||||||
|  | 
 | ||||||
|  |         //Execute code | ||||||
|  |         int timeout = Math.min(hNpc.getEnergy(), MAX_EXEC_TIME); | ||||||
|  |         hNpc.getCpu().reset(); | ||||||
|  |         int cost = hNpc.getCpu().execute(timeout); | ||||||
|  |         hNpc.spendEnergy(cost); | ||||||
|  | 
 | ||||||
|  |         if (hNpc.getCurrentAction() == Action.WALKING) { | ||||||
|  |             if (hNpc.spendEnergy(100)) { | ||||||
|  |                 if (hNpc.incrementLocation()) { | ||||||
|  |                     //Couldn't walk | ||||||
|  |                     hNpc.setCurrentAction(Action.IDLE); | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 hNpc.setCurrentAction(Action.IDLE); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,19 +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.ArrayList; | import java.util.Arrays; | ||||||
| import java.util.List; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 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; | ||||||
| 
 | 
 | ||||||
| @ -27,26 +27,21 @@ public class Factory extends Structure implements Updatable { | |||||||
|      */ |      */ | ||||||
|     private static final int NPC_CREATION_COOLDOWN = NonPlayerCharacter.LIFETIME / MAX_NPC_COUNT; |     private static final int NPC_CREATION_COOLDOWN = NonPlayerCharacter.LIFETIME / MAX_NPC_COUNT; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * List of associated NonPlayerCharacters |  | ||||||
|      */ |  | ||||||
|     private ArrayList<NonPlayerCharacter> npcs = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Number of ticks to wait until the Factory can spawn a new NPC |      * Number of ticks to wait until the Factory can spawn a new NPC | ||||||
|      */ |      */ | ||||||
|     private int cooldown = 0; |     private int cooldown = 0; | ||||||
| 
 | 
 | ||||||
|     /** |     private boolean locked = true; | ||||||
|      * Temporary NPC objectId array. The Factory links the NPCs to itself when initialised, |  | ||||||
|      * at the first call of update(). |  | ||||||
|      */ |  | ||||||
|     private Object[] tmpNpcArray = new Object[0]; |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Factory are uninitialised until the first update() call |      * If non-null, the next spawned NPC will be a HackedNPC and the program will be | ||||||
|  |      * injected in its memory | ||||||
|      */ |      */ | ||||||
|     private boolean initialised = false; |     private char[] program; | ||||||
|  |     private int programIndex = 0; | ||||||
|  | 
 | ||||||
|  |     private static final int PROGRAM_SIZE = GameServer.INSTANCE.getConfig().getInt("factory_program_size"); | ||||||
| 
 | 
 | ||||||
|     public Factory() { |     public Factory() { | ||||||
|         super(2, 2); |         super(2, 2); | ||||||
| @ -54,8 +49,6 @@ public class Factory extends Structure implements Updatable { | |||||||
| 
 | 
 | ||||||
|     public Factory(Document document) { |     public Factory(Document document) { | ||||||
|         super(document, 2, 2); |         super(document, 2, 2); | ||||||
| 
 |  | ||||||
|         tmpNpcArray = ((ArrayList) document.get("npcs")).toArray(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -70,66 +63,95 @@ public class Factory extends Structure implements Updatable { | |||||||
|     @Override |     @Override | ||||||
|     public void update() { |     public void update() { | ||||||
| 
 | 
 | ||||||
|         if (!initialised) { |         Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); | ||||||
| 
 | 
 | ||||||
|             initialised = true; |         if (settlement == null) { | ||||||
|  |             //Only happens when server is killed during save function | ||||||
|  |             getWorld().decUpdatable(); | ||||||
|  |             setDead(true); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|             for (Object id : tmpNpcArray) { |         if (cooldown == 0) { | ||||||
|  |             if (settlement.getNpcs().size() < MAX_NPC_COUNT) { | ||||||
|  |                 Point p = getAdjacentTile(); | ||||||
| 
 | 
 | ||||||
|                 NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((ObjectId) id); |                 if (p != null) { | ||||||
|  |                     NonPlayerCharacter npc = spawnNPC(p); | ||||||
|  |                     settlement.addNpc(npc); | ||||||
| 
 | 
 | ||||||
|                 if (npc != null) { |                     getWorld().addObject(npc); | ||||||
|                     npc.setFactory(this); |                     getWorld().incUpdatable(); | ||||||
|                     npcs.add(npc); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             tmpNpcArray = null; |             cooldown += NPC_CREATION_COOLDOWN; | ||||||
| 
 | 
 | ||||||
|         } else { |         } else { | ||||||
| 
 |             cooldown--; | ||||||
|             if (cooldown == 0) { |  | ||||||
|                 if (npcs.size() < MAX_NPC_COUNT) { |  | ||||||
|                     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(); |  | ||||||
|                         npc.setFactory(this); |  | ||||||
| 
 |  | ||||||
|                         npcs.add(npc); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 cooldown += NPC_CREATION_COOLDOWN; |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 cooldown--; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private NonPlayerCharacter spawnNPC(Point p) { | ||||||
|  | 
 | ||||||
|  |         NonPlayerCharacter npc; | ||||||
|  | 
 | ||||||
|  |         if (programIndex == 0) { | ||||||
|  |             npc = spawnRandomNpc(p); | ||||||
|  |         } else { | ||||||
|  |             npc = spawnHackedNpc(p); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return npc; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private NonPlayerCharacter spawnRandomNpc(Point p) { | ||||||
|  |         NonPlayerCharacter npc; | ||||||
|  |         npc = new HarvesterNPC(); | ||||||
|  |         npc.setWorld(getWorld()); | ||||||
|  |         npc.setObjectId(new ObjectId()); | ||||||
|  |         npc.setX(p.x); | ||||||
|  |         npc.setY(p.y); | ||||||
|  |         return npc; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private NonPlayerCharacter spawnHackedNpc(Point p) { | ||||||
|  |         NonPlayerCharacter npc; | ||||||
|  |         npc = new HackedNPC(program); | ||||||
|  |         npc.setWorld(getWorld()); | ||||||
|  |         npc.setObjectId(new ObjectId()); | ||||||
|  |         npc.setX(p.x); | ||||||
|  |         npc.setY(p.y); | ||||||
|  | 
 | ||||||
|  |         this.locked = true; | ||||||
|  |         this.programIndex = 0; | ||||||
|  | 
 | ||||||
|  |         return npc; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Document mongoSerialise() { |     public boolean sendMessage(char[] message) { | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 | 
 | ||||||
|         List<ObjectId> tmpNpcArray = new ArrayList<>(npcs.size()); |         if (locked) { | ||||||
|  |             Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); | ||||||
| 
 | 
 | ||||||
|         for (NonPlayerCharacter npc : npcs) { |             if (Arrays.equals(settlement.getPassword(), message)) { | ||||||
|             tmpNpcArray.add(npc.getObjectId()); |                 this.locked = false; | ||||||
|  | 
 | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|  |         } else if (programIndex <= PROGRAM_SIZE) { | ||||||
|  | 
 | ||||||
|  |             if (programIndex == 0) { | ||||||
|  |                 program = new char[PROGRAM_SIZE]; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             System.arraycopy(message, 0, program, programIndex, message.length); | ||||||
|  |             programIndex += message.length; | ||||||
|  | 
 | ||||||
|  |             return true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         dbObject.put("npcs", tmpNpcArray); |         return true; | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     ArrayList<NonPlayerCharacter> getNpcs() { |  | ||||||
|         return npcs; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										339
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/HackedNPC.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/HackedNPC.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,339 @@ | |||||||
|  | package net.simon987.npcplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.*; | ||||||
|  | import net.simon987.server.event.ObjectDeathEvent; | ||||||
|  | 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.logging.LogManager; | ||||||
|  | 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 { | ||||||
|  | 
 | ||||||
|  |     private static final int MEM_SIZE = GameServer.INSTANCE.getConfig().getInt("hacked_npc_mem_size"); | ||||||
|  |     private static final boolean DIE_ON_NO_ENERGY = GameServer.INSTANCE.getConfig().getInt("hacked_npc_die_on_no_energy") != 0; | ||||||
|  | 
 | ||||||
|  |     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); | ||||||
|  |         cpu.getMemory().write(0, program, 0, program.length); | ||||||
|  | 
 | ||||||
|  |         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")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         setTask(new ExecuteCpuTask()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     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")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         setTask(new ExecuteCpuTask()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void update() { | ||||||
|  |         super.update(); | ||||||
|  | 
 | ||||||
|  |         lastAction = currentAction; | ||||||
|  |         currentAction = Action.IDLE; | ||||||
|  | 
 | ||||||
|  |         lastConsoleMessagesBuffer = new ArrayList<>(consoleMessagesBuffer); | ||||||
|  |         consoleMessagesBuffer.clear(); | ||||||
|  | 
 | ||||||
|  |         for (HardwareModule module : hardwareAddresses.values()) { | ||||||
|  |             module.update(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Self-destroy when age limit is reached | ||||||
|  |         if (getAge() >= NonPlayerCharacter.LIFETIME) { | ||||||
|  |             setDead(true); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Don't bother calling checkCompleted() | ||||||
|  |         getTask().tick(this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void setKeyboardBuffer(ArrayList<Integer> kbBuffer) { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no keyboard module" + | ||||||
|  |                 "@HackedNPC::setKeyBoardBuffer()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void setParent(User user) { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no parent" + | ||||||
|  |                 "@HackedNPC::setParent()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public User getParent() { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no parent" + | ||||||
|  |                 "@HackedNPC::getParent()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public ArrayList<Integer> getKeyboardBuffer() { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no keyboard module" + | ||||||
|  |                 "@HackedNPC::getKeyBoardBuffer()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Memory getFloppyData() { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has floppy data." + | ||||||
|  |                 "@HackedNPC::getFloppyData()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void setAction(Action action) { | ||||||
|  |         currentAction = action; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public ArrayList<char[]> getConsoleMessagesBuffer() { | ||||||
|  |         return lastConsoleMessagesBuffer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public int getConsoleMode() { | ||||||
|  |         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no console UI." + | ||||||
|  |                 "@HackedNPC::getConsoleMode()"); | ||||||
|  |         Thread.dumpStack(); | ||||||
|  |         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); | ||||||
|  | 
 | ||||||
|  |         if (energy == 0 && DIE_ON_NO_ENERGY) { | ||||||
|  |             setDead(true); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean spendEnergy(int amount) { | ||||||
|  | 
 | ||||||
|  |         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); | ||||||
|  | 
 | ||||||
|  |         if (battery.getEnergy() - amount < 0) { | ||||||
|  |             if (DIE_ON_NO_ENERGY) { | ||||||
|  |                 setDead(true); | ||||||
|  |             } | ||||||
|  |             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 boolean onDeadCallback() { | ||||||
|  | 
 | ||||||
|  |         getWorld().decUpdatable(); | ||||||
|  | 
 | ||||||
|  |         if (getSettlement() != null && getSettlement().getNpcs() != null) { | ||||||
|  |             getSettlement().getNpcs().remove(this); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         GameServer.INSTANCE.getEventDispatcher().dispatch(new ObjectDeathEvent(this)); | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject debugJsonSerialise() { | ||||||
|  |         return jsonSerialise(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -30,10 +30,9 @@ public class HarvesterNPC extends NonPlayerCharacter { | |||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void update() { |     public void update() { | ||||||
| 
 |  | ||||||
|         super.update(); |         super.update(); | ||||||
| 
 | 
 | ||||||
|         if (getFactory() != null) { |         if (getSettlement() != null) { | ||||||
|             if (getTask().checkCompleted()) { |             if (getTask().checkCompleted()) { | ||||||
| 
 | 
 | ||||||
|                 setTask(new HarvestTask()); |                 setTask(new HarvestTask()); | ||||||
| @ -54,8 +53,8 @@ public class HarvesterNPC extends NonPlayerCharacter { | |||||||
| 
 | 
 | ||||||
|         getWorld().decUpdatable(); |         getWorld().decUpdatable(); | ||||||
| 
 | 
 | ||||||
|         if (getFactory() != null && getFactory().getNpcs() != null) { |         if (getSettlement() != null && getSettlement().getNpcs() != null) { | ||||||
|             getFactory().getNpcs().remove(this); |             getSettlement().getNpcs().remove(this); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         GameServer.INSTANCE.getEventDispatcher().dispatch(new ObjectDeathEvent(this)); |         GameServer.INSTANCE.getEventDispatcher().dispatch(new ObjectDeathEvent(this)); | ||||||
|  | |||||||
| @ -41,16 +41,7 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
|      */ |      */ | ||||||
|     private Action lastAction = Action.IDLE; |     private Action lastAction = Action.IDLE; | ||||||
| 
 | 
 | ||||||
|     /** |     private Settlement settlement; | ||||||
|      * Factory that created this NPC |  | ||||||
|      */ |  | ||||||
|     private Factory factory; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * If set to true, the NPC will be destroyed next tick if it is |  | ||||||
|      * not linked to a Factory |  | ||||||
|      */ |  | ||||||
|     private boolean selfDestroyNextTick = false; |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Age of the npc, in ticks |      * Age of the npc, in ticks | ||||||
| @ -93,13 +84,9 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
| 
 | 
 | ||||||
|         age++; |         age++; | ||||||
| 
 | 
 | ||||||
|         //Destroy NPCs that are not linked with a Factory |         //Destroy NPCs that are not linked with a Settlement | ||||||
|         if (factory == null) { |         if (settlement == null) { | ||||||
|             if (selfDestroyNextTick) { |             setDead(true); | ||||||
|                 setDead(true); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             selfDestroyNextTick = true; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         //Heal the NPC |         //Heal the NPC | ||||||
| @ -147,7 +134,7 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
| 
 | 
 | ||||||
|         if (direction == Direction.NORTH) { |         if (direction == Direction.NORTH) { | ||||||
| 
 | 
 | ||||||
|             if (Util.manhattanDist(factory.getWorld().getX(), factory.getWorld().getY(), |             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), | ||||||
|                     getWorld().getX(), getWorld().getY() - 1) <= MAX_FACTORY_DISTANCE) { |                     getWorld().getX(), getWorld().getY() - 1) <= MAX_FACTORY_DISTANCE) { | ||||||
|                 if (!moveTo(8, 0, 0)) { |                 if (!moveTo(8, 0, 0)) { | ||||||
|                     setDirection(Direction.NORTH); |                     setDirection(Direction.NORTH); | ||||||
| @ -159,7 +146,7 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } else if (direction == Direction.EAST) { |         } else if (direction == Direction.EAST) { | ||||||
|             if (Util.manhattanDist(factory.getWorld().getX(), factory.getWorld().getY(), |             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), | ||||||
|                     getWorld().getX() + 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { |                     getWorld().getX() + 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { | ||||||
|                 if (!moveTo(15, 7, 0)) { |                 if (!moveTo(15, 7, 0)) { | ||||||
|                     setDirection(Direction.EAST); |                     setDirection(Direction.EAST); | ||||||
| @ -170,7 +157,7 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } else if (direction == Direction.SOUTH) { |         } else if (direction == Direction.SOUTH) { | ||||||
|             if (Util.manhattanDist(factory.getWorld().getX(), factory.getWorld().getY(), |             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), | ||||||
|                     getWorld().getX(), getWorld().getY() + 1) <= MAX_FACTORY_DISTANCE) { |                     getWorld().getX(), getWorld().getY() + 1) <= MAX_FACTORY_DISTANCE) { | ||||||
|                 if (!moveTo(8, 15, 0)) { |                 if (!moveTo(8, 15, 0)) { | ||||||
|                     setDirection(Direction.SOUTH); |                     setDirection(Direction.SOUTH); | ||||||
| @ -181,7 +168,7 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } else if (direction == Direction.WEST) { |         } else if (direction == Direction.WEST) { | ||||||
|             if (Util.manhattanDist(factory.getWorld().getX(), factory.getWorld().getY(), |             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), | ||||||
|                     getWorld().getX() - 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { |                     getWorld().getX() - 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { | ||||||
|                 if (!moveTo(0, 7, 0)) { |                 if (!moveTo(0, 7, 0)) { | ||||||
|                     setDirection(Direction.WEST); |                     setDirection(Direction.WEST); | ||||||
| @ -254,16 +241,15 @@ public abstract class NonPlayerCharacter extends GameObject implements Updatable | |||||||
|         return lastAction; |         return lastAction; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Factory getFactory() { |  | ||||||
|         return factory; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setFactory(Factory factory) { |  | ||||||
|         this.factory = factory; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getAge() { |     public int getAge() { | ||||||
|         return age; |         return age; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public Settlement getSettlement() { | ||||||
|  |         return settlement; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setSettlement(Settlement settlement) { | ||||||
|  |         this.settlement = settlement; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										109
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/NpcBattery.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/NpcBattery.java
									
									
									
									
									
										Normal 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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -11,15 +11,18 @@ import net.simon987.server.ServerConfiguration; | |||||||
| import net.simon987.server.game.objects.GameRegistry; | import net.simon987.server.game.objects.GameRegistry; | ||||||
| import net.simon987.server.logging.LogManager; | import net.simon987.server.logging.LogManager; | ||||||
| import net.simon987.server.plugin.ServerPlugin; | import net.simon987.server.plugin.ServerPlugin; | ||||||
|  | import org.bson.Document; | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.io.InputStream; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Scanner; | ||||||
|  | import java.util.concurrent.ConcurrentHashMap; | ||||||
| 
 | 
 | ||||||
| public class NpcPlugin extends ServerPlugin { | public class NpcPlugin extends ServerPlugin { | ||||||
| 
 | 
 | ||||||
|     /** |     public static Map<String, Settlement> settlementMap; | ||||||
|      * Radio tower cache | 
 | ||||||
|      */ |     public static Document DEFAULT_HACKED_NPC; | ||||||
|     private static ArrayList<RadioTower> radioTowers; |  | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void init(GameServer gameServer) { |     public void init(GameServer gameServer) { | ||||||
| @ -27,7 +30,7 @@ public class NpcPlugin extends ServerPlugin { | |||||||
|         ServerConfiguration configuration = gameServer.getConfig(); |         ServerConfiguration configuration = gameServer.getConfig(); | ||||||
|         GameRegistry registry = gameServer.getRegistry(); |         GameRegistry registry = gameServer.getRegistry(); | ||||||
| 
 | 
 | ||||||
|         listeners.add(new WorldCreationListener(configuration.getInt("factory_spawn_rate"))); |         listeners.add(new WorldCreationListener(configuration.getInt("settlement_spawn_rate"))); | ||||||
|         listeners.add(new CpuInitialisationListener()); |         listeners.add(new CpuInitialisationListener()); | ||||||
|         listeners.add(new VaultWorldUpdateListener(configuration)); |         listeners.add(new VaultWorldUpdateListener(configuration)); | ||||||
|         listeners.add(new VaultCompleteListener()); |         listeners.add(new VaultCompleteListener()); | ||||||
| @ -40,19 +43,51 @@ 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); | ||||||
| 
 | 
 | ||||||
|         radioTowers = new ArrayList<>(32); |         settlementMap = new ConcurrentHashMap<>(); | ||||||
|  | 
 | ||||||
|  |         LogManager.LOGGER.fine("(NPC Plugin) Loading default HackedNPC settings from" + | ||||||
|  |                 " defaultHackedCubotHardware.json"); | ||||||
|  |         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"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static ArrayList<RadioTower> getRadioTowers() { |     @Override | ||||||
|         return radioTowers; |     public Document mongoSerialise() { | ||||||
|  |         Document document = super.mongoSerialise(); | ||||||
|  | 
 | ||||||
|  |         Document settlements = new Document(); | ||||||
|  |         for (String world : settlementMap.keySet()) { | ||||||
|  |             settlements.put(world, settlementMap.get(world).mongoSerialise()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         document.put("settlement_map", settlements); | ||||||
|  | 
 | ||||||
|  |         return document; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public void load(Document document) { | ||||||
|  |         super.load(document); | ||||||
|  | 
 | ||||||
|  |         Document settlements = (Document) document.get("settlement_map"); | ||||||
|  | 
 | ||||||
|  |         for (String world : settlements.keySet()) { | ||||||
|  |             settlementMap.put(world, new Settlement((Document) settlements.get(world))); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         LogManager.LOGGER.fine(String.format("(%s) Loaded %d settlements", name, settlementMap.size())); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import net.simon987.server.game.objects.ControllableUnit; | |||||||
| import org.bson.Document; | import org.bson.Document; | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class RadioReceiverHardware extends HardwareModule { | public class RadioReceiverHardware extends HardwareModule { | ||||||
| 
 | 
 | ||||||
| @ -39,12 +40,14 @@ public class RadioReceiverHardware extends HardwareModule { | |||||||
|             //Find the nearest Radio Tower and query it |             //Find the nearest Radio Tower and query it | ||||||
|             cubot.setAction(Action.LISTENING); |             cubot.setAction(Action.LISTENING); | ||||||
| 
 | 
 | ||||||
|             ArrayList<char[]> messages = new ArrayList<>(6); |             List<char[]> messages = new ArrayList<>(6); | ||||||
| 
 | 
 | ||||||
|             ArrayList<RadioTower> towers = new ArrayList<>(NpcPlugin.getRadioTowers()); //Avoid ConcurrentModificationException |             for (String world : NpcPlugin.settlementMap.keySet()) { | ||||||
|             for (RadioTower tower : towers) { |                 RadioTower tower = NpcPlugin.settlementMap.get(world).getRadioTower(); | ||||||
|                 if (Util.manhattanDist(tower.getWorld().getX(), tower.getWorld().getY(), cubot.getWorld().getX(), | 
 | ||||||
|                         cubot.getWorld().getY()) <= RadioTower.MAX_RANGE) { |                 if (tower != null && Util.manhattanDist( | ||||||
|  |                         tower.getWorld().getX(), tower.getWorld().getY(), | ||||||
|  |                         cubot.getWorld().getX(), cubot.getWorld().getY()) <= RadioTower.MAX_RANGE) { | ||||||
|                     //Tower is in range |                     //Tower is in range | ||||||
|                     messages.addAll(tower.getMessages()); |                     messages.addAll(tower.getMessages()); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -24,7 +24,6 @@ public class RadioTower extends Structure implements MessageReceiver, Updatable | |||||||
| 
 | 
 | ||||||
|     public RadioTower(Document document) { |     public RadioTower(Document document) { | ||||||
|         super(document, 1, 1); |         super(document, 1, 1); | ||||||
|         NpcPlugin.getRadioTowers().add(this); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
							
								
								
									
										222
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,222 @@ | |||||||
|  | package net.simon987.npcplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.game.world.TilePlain; | ||||||
|  | import net.simon987.server.game.world.World; | ||||||
|  | import net.simon987.server.game.world.WorldGenerationException; | ||||||
|  | import net.simon987.server.io.MongoSerializable; | ||||||
|  | import org.bson.Document; | ||||||
|  | import org.bson.types.ObjectId; | ||||||
|  | 
 | ||||||
|  | import java.awt.*; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | public class Settlement implements MongoSerializable { | ||||||
|  | 
 | ||||||
|  |     private Factory factory = null; | ||||||
|  |     private RadioTower radioTower = null; | ||||||
|  |     private VaultDoor vaultDoor = null; | ||||||
|  |     private World world; | ||||||
|  |     private DifficultyLevel difficultyLevel; | ||||||
|  | 
 | ||||||
|  |     private List<NonPlayerCharacter> npcs = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |     private char[] password; | ||||||
|  | 
 | ||||||
|  |     public Settlement(Document document) { | ||||||
|  | 
 | ||||||
|  |         world = GameServer.INSTANCE.getGameUniverse().getWorld(document.getString("world"), false); | ||||||
|  |         ObjectId radioTowerId = document.getObjectId("radio_tower"); | ||||||
|  |         if (radioTowerId != null) { | ||||||
|  |             radioTower = (RadioTower) GameServer.INSTANCE.getGameUniverse().getObject(radioTowerId); | ||||||
|  |         } | ||||||
|  |         ObjectId vaultDoorId = document.getObjectId("vault_door"); | ||||||
|  |         if (vaultDoorId != null) { | ||||||
|  |             vaultDoor = (VaultDoor) GameServer.INSTANCE.getGameUniverse().getObject(vaultDoorId); | ||||||
|  |         } | ||||||
|  |         ObjectId factoryId = document.getObjectId("factory"); | ||||||
|  |         factory = (Factory) GameServer.INSTANCE.getGameUniverse().getObject(factoryId); | ||||||
|  | 
 | ||||||
|  |         difficultyLevel = DifficultyLevel.values()[document.getInteger("difficulty_level")]; | ||||||
|  | 
 | ||||||
|  |         Object[] npcArray = ((ArrayList) document.get("npcs")).toArray(); | ||||||
|  |         for (Object id : npcArray) { | ||||||
|  | 
 | ||||||
|  |             NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((ObjectId) id); | ||||||
|  | 
 | ||||||
|  |             if (npc != null) { | ||||||
|  |                 addNpc(npc); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         password = document.getString("password").toCharArray(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Settlement(World world) throws WorldGenerationException { | ||||||
|  | 
 | ||||||
|  |         this.world = world; | ||||||
|  |         this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ? | ||||||
|  |         this.password = "12345678".toCharArray(); | ||||||
|  | 
 | ||||||
|  |         outerLoopFactory: | ||||||
|  |         for (int x = 2; x < 12; x++) { | ||||||
|  |             for (int y = 2; y < 12; y++) { | ||||||
|  | 
 | ||||||
|  |                 if ((!world.isTileBlocked(x, y) && !world.isTileBlocked(x + 1, y) && | ||||||
|  |                         !world.isTileBlocked(x, y + 1) && !world.isTileBlocked(x + 1, y + 1))) { | ||||||
|  | 
 | ||||||
|  |                     Factory factory = new Factory(); | ||||||
|  | 
 | ||||||
|  |                     factory.setWorld(world); | ||||||
|  |                     factory.setObjectId(new ObjectId()); | ||||||
|  |                     factory.setX(x); | ||||||
|  |                     factory.setY(y); | ||||||
|  | 
 | ||||||
|  |                     if (factory.getAdjacentTile() == null) { | ||||||
|  |                         //Factory has no non-blocked adjacent tiles | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     world.addObject(factory); | ||||||
|  |                     world.incUpdatable(); | ||||||
|  |                     this.factory = factory; | ||||||
|  | 
 | ||||||
|  |                     break outerLoopFactory; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (factory == null) { | ||||||
|  |             throw new WorldGenerationException("Could not place Factory"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Also spawn a radio tower in the same World | ||||||
|  |         Point p = world.getRandomTileWithAdjacent(8, TilePlain.ID); | ||||||
|  |         if (p != null) { | ||||||
|  |             while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0) { | ||||||
|  |                 p = world.getRandomPassableTile(); | ||||||
|  | 
 | ||||||
|  |                 if (p == null) { | ||||||
|  |                     //World is full | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             RadioTower radioTower = new RadioTower(); | ||||||
|  | 
 | ||||||
|  |             radioTower.setWorld(world); | ||||||
|  |             radioTower.setObjectId(new ObjectId()); | ||||||
|  |             radioTower.setX(p.x); | ||||||
|  |             radioTower.setY(p.y); | ||||||
|  | 
 | ||||||
|  |             if (radioTower.getAdjacentTile() != null) { | ||||||
|  |                 //Radio Tower has adjacent tiles | ||||||
|  |                 world.addObject(radioTower); | ||||||
|  |                 world.incUpdatable(); //In case the Factory couldn't be spawned. | ||||||
|  | 
 | ||||||
|  |                 this.radioTower = radioTower; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //Also spawn a Vault in the same World | ||||||
|  |         p = world.getRandomPassableTile(); | ||||||
|  |         if (p != null) { | ||||||
|  | 
 | ||||||
|  |             VaultDoor vaultDoor = new VaultDoor(); | ||||||
|  |             vaultDoor.setWorld(world); | ||||||
|  | 
 | ||||||
|  |             int counter = 700; | ||||||
|  |             while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0 | ||||||
|  |                     || vaultDoor.getAdjacentTileCount(true) < 8) { | ||||||
|  |                 p = world.getRandomPassableTile(); | ||||||
|  | 
 | ||||||
|  |                 if (p == null) { | ||||||
|  |                     //World is full | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 vaultDoor.setX(p.x); | ||||||
|  |                 vaultDoor.setY(p.y); | ||||||
|  | 
 | ||||||
|  |                 counter--; | ||||||
|  | 
 | ||||||
|  |                 if (counter <= 0) { | ||||||
|  |                     //Reached maximum amount of retries | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             vaultDoor.setObjectId(new ObjectId()); | ||||||
|  |             world.addObject(vaultDoor); | ||||||
|  |             world.incUpdatable(); //In case the Factory & Radio Tower couldn't be spawned. | ||||||
|  |             vaultDoor.setWorld(world); | ||||||
|  | 
 | ||||||
|  |             vaultDoor.initialize(); | ||||||
|  |             this.vaultDoor = vaultDoor; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void addNpc(NonPlayerCharacter npc) { | ||||||
|  |         npcs.add(npc); | ||||||
|  |         npc.setSettlement(this); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Document mongoSerialise() { | ||||||
|  |         Document document = new Document(); | ||||||
|  | 
 | ||||||
|  |         document.put("world", world.getId()); | ||||||
|  |         if (radioTower != null) { | ||||||
|  |             document.put("radio_tower", radioTower.getObjectId()); | ||||||
|  |         } | ||||||
|  |         if (vaultDoor != null) { | ||||||
|  |             document.put("vault_door", vaultDoor.getObjectId()); | ||||||
|  |         } | ||||||
|  |         document.put("factory", factory.getObjectId()); | ||||||
|  |         document.put("difficulty_level", difficultyLevel.ordinal()); | ||||||
|  |         document.put("password", String.valueOf(password)); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         List<ObjectId> npcArray = new ArrayList<>(npcs.size()); | ||||||
|  |         for (NonPlayerCharacter npc : npcs) { | ||||||
|  |             npcArray.add(npc.getObjectId()); | ||||||
|  |         } | ||||||
|  |         document.put("npcs", npcArray); | ||||||
|  | 
 | ||||||
|  |         return document; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public enum DifficultyLevel { | ||||||
|  |         NORMAL(0); | ||||||
|  | 
 | ||||||
|  |         public int cypherId; | ||||||
|  | 
 | ||||||
|  |         DifficultyLevel(int cypherId) { | ||||||
|  |             this.cypherId = cypherId; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Factory getFactory() { | ||||||
|  |         return factory; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public RadioTower getRadioTower() { | ||||||
|  |         return radioTower; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public VaultDoor getVaultDoor() { | ||||||
|  |         return vaultDoor; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public World getWorld() { | ||||||
|  |         return world; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public List<NonPlayerCharacter> getNpcs() { | ||||||
|  |         return npcs; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public char[] getPassword() { | ||||||
|  |         return password; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -29,7 +29,7 @@ public class VaultDimension { | |||||||
| 
 | 
 | ||||||
|     public VaultDimension(VaultDoor vaultDoor) { |     public VaultDimension(VaultDoor vaultDoor) { | ||||||
| 
 | 
 | ||||||
|         name = "v" + vaultDoor.getObjectId() + "-"; |         name = "v" + vaultDoor.getObjectId(); | ||||||
| 
 | 
 | ||||||
|         /* |         /* | ||||||
|          * Creates a group of vault worlds and pieces them together with openings. |          * Creates a group of vault worlds and pieces them together with openings. | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| package net.simon987.npcplugin; | package net.simon987.npcplugin; | ||||||
| 
 | 
 | ||||||
| import net.simon987.server.GameServer; | import net.simon987.server.GameServer; | ||||||
| import net.simon987.server.crypto.RandomStringGenerator; |  | ||||||
| import net.simon987.server.game.objects.*; | import net.simon987.server.game.objects.*; | ||||||
| import net.simon987.server.game.world.World; | import net.simon987.server.game.world.World; | ||||||
| import net.simon987.server.logging.LogManager; | import net.simon987.server.logging.LogManager; | ||||||
| @ -14,13 +13,6 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
| 
 | 
 | ||||||
|     private static final int MAP_INFO = 0x0B00; |     private static final int MAP_INFO = 0x0B00; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Password to open the vault door |  | ||||||
|      */ |  | ||||||
|     private char[] password; |  | ||||||
| 
 |  | ||||||
|     private RandomStringGenerator randomStringGenerator; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Whether or not the vault door is opened |      * Whether or not the vault door is opened | ||||||
|      */ |      */ | ||||||
| @ -37,16 +29,9 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
|     private int OPEN_TIME = GameServer.INSTANCE.getConfig().getInt("vault_door_open_time"); |     private int OPEN_TIME = GameServer.INSTANCE.getConfig().getInt("vault_door_open_time"); | ||||||
| 
 | 
 | ||||||
|     private int openedTimer = 0; |     private int openedTimer = 0; | ||||||
|     private int cypherId; |  | ||||||
| 
 | 
 | ||||||
|     public VaultDoor(int cypherId) { |     public VaultDoor() { | ||||||
|         super(1, 1); |         super(1, 1); | ||||||
| 
 |  | ||||||
|         this.cypherId = cypherId; |  | ||||||
| 
 |  | ||||||
|         this.randomStringGenerator = new RandomStringGenerator(); |  | ||||||
| 
 |  | ||||||
|         this.password = "12345678".toCharArray(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public VaultDoor(Document document) { |     public VaultDoor(Document document) { | ||||||
| @ -60,8 +45,6 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
|             homeX = document.getInteger("homeX"); |             homeX = document.getInteger("homeX"); | ||||||
|             homeY = document.getInteger("homeY"); |             homeY = document.getInteger("homeY"); | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         password = document.getString("password").toCharArray(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -69,8 +52,7 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
|     public void update() { |     public void update() { | ||||||
|         if (open){ |         if (open){ | ||||||
|             if (openedTimer <= 0) { |             if (openedTimer <= 0) { | ||||||
|                 //Door was open for OPEN_TIME, close it and regen password |                 //Door was open for OPEN_TIME, close it | ||||||
|                 //password = GameServer.INSTANCE.getConfig().getRandomPassword(); |  | ||||||
|                 open = false; |                 open = false; | ||||||
|                 openedTimer = 0; |                 openedTimer = 0; | ||||||
|                 LogManager.LOGGER.fine("Closed Vault door ID: " + getObjectId()); |                 LogManager.LOGGER.fine("Closed Vault door ID: " + getObjectId()); | ||||||
| @ -84,10 +66,12 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
|     @Override |     @Override | ||||||
|     public boolean sendMessage(char[] message) { |     public boolean sendMessage(char[] message) { | ||||||
| 
 | 
 | ||||||
|         System.out.println("message: " + new String(message)); |         Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); | ||||||
|         System.out.println("password: " + new String(password)); |  | ||||||
| 
 | 
 | ||||||
|         if (Arrays.equals(message, password)) { |         System.out.println("message: " + new String(message)); | ||||||
|  |         System.out.println("password: " + new String(settlement.getPassword())); | ||||||
|  | 
 | ||||||
|  |         if (Arrays.equals(message, settlement.getPassword())) { | ||||||
|             if (!open) { |             if (!open) { | ||||||
|                 openVault(); |                 openVault(); | ||||||
|             } else { |             } else { | ||||||
| @ -144,7 +128,6 @@ public class VaultDoor extends Structure implements MessageReceiver, Enterable, | |||||||
| 
 | 
 | ||||||
|         dbObject.put("homeX", getHomeX()); |         dbObject.put("homeX", getHomeX()); | ||||||
|         dbObject.put("homeY", getHomeY()); |         dbObject.put("homeY", getHomeY()); | ||||||
|         dbObject.put("password", new String(password)); |  | ||||||
| 
 | 
 | ||||||
|         return dbObject; |         return dbObject; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1,17 +1,14 @@ | |||||||
| package net.simon987.npcplugin.event; | package net.simon987.npcplugin.event; | ||||||
| 
 | 
 | ||||||
| import net.simon987.npcplugin.Factory; |  | ||||||
| import net.simon987.npcplugin.NpcPlugin; | import net.simon987.npcplugin.NpcPlugin; | ||||||
| import net.simon987.npcplugin.RadioTower; | import net.simon987.npcplugin.Settlement; | ||||||
| import net.simon987.npcplugin.VaultDoor; |  | ||||||
| import net.simon987.server.event.GameEvent; | import net.simon987.server.event.GameEvent; | ||||||
| import net.simon987.server.event.GameEventListener; | import net.simon987.server.event.GameEventListener; | ||||||
| import net.simon987.server.event.WorldGenerationEvent; | import net.simon987.server.event.WorldGenerationEvent; | ||||||
| import net.simon987.server.game.world.TilePlain; |  | ||||||
| import net.simon987.server.game.world.World; | import net.simon987.server.game.world.World; | ||||||
| import org.bson.types.ObjectId; | import net.simon987.server.game.world.WorldGenerationException; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
| 
 | 
 | ||||||
| import java.awt.*; |  | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| 
 | 
 | ||||||
| public class WorldCreationListener implements GameEventListener { | public class WorldCreationListener implements GameEventListener { | ||||||
| @ -37,105 +34,14 @@ public class WorldCreationListener implements GameEventListener { | |||||||
| 
 | 
 | ||||||
|         if (random.nextInt(FACTORY_SPAWN_RATE) == 0) { |         if (random.nextInt(FACTORY_SPAWN_RATE) == 0) { | ||||||
| 
 | 
 | ||||||
|             World world = ((WorldGenerationEvent) event).getWorld(); |             World world = (World) event.getSource(); | ||||||
| 
 | 
 | ||||||
|             outerLoopFactory: |             try { | ||||||
|             for (int x = 2; x < 12; x++) { |                 Settlement settlement = new Settlement(world); | ||||||
|                 for (int y = 2; y < 12; y++) { |                 NpcPlugin.settlementMap.put(world.getId(), settlement); | ||||||
| 
 |             } catch (WorldGenerationException e) { | ||||||
|                     if ((!world.isTileBlocked(x, y) && !world.isTileBlocked(x + 1, y) && |                 LogManager.LOGGER.fine(String.format("Exception during settlement generation: %s.", | ||||||
|                             !world.isTileBlocked(x, y + 1) && !world.isTileBlocked(x + 1, y + 1))) { |                         e.getMessage())); | ||||||
| 
 |  | ||||||
|                         Factory factory = new Factory(); |  | ||||||
| 
 |  | ||||||
|                         factory.setWorld(world); |  | ||||||
|                         factory.setObjectId(new ObjectId()); |  | ||||||
|                         factory.setX(x); |  | ||||||
|                         factory.setY(y); |  | ||||||
| 
 |  | ||||||
|                         if (factory.getAdjacentTile() == null) { |  | ||||||
|                             //Factory has no non-blocked adjacent tiles |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         world.addObject(factory); |  | ||||||
|                         world.incUpdatable(); |  | ||||||
| 
 |  | ||||||
| //                        LogManager.LOGGER.info("Spawned Factory at (" + world.getX() + ", " + world.getY() + |  | ||||||
| //                                ") (" + x + ", " + y + ")"); |  | ||||||
|                         break outerLoopFactory; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Also spawn a radio tower in the same World |  | ||||||
|             Point p = world.getRandomTileWithAdjacent(8, TilePlain.ID); |  | ||||||
|             if (p != null) { |  | ||||||
|                 while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0) { |  | ||||||
|                     p = world.getRandomPassableTile(); |  | ||||||
| 
 |  | ||||||
|                     if (p == null) { |  | ||||||
|                         //World is full |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 RadioTower radioTower = new RadioTower(); |  | ||||||
| 
 |  | ||||||
|                 radioTower.setWorld(world); |  | ||||||
|                 radioTower.setObjectId(new ObjectId()); |  | ||||||
|                 radioTower.setX(p.x); |  | ||||||
|                 radioTower.setY(p.y); |  | ||||||
| 
 |  | ||||||
|                 if (radioTower.getAdjacentTile() != null) { |  | ||||||
|                     //Radio Tower has adjacent tiles |  | ||||||
|                     world.addObject(radioTower); |  | ||||||
|                     world.incUpdatable(); //In case the Factory couldn't be spawned. |  | ||||||
| 
 |  | ||||||
|                     NpcPlugin.getRadioTowers().add(radioTower); |  | ||||||
| 
 |  | ||||||
| //                    LogManager.LOGGER.info("Spawned RadioTower at (" + world.getX() + ", " + world.getY() + |  | ||||||
| //                            ") (" + p.x + ", " + p.y + ")"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Also spawn a Vault in the same World |  | ||||||
|             p = world.getRandomPassableTile(); |  | ||||||
|             if (p != null) { |  | ||||||
| 
 |  | ||||||
|                 VaultDoor vaultDoor = new VaultDoor(0); //todo cypherId ? |  | ||||||
|                 vaultDoor.setWorld(world); |  | ||||||
| 
 |  | ||||||
|                 int counter = 700; |  | ||||||
|                 while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0 |  | ||||||
|                         || vaultDoor.getAdjacentTileCount(true) < 8) { |  | ||||||
|                     p = world.getRandomPassableTile(); |  | ||||||
| 
 |  | ||||||
|                     if (p == null) { |  | ||||||
|                         //World is full |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     vaultDoor.setX(p.x); |  | ||||||
|                     vaultDoor.setY(p.y); |  | ||||||
| 
 |  | ||||||
|                     counter--; |  | ||||||
| 
 |  | ||||||
|                     if (counter <= 0) { |  | ||||||
|                         //Reached maximum amount of retries |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 vaultDoor.setObjectId(new ObjectId()); |  | ||||||
|                 world.addObject(vaultDoor); |  | ||||||
|                 world.incUpdatable(); //In case the Factory & Radio Tower couldn't be spawned. |  | ||||||
|                 vaultDoor.setWorld(world); |  | ||||||
| 
 |  | ||||||
|                 vaultDoor.initialize(); |  | ||||||
| 
 |  | ||||||
| //                LogManager.LOGGER.info("Spawned Vault Door at (" + world.getX() + ", " + world.getY() + |  | ||||||
| //                        ") (" + p.x + ", " + p.y + ")"); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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 | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
| @ -1,3 +1,4 @@ | |||||||
| classpath=net.simon987.npcplugin.NpcPlugin | classpath=net.simon987.npcplugin.NpcPlugin | ||||||
| name=NPC Plugin | name=NPC Plugin | ||||||
| version=1.0 | version=1.1 | ||||||
|  | depend=Cubot Plugin | ||||||
| @ -22,7 +22,9 @@ | |||||||
|     <orderEntry type="module" module-name="Server" /> |     <orderEntry type="module" module-name="Server" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.7.0" level="project" /> |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> | ||||||
|  | |||||||
| @ -73,9 +73,6 @@ public class WorldUtils { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| //        LogManager.LOGGER.info("Generated " + biomassBlobs.size() + " biomassBlobs for World (" + world.getX() + ',' + |  | ||||||
| //                world.getY() + ')'); |  | ||||||
| 
 |  | ||||||
|         return biomassBlobs; |         return biomassBlobs; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -7,7 +7,6 @@ import net.simon987.server.event.GameEventListener; | |||||||
| import net.simon987.server.event.ObjectDeathEvent; | import net.simon987.server.event.ObjectDeathEvent; | ||||||
| import net.simon987.server.game.objects.GameObject; | import net.simon987.server.game.objects.GameObject; | ||||||
| import net.simon987.server.game.world.World; | import net.simon987.server.game.world.World; | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import org.bson.types.ObjectId; | import org.bson.types.ObjectId; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -41,8 +40,6 @@ public class ObjectDeathListener implements GameEventListener { | |||||||
|                         dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); |                         dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); | ||||||
|                 //Add it to the world game objects |                 //Add it to the world game objects | ||||||
|                 dyingHarvesterNPC.getWorld().addObject(newBiomassBlob); |                 dyingHarvesterNPC.getWorld().addObject(newBiomassBlob); | ||||||
|                 LogManager.LOGGER.fine("Spawned biomass at (" + newBiomassBlob.getX() + |  | ||||||
|                         ", " + newBiomassBlob.getY() + ")"); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -21,7 +21,9 @@ | |||||||
|     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> |     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.2" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> |     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.7" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.7.0" level="project" /> |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> | ||||||
|  |     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.0.5.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.0.6.RELEASE" level="project" /> | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> |     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.0.6.RELEASE" level="project" /> | ||||||
|  | |||||||
| @ -106,8 +106,8 @@ | |||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.mongodb</groupId> |             <groupId>org.mongodb</groupId> | ||||||
|             <artifactId>mongo-java-driver</artifactId> |             <artifactId>mongodb-driver-sync</artifactId> | ||||||
|             <version>3.7.0</version> |             <version>3.9.1</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.springframework.security</groupId> |             <groupId>org.springframework.security</groupId> | ||||||
|  | |||||||
| @ -1,9 +1,7 @@ | |||||||
| package net.simon987.server; | package net.simon987.server; | ||||||
| 
 | 
 | ||||||
| import com.mongodb.MongoClient; | import com.mongodb.MongoClientException; | ||||||
| import com.mongodb.client.MongoCollection; | import com.mongodb.client.*; | ||||||
| import com.mongodb.client.MongoCursor; |  | ||||||
| import com.mongodb.client.MongoDatabase; |  | ||||||
| import com.mongodb.client.model.ReplaceOptions; | import com.mongodb.client.model.ReplaceOptions; | ||||||
| import net.simon987.server.crypto.CryptoProvider; | import net.simon987.server.crypto.CryptoProvider; | ||||||
| import net.simon987.server.crypto.SecretKeyGenerator; | import net.simon987.server.crypto.SecretKeyGenerator; | ||||||
| @ -18,6 +16,7 @@ import net.simon987.server.game.objects.GameRegistry; | |||||||
| import net.simon987.server.game.world.*; | import net.simon987.server.game.world.*; | ||||||
| import net.simon987.server.logging.LogManager; | import net.simon987.server.logging.LogManager; | ||||||
| import net.simon987.server.plugin.PluginManager; | import net.simon987.server.plugin.PluginManager; | ||||||
|  | import net.simon987.server.plugin.ServerPlugin; | ||||||
| import net.simon987.server.user.User; | import net.simon987.server.user.User; | ||||||
| import net.simon987.server.user.UserManager; | import net.simon987.server.user.UserManager; | ||||||
| import net.simon987.server.user.UserStatsHelper; | import net.simon987.server.user.UserStatsHelper; | ||||||
| @ -57,7 +56,9 @@ public class GameServer implements Runnable { | |||||||
|     public GameServer() { |     public GameServer() { | ||||||
|         this.config = new ServerConfiguration("config.properties"); |         this.config = new ServerConfiguration("config.properties"); | ||||||
| 
 | 
 | ||||||
|         mongo = new MongoClient(config.getString("mongo_address"), config.getInt("mongo_port")); |         String connString = String.format("mongodb://%s:%d", | ||||||
|  |                 config.getString("mongo_address"), config.getInt("mongo_port")); | ||||||
|  |         mongo = MongoClients.create(connString); | ||||||
|         MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname")); |         MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname")); | ||||||
| 
 | 
 | ||||||
|         MongoCollection<Document> userCollection = db.getCollection("user"); |         MongoCollection<Document> userCollection = db.getCollection("user"); | ||||||
| @ -221,11 +222,18 @@ public class GameServer implements Runnable { | |||||||
|             universe.addUser(user); |             universe.addUser(user); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         //Load misc server info |         //Load server & plugin data | ||||||
|         cursor = server.find().iterator(); |         cursor = server.find().iterator(); | ||||||
|         if (cursor.hasNext()) { |         if (cursor.hasNext()) { | ||||||
|             Document serverObj = cursor.next(); |             Document serverObj = cursor.next(); | ||||||
|             gameUniverse.setTime((long) serverObj.get("time")); |             gameUniverse.setTime((long) serverObj.get("time")); | ||||||
|  | 
 | ||||||
|  |             Document plugins = (Document) serverObj.get("plugins"); | ||||||
|  | 
 | ||||||
|  |             for (String pluginName : plugins.keySet()) { | ||||||
|  |                 ServerPlugin plugin = pluginManager.getPluginByName(pluginName); | ||||||
|  |                 plugin.load((Document) plugins.get(pluginName)); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         LogManager.LOGGER.info("Done loading! W:" + GameServer.INSTANCE.getGameUniverse().getWorldCount() + |         LogManager.LOGGER.info("Done loading! W:" + GameServer.INSTANCE.getGameUniverse().getWorldCount() + | ||||||
| @ -235,7 +243,16 @@ public class GameServer implements Runnable { | |||||||
|     public void save() { |     public void save() { | ||||||
| 
 | 
 | ||||||
|         LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorldCount() + " | U:" + gameUniverse.getUserCount()); |         LogManager.LOGGER.info("Saving to MongoDB | W:" + gameUniverse.getWorldCount() + " | U:" + gameUniverse.getUserCount()); | ||||||
|  | 
 | ||||||
|  |         ClientSession session = null; | ||||||
|         try { |         try { | ||||||
|  |             try { | ||||||
|  |                 session = mongo.startSession(); | ||||||
|  |                 session.startTransaction(); | ||||||
|  |             } catch (MongoClientException e) { | ||||||
|  |                 LogManager.LOGGER.fine("Could not create mongoDB session, will not start a transaction."); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname")); |             MongoDatabase db = mongo.getDatabase(config.getString("mongo_dbname")); | ||||||
|             ReplaceOptions updateOptions = new ReplaceOptions(); |             ReplaceOptions updateOptions = new ReplaceOptions(); | ||||||
|             updateOptions.upsert(true); |             updateOptions.upsert(true); | ||||||
| @ -267,13 +284,27 @@ public class GameServer implements Runnable { | |||||||
| 
 | 
 | ||||||
|             Document serverObj = new Document(); |             Document serverObj = new Document(); | ||||||
|             serverObj.put("time", gameUniverse.getTime()); |             serverObj.put("time", gameUniverse.getTime()); | ||||||
|  | 
 | ||||||
|  |             Document plugins = new Document(); | ||||||
|  |             for (ServerPlugin plugin : pluginManager.getPlugins()) { | ||||||
|  |                 plugins.put(plugin.getName(), plugin.mongoSerialise()); | ||||||
|  |             } | ||||||
|  |             serverObj.put("plugins", plugins); | ||||||
|  | 
 | ||||||
|             //A constant id ensures only one entry is kept and updated, instead of a new entry created every save. |             //A constant id ensures only one entry is kept and updated, instead of a new entry created every save. | ||||||
|             server.replaceOne(new Document("_id", "serverinfo"), serverObj, updateOptions); |             server.replaceOne(new Document("_id", "serverinfo"), serverObj, updateOptions); | ||||||
|  |             if (session != null) { | ||||||
|  |                 session.commitTransaction(); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             LogManager.LOGGER.info("" + insertedWorlds + " worlds saved, " + unloaded_worlds + " unloaded"); |             LogManager.LOGGER.info("" + insertedWorlds + " worlds saved, " + unloaded_worlds + " unloaded"); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             LogManager.LOGGER.severe("Problem happened during save function"); |             LogManager.LOGGER.severe("Problem happened during save function"); | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|  | 
 | ||||||
|  |             if (session != null) { | ||||||
|  |                 session.commitTransaction(); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import spark.Spark; | |||||||
| public class Main { | public class Main { | ||||||
|     public static void main(String[] args) { |     public static void main(String[] args) { | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         ServerConfiguration config = new ServerConfiguration("config.properties"); |         ServerConfiguration config = new ServerConfiguration("config.properties"); | ||||||
|         LogManager.initialize(config); |         LogManager.initialize(config); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| package net.simon987.server.game; | package net.simon987.server.game; | ||||||
| 
 | 
 | ||||||
| import com.mongodb.MongoClient; | import com.mongodb.client.MongoClient; | ||||||
| import com.mongodb.client.MongoCollection; | import com.mongodb.client.MongoCollection; | ||||||
| import com.mongodb.client.MongoCursor; | import com.mongodb.client.MongoCursor; | ||||||
| import com.mongodb.client.MongoDatabase; | import com.mongodb.client.MongoDatabase; | ||||||
| @ -20,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; | |||||||
| 
 | 
 | ||||||
| public class GameUniverse { | public class GameUniverse { | ||||||
| 
 | 
 | ||||||
|     //private ArrayList<World> worlds; |  | ||||||
|     private ConcurrentHashMap<String, World> worlds; |     private ConcurrentHashMap<String, World> worlds; | ||||||
|     //username:user |     //username:user | ||||||
|     private ConcurrentHashMap<String, User> users; |     private ConcurrentHashMap<String, User> users; | ||||||
| @ -115,6 +114,14 @@ public class GameUniverse { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public World getWorld(String id, boolean createNew) { | ||||||
|  | 
 | ||||||
|  |         String[] tokens = id.split("-"); | ||||||
|  | 
 | ||||||
|  |         return getWorld(Integer.decode(tokens[1]), Integer.decode(tokens[2]), | ||||||
|  |                 createNew, tokens[0]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public World getLoadedWorld(int x, int y, String dimension) { |     public World getLoadedWorld(int x, int y, String dimension) { | ||||||
|         // Wrapping coordinates around cyclically |         // Wrapping coordinates around cyclically | ||||||
|         x %= maxWidth; |         x %= maxWidth; | ||||||
| @ -225,6 +232,7 @@ public class GameUniverse { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         LogManager.LOGGER.severe("Couldn't find object: " + id); |         LogManager.LOGGER.severe("Couldn't find object: " + id); | ||||||
|  |         Thread.dumpStack(); | ||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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, HardwareHost { | ||||||
| 
 | 
 | ||||||
|     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); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -159,30 +159,30 @@ public abstract class GameObject implements JSONSerializable, MongoSerializable | |||||||
| 
 | 
 | ||||||
|         int count = 0; |         int count = 0; | ||||||
| 
 | 
 | ||||||
|         if (!getWorld().isTileBlocked(getX() + 1, getY())) { |         if (getWorld().getTileMap().isInBounds(x + 1, y) && !getWorld().isTileBlocked(x + 1, y)) { | ||||||
|             count++; |             count++; | ||||||
|         } |         } | ||||||
|         if (!getWorld().isTileBlocked(getX(), getY() + 1)) { |         if (getWorld().getTileMap().isInBounds(x, y + 1) && !getWorld().isTileBlocked(x, y + 1)) { | ||||||
|             count++; |             count++; | ||||||
|         } |         } | ||||||
|         if (!getWorld().isTileBlocked(getX() - 1, getY())) { |         if (getWorld().getTileMap().isInBounds(x - 1, y) && !getWorld().isTileBlocked(x - 1, y)) { | ||||||
|             count++; |             count++; | ||||||
|         } |         } | ||||||
|         if (!getWorld().isTileBlocked(getX(), getY() - 1)) { |         if (getWorld().getTileMap().isInBounds(x, y - 1) && !getWorld().isTileBlocked(x, y - 1)) { | ||||||
|             count++; |             count++; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (diagonals) { |         if (diagonals) { | ||||||
|             if (!getWorld().isTileBlocked(getX() + 1, getY() + 1)) { |             if (getWorld().getTileMap().isInBounds(x + 1, y + 1) && !getWorld().isTileBlocked(x + 1, y + 1)) { | ||||||
|                 count++; |                 count++; | ||||||
|             } |             } | ||||||
|             if (!getWorld().isTileBlocked(getX() - 1, getY() + 1)) { |             if (getWorld().getTileMap().isInBounds(x - 1, y + 1) && !getWorld().isTileBlocked(x - 1, y + 1)) { | ||||||
|                 count++; |                 count++; | ||||||
|             } |             } | ||||||
|             if (!getWorld().isTileBlocked(getX() + 1, getY() - 1)) { |             if (getWorld().getTileMap().isInBounds(x + 1, y - 1) && !getWorld().isTileBlocked(x + 1, y - 1)) { | ||||||
|                 count++; |                 count++; | ||||||
|             } |             } | ||||||
|             if (!getWorld().isTileBlocked(getX() - 1, getY() - 1)) { |             if (getWorld().getTileMap().isInBounds(x - 1, y - 1) && !getWorld().isTileBlocked(x - 1, y - 1)) { | ||||||
|                 count++; |                 count++; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import net.simon987.server.GameServer; | |||||||
| import net.simon987.server.game.objects.GameRegistry; | import net.simon987.server.game.objects.GameRegistry; | ||||||
| import net.simon987.server.io.JSONSerializable; | import net.simon987.server.io.JSONSerializable; | ||||||
| import net.simon987.server.io.MongoSerializable; | import net.simon987.server.io.MongoSerializable; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
| import org.bson.Document; | import org.bson.Document; | ||||||
| import org.json.simple.JSONArray; | import org.json.simple.JSONArray; | ||||||
| import org.json.simple.JSONObject; | import org.json.simple.JSONObject; | ||||||
| @ -87,7 +88,8 @@ public class TileMap implements JSONSerializable, MongoSerializable { | |||||||
|      */ |      */ | ||||||
|     public int getTileIdAt(int x, int y) { |     public int getTileIdAt(int x, int y) { | ||||||
|         try { |         try { | ||||||
|             return tiles[x][y].getId(); |             Tile tile = tiles[x][y]; | ||||||
|  |             return tile == null ? -1 : tile.getId(); | ||||||
|         } catch (ArrayIndexOutOfBoundsException e) { |         } catch (ArrayIndexOutOfBoundsException e) { | ||||||
|             return -1; |             return -1; | ||||||
|         } |         } | ||||||
| @ -101,13 +103,18 @@ public class TileMap implements JSONSerializable, MongoSerializable { | |||||||
|      * @return the tile id at the specified position, null if out of bounds |      * @return the tile id at the specified position, null if out of bounds | ||||||
|      */ |      */ | ||||||
|     public Tile getTileAt(int x, int y) { |     public Tile getTileAt(int x, int y) { | ||||||
|         try { |         if (isInBounds(x, y)) { | ||||||
|             return tiles[x][y]; |             return tiles[x][y]; | ||||||
|         } catch (ArrayIndexOutOfBoundsException e) { |         } else { | ||||||
|  |             LogManager.LOGGER.warning(String.format("ArrayIndexOutOfBoundsException in TileMap::getTileAt(%d, %d)", x, y)); | ||||||
|  |             Thread.dumpStack(); | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public boolean isInBounds(int x, int y) { | ||||||
|  |         return x >= 0 && x < width && y >= 0 && y < width; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     public int getWidth() { |     public int getWidth() { | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ public class World implements MongoSerializable { | |||||||
|      * @return long |      * @return long | ||||||
|      */ |      */ | ||||||
|     public static String idFromCoordinates(int x, int y, String dimension) { |     public static String idFromCoordinates(int x, int y, String dimension) { | ||||||
|         return dimension + "0x" + Integer.toHexString(x) + "-" + "0x" + Integer.toHexString(y); |         return dimension + "-0x" + Integer.toHexString(x) + "-" + "0x" + Integer.toHexString(y); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -425,28 +425,28 @@ public class World implements MongoSerializable { | |||||||
|             if (rTile != null) { |             if (rTile != null) { | ||||||
|                 int adjacentTiles = 0; |                 int adjacentTiles = 0; | ||||||
| 
 | 
 | ||||||
|                 if (!isTileBlocked(rTile.x, rTile.y - 1)) { |                 if (tileMap.isInBounds(rTile.x, rTile.y - 1) && !isTileBlocked(rTile.x, rTile.y - 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x + 1, rTile.y)) { |                 if (tileMap.isInBounds(rTile.x + 1, rTile.y) && !isTileBlocked(rTile.x + 1, rTile.y)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x, rTile.y + 1)) { |                 if (tileMap.isInBounds(rTile.x, rTile.y + 1) && !isTileBlocked(rTile.x, rTile.y + 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x - 1, rTile.y)) { |                 if (tileMap.isInBounds(rTile.x - 1, rTile.y) && !isTileBlocked(rTile.x - 1, rTile.y)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x + 1, rTile.y + 1)) { |                 if (tileMap.isInBounds(rTile.x + 1, rTile.y + 1) && !isTileBlocked(rTile.x + 1, rTile.y + 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x - 1, rTile.y + 1)) { |                 if (tileMap.isInBounds(rTile.x - 1, rTile.y + 1) && !isTileBlocked(rTile.x - 1, rTile.y + 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x + 1, rTile.y - 1)) { |                 if (tileMap.isInBounds(rTile.x + 1, rTile.y - 1) && !isTileBlocked(rTile.x + 1, rTile.y - 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
|                 if (!isTileBlocked(rTile.x - 1, rTile.y - 1)) { |                 if (tileMap.isInBounds(rTile.x - 1, rTile.y - 1) && !isTileBlocked(rTile.x - 1, rTile.y - 1)) { | ||||||
|                     adjacentTiles++; |                     adjacentTiles++; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,7 @@ | |||||||
|  | package net.simon987.server.game.world; | ||||||
|  | 
 | ||||||
|  | public class WorldGenerationException extends Exception { | ||||||
|  |     public WorldGenerationException(String message) { | ||||||
|  |         super(message); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -38,6 +38,8 @@ public class WorldGenerator { | |||||||
|     private int minCopperCount; |     private int minCopperCount; | ||||||
|     private int maxCopperCount; |     private int maxCopperCount; | ||||||
| 
 | 
 | ||||||
|  |     private String dimension; | ||||||
|  | 
 | ||||||
|     private static final int DEFAULT_WORLD_SIZE = 16; |     private static final int DEFAULT_WORLD_SIZE = 16; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -48,6 +50,8 @@ public class WorldGenerator { | |||||||
| 
 | 
 | ||||||
|     public WorldGenerator(ServerConfiguration config) { |     public WorldGenerator(ServerConfiguration config) { | ||||||
| 
 | 
 | ||||||
|  |         dimension = config.getString("new_user_dimension"); | ||||||
|  | 
 | ||||||
|         centerPointCountMin = config.getInt("wg_centerPointCountMin"); |         centerPointCountMin = config.getInt("wg_centerPointCountMin"); | ||||||
|         centerPointCountMax = config.getInt("wg_centerPointCountMax"); |         centerPointCountMax = config.getInt("wg_centerPointCountMax"); | ||||||
|         wallPlainRatio = config.getInt("wg_wallPlainRatio"); |         wallPlainRatio = config.getInt("wg_wallPlainRatio"); | ||||||
| @ -88,9 +92,9 @@ public class WorldGenerator { | |||||||
|     /** |     /** | ||||||
|      * Generates an empty World |      * Generates an empty World | ||||||
|      */ |      */ | ||||||
|     private static World generateEmptyWorld(int locX, int locY) { |     private static World generateEmptyWorld(int locX, int locY, String dimension) { | ||||||
| 
 | 
 | ||||||
|         return new World(locX, locY, new TileMap(DEFAULT_WORLD_SIZE, DEFAULT_WORLD_SIZE), "w-"); |         return new World(locX, locY, new TileMap(DEFAULT_WORLD_SIZE, DEFAULT_WORLD_SIZE), dimension); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -99,7 +103,7 @@ public class WorldGenerator { | |||||||
|     public World generateWorld(int locX, int locY) throws CancelledException { |     public World generateWorld(int locX, int locY) throws CancelledException { | ||||||
|         Random random = new Random(); |         Random random = new Random(); | ||||||
| 
 | 
 | ||||||
|         World world = generateEmptyWorld(locX, locY); |         World world = generateEmptyWorld(locX, locY, dimension); | ||||||
| 
 | 
 | ||||||
|         centerPointsMap = new HashMap<>(16); |         centerPointsMap = new HashMap<>(16); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -152,6 +152,10 @@ public class PluginManager { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public ServerPlugin getPluginByName(String name) { | ||||||
|  |         return PluginManager.getPluginByName(name, loadedPlugins); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private boolean isLoaded(String name) { |     private boolean isLoaded(String name) { | ||||||
|         return getPluginByName(name, loadedPlugins) != null; |         return getPluginByName(name, loadedPlugins) != null; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -2,11 +2,14 @@ package net.simon987.server.plugin; | |||||||
| 
 | 
 | ||||||
| import net.simon987.server.GameServer; | import net.simon987.server.GameServer; | ||||||
| import net.simon987.server.event.GameEventListener; | import net.simon987.server.event.GameEventListener; | ||||||
|  | import net.simon987.server.io.MongoSerializable; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
|  | import org.bson.Document; | ||||||
| 
 | 
 | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public abstract class ServerPlugin { | public abstract class ServerPlugin implements MongoSerializable { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Name of the plugin |      * Name of the plugin | ||||||
| @ -49,4 +52,22 @@ public abstract class ServerPlugin { | |||||||
|     public List<GameEventListener> getListeners() { |     public List<GameEventListener> getListeners() { | ||||||
|         return listeners; |         return listeners; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public Document mongoSerialise() { | ||||||
|  |         Document document = new Document(); | ||||||
|  | 
 | ||||||
|  |         document.put("version", version); | ||||||
|  | 
 | ||||||
|  |         return document; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void load(Document document) { | ||||||
|  | 
 | ||||||
|  |         LogManager.LOGGER.fine(String.format("(%s) Loading from database", name)); | ||||||
|  |         if (!version.equals(document.getString("version"))) { | ||||||
|  |             LogManager.LOGGER.warning(String.format("(%s) Version mismatch with database!" + | ||||||
|  |                     " This could cause problems. %s!=%s", name, version, document.getString("version"))); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -138,9 +138,9 @@ public class SocketServer { | |||||||
|                 } else { |                 } else { | ||||||
|                     ControllableUnit unit = user.getUser().getControlledUnit(); |                     ControllableUnit unit = user.getUser().getControlledUnit(); | ||||||
| 
 | 
 | ||||||
|                     json.put("c", charArraysToJSON(unit.getConsoleMessagesBuffer())); |                     json.put("console_message_buffer", charArraysToJSON(unit.getConsoleMessagesBuffer())); | ||||||
|                     json.put("keys", intListToJSON(unit.getKeyboardBuffer())); |                     json.put("keys", intListToJSON(unit.getKeyboardBuffer())); | ||||||
|                     json.put("cm", unit.getConsoleMode()); |                     json.put("console_mode", unit.getConsoleMode()); | ||||||
| 
 | 
 | ||||||
|                     sendJSONObject(user, json); |                     sendJSONObject(user, json); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ wg_maxCopperCount=2 | |||||||
| wg_fluidCenterPointMin=0 | wg_fluidCenterPointMin=0 | ||||||
| wg_fluidCenterPointMax=2 | wg_fluidCenterPointMax=2 | ||||||
| #CPU | #CPU | ||||||
| tick_length=1000 | tick_length=50 | ||||||
| org_offset=512 | org_offset=512 | ||||||
| stack_bottom=65536 | stack_bottom=65536 | ||||||
| memory_size=65536 | memory_size=65536 | ||||||
| @ -48,7 +48,7 @@ user_timeout=100 | |||||||
| #User creation | #User creation | ||||||
| new_user_worldX=32767 | new_user_worldX=32767 | ||||||
| new_user_worldY=32767 | new_user_worldY=32767 | ||||||
| new_user_dimension=w- | new_user_dimension=w | ||||||
| # Default user code | # Default user code | ||||||
| new_user_code=; Welcome to Much Assembly required!\n\ | new_user_code=; Welcome to Much Assembly required!\n\ | ||||||
|   ; You will find useful information on the game here: https://github.com/simon987/Much-Assembly-Required/wiki\n\ |   ; You will find useful information on the game here: https://github.com/simon987/Much-Assembly-Required/wiki\n\ | ||||||
| @ -66,11 +66,15 @@ shield_energy_cost=50 | |||||||
| npc_lifetime=1024 | npc_lifetime=1024 | ||||||
| npc_max_factory_distance=3 | npc_max_factory_distance=3 | ||||||
| factory_max_npc_count=16 | factory_max_npc_count=16 | ||||||
| factory_spawn_rate=35 | factory_program_size=1024 | ||||||
|  | settlement_spawn_rate=35 | ||||||
| harvester_hp_max=100 | 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 | ||||||
|  | npc_exec_time=5 | ||||||
|  | hacked_npc_die_on_no_energy=1 | ||||||
| #Vaults | #Vaults | ||||||
| vault_door_open_time=4 | vault_door_open_time=4 | ||||||
| min_electric_box_count=1 | min_electric_box_count=1 | ||||||
|  | |||||||
| @ -115,7 +115,6 @@ | |||||||
| .bottom-panel { | .bottom-panel { | ||||||
|     min-height: 18px; |     min-height: 18px; | ||||||
|     max-height: 100%; |     max-height: 100%; | ||||||
|     height: 235px; |  | ||||||
|     width: 100%; |     width: 100%; | ||||||
|     position: fixed; |     position: fixed; | ||||||
|     bottom: 0; |     bottom: 0; | ||||||
|  | |||||||
							
								
								
									
										54
									
								
								Server/src/main/resources/static/js/mar.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										54
									
								
								Server/src/main/resources/static/js/mar.js
									
									
									
									
										vendored
									
									
								
							| @ -276,6 +276,9 @@ var config = { | |||||||
|         lowEnergy: 100, |         lowEnergy: 100, | ||||||
|         otherCubotAlpha: 0.6, |         otherCubotAlpha: 0.6, | ||||||
|     }, |     }, | ||||||
|  |     hackedNpc: { | ||||||
|  |         tint: 0xE040FB, | ||||||
|  |     }, | ||||||
|     biomass: { |     biomass: { | ||||||
|         tint: 0x63B85F, |         tint: 0x63B85F, | ||||||
|         tintHover: 0x00FF00, |         tintHover: 0x00FF00, | ||||||
| @ -537,9 +540,9 @@ var TickListener = (function () { | |||||||
|             mar.client.keyboardBuffer.keys = message.keys; |             mar.client.keyboardBuffer.keys = message.keys; | ||||||
|         } |         } | ||||||
|         if (message.c != undefined) { |         if (message.c != undefined) { | ||||||
|             mar.client.consoleScreen.handleConsoleBufferUpdate(message.c, message.cm); |             mar.client.consoleScreen.handleConsoleBufferUpdate(message.console_message_buffer, message.console_mode); | ||||||
|             if (DEBUG) { |             if (DEBUG) { | ||||||
|                 console.log("[MAR] Received " + message.c.length + " console message(s)"); |                 console.log("[MAR] Received " + message.console_message_buffer.length + " console message(s)"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| @ -830,6 +833,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 +877,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 +923,8 @@ 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.baseTint = config.cubot.tint; | ||||||
|         _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 +956,9 @@ 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; | ||||||
| @ -956,11 +966,11 @@ var Cubot = (function (_super) { | |||||||
|     Cubot.prototype.onTileHover = function () { |     Cubot.prototype.onTileHover = function () { | ||||||
|         mar.game.add.tween(this).to({ isoZ: 45 }, 200, Phaser.Easing.Quadratic.InOut, true); |         mar.game.add.tween(this).to({ isoZ: 45 }, 200, Phaser.Easing.Quadratic.InOut, true); | ||||||
|         mar.game.add.tween(this.scale).to({ x: 1.2, y: 1.2 }, 200, Phaser.Easing.Linear.None, true); |         mar.game.add.tween(this.scale).to({ x: 1.2, y: 1.2 }, 200, Phaser.Easing.Linear.None, true); | ||||||
|         this.cubotSprite.tint = config.cubot.hoverTint; |  | ||||||
|         if (this.text !== undefined) { |         if (this.text !== undefined) { | ||||||
|             this.text.visible = true; |             this.text.visible = true; | ||||||
|         } |         } | ||||||
|         this.hovered = true; |         this.hovered = true; | ||||||
|  |         this.cubotSprite.tint = this.getTint(); | ||||||
|     }; |     }; | ||||||
|     Cubot.prototype.onTileExit = function () { |     Cubot.prototype.onTileExit = function () { | ||||||
|         mar.game.add.tween(this).to({ isoZ: 15 }, 400, Phaser.Easing.Bounce.Out, true); |         mar.game.add.tween(this).to({ isoZ: 15 }, 400, Phaser.Easing.Bounce.Out, true); | ||||||
| @ -1000,7 +1010,7 @@ var Cubot = (function (_super) { | |||||||
|                 return config.cubot.lowEnergyTint; |                 return config.cubot.lowEnergyTint; | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 return config.cubot.tint; |                 return this.baseTint; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
| @ -1012,7 +1022,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]); | ||||||
| @ -1188,9 +1198,6 @@ var HarvesterNPC = (function (_super) { | |||||||
|         _this.text.visible = false; |         _this.text.visible = false; | ||||||
|         return _this; |         return _this; | ||||||
|     } |     } | ||||||
|     HarvesterNPC.prototype.getTint = function () { |  | ||||||
|         return config.cubot.tint; |  | ||||||
|     }; |  | ||||||
|     HarvesterNPC.prototype.updateDirection = function () { |     HarvesterNPC.prototype.updateDirection = function () { | ||||||
|         switch (this.direction) { |         switch (this.direction) { | ||||||
|             case Direction.NORTH: |             case Direction.NORTH: | ||||||
| @ -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 1000; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|     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,24 @@ 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.baseTint = config.hackedNpc.tint; | ||||||
|  |         _this.cubotSprite.tint = _this.baseTint; | ||||||
|  |         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); | ||||||
|  |     }; | ||||||
|  |     return HackedNPC; | ||||||
|  | }(HarvesterNPC)); | ||||||
| var BiomassBlob = (function (_super) { | var BiomassBlob = (function (_super) { | ||||||
|     __extends(BiomassBlob, _super); |     __extends(BiomassBlob, _super); | ||||||
|     function BiomassBlob(json) { |     function BiomassBlob(json) { | ||||||
| @ -1336,7 +1368,7 @@ var VaultDoor = (function (_super) { | |||||||
|         _this.anchor.set(0.55, 0.55); |         _this.anchor.set(0.55, 0.55); | ||||||
|         _this.inputEnabled = true; |         _this.inputEnabled = true; | ||||||
|         _this.events.onInputDown.add(function (self) { |         _this.events.onInputDown.add(function (self) { | ||||||
|             Debug.goToHex("7FFF", "7FFF", "v" + self.id + "-"); |             Debug.goToHex("7FFF", "7FFF", "v" + self.id); | ||||||
|             document.body.style.cursor = 'default'; |             document.body.style.cursor = 'default'; | ||||||
|             document.body.setAttribute("title", ""); |             document.body.setAttribute("title", ""); | ||||||
|         }, _this); |         }, _this); | ||||||
| @ -1417,7 +1449,7 @@ var ElectricBox = (function (_super) { | |||||||
| var Portal = (function (_super) { | var Portal = (function (_super) { | ||||||
|     __extends(Portal, _super); |     __extends(Portal, _super); | ||||||
|     function Portal(json) { |     function Portal(json) { | ||||||
|         var _this = _super.call(this, Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/Portal") || this; |         var _this = _super.call(this, Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/portal") || this; | ||||||
|         _this.anchor.set(0.5, 0.3); |         _this.anchor.set(0.5, 0.3); | ||||||
|         _this.tint = config.portal.tint; |         _this.tint = config.portal.tint; | ||||||
|         _this.setText("Portal"); |         _this.setText("Portal"); | ||||||
|  | |||||||
| @ -118,11 +118,7 @@ | |||||||
| 
 | 
 | ||||||
|     #parse("footer.vm") |     #parse("footer.vm") | ||||||
| 
 | 
 | ||||||
| ##Console | <div class="bottom-panel" style="height: 0"> | ||||||
| <style> |  | ||||||
| </style> |  | ||||||
| 
 |  | ||||||
| <div class="bottom-panel"> |  | ||||||
|     <div class="splitter-horizontal"></div> |     <div class="splitter-horizontal"></div> | ||||||
|     <div class="console-wrapper"> |     <div class="console-wrapper"> | ||||||
|         <div class="console-side-bar"> |         <div class="console-side-bar"> | ||||||
| @ -151,7 +147,6 @@ | |||||||
|                     <button class="dropdown-item" onclick="mar.client.consoleScreen.setMode(4)">64 chars</button> |                     <button class="dropdown-item" onclick="mar.client.consoleScreen.setMode(4)">64 chars</button> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|             </p> |  | ||||||
|             <p> |             <p> | ||||||
|                 <button id="resetButton" class="btn btn-danger btn-shadow" style="margin-left: 0" |                 <button id="resetButton" class="btn btn-danger btn-shadow" style="margin-left: 0" | ||||||
|                         data-container="body" data-toggle="popover" data-trigger="hover" |                         data-container="body" data-toggle="popover" data-trigger="hover" | ||||||
| @ -163,9 +158,7 @@ | |||||||
|             <div class="piece scanlines noclick"></div> |             <div class="piece scanlines noclick"></div> | ||||||
|             <div class="piece glow noclick"></div> |             <div class="piece glow noclick"></div> | ||||||
|         </div> |         </div> | ||||||
| 
 |  | ||||||
|     </div> |     </div> | ||||||
| 
 |  | ||||||
| </div> | </div> | ||||||
| 
 | 
 | ||||||
| <script> | <script> | ||||||
|  | |||||||
| @ -85,10 +85,12 @@ class TickListener implements MessageListener { | |||||||
| 
 | 
 | ||||||
|         //Update console screen
 |         //Update console screen
 | ||||||
|         if (message.c != undefined) { |         if (message.c != undefined) { | ||||||
|             mar.client.consoleScreen.handleConsoleBufferUpdate(message.c, message.cm as ConsoleMode); |             mar.client.consoleScreen.handleConsoleBufferUpdate( | ||||||
|  |                 message.console_message_buffer, | ||||||
|  |                 message.console_mode as ConsoleMode); | ||||||
| 
 | 
 | ||||||
|             if (DEBUG) { |             if (DEBUG) { | ||||||
|                 console.log("[MAR] Received " + message.c.length + " console message(s)") |                 console.log("[MAR] Received " + message.console_message_buffer.length + " console message(s)") | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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; | ||||||
| @ -136,6 +138,7 @@ class Cubot extends GameObject { | |||||||
|     protected cubotSprite: Phaser.Sprite; |     protected cubotSprite: Phaser.Sprite; | ||||||
|     private shieldBackSprite: Phaser.Sprite; |     private shieldBackSprite: Phaser.Sprite; | ||||||
|     private shieldFrontSprite: Phaser.Sprite; |     private shieldFrontSprite: Phaser.Sprite; | ||||||
|  |     protected baseTint: number; | ||||||
| 
 | 
 | ||||||
|     constructor(json) { |     constructor(json) { | ||||||
|         //workaround for topological sort, needs sprite dimensions
 |         //workaround for topological sort, needs sprite dimensions
 | ||||||
| @ -155,7 +158,8 @@ 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.baseTint = config.cubot.tint; | ||||||
| 
 | 
 | ||||||
|         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 +201,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; | ||||||
| @ -207,13 +215,12 @@ class Cubot extends GameObject { | |||||||
|         mar.game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); |         mar.game.add.tween(this).to({isoZ: 45}, 200, Phaser.Easing.Quadratic.InOut, true); | ||||||
|         mar.game.add.tween(this.scale).to({x: 1.2, y: 1.2}, 200, Phaser.Easing.Linear.None, true); |         mar.game.add.tween(this.scale).to({x: 1.2, y: 1.2}, 200, Phaser.Easing.Linear.None, true); | ||||||
| 
 | 
 | ||||||
|         this.cubotSprite.tint = config.cubot.hoverTint; |  | ||||||
| 
 |  | ||||||
|         if (this.text !== undefined) { |         if (this.text !== undefined) { | ||||||
|             this.text.visible = true; |             this.text.visible = true; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         this.hovered = true; |         this.hovered = true; | ||||||
|  |         this.cubotSprite.tint = this.getTint(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -263,7 +270,7 @@ class Cubot extends GameObject { | |||||||
|             if (this.energy <= config.cubot.lowEnergy) { |             if (this.energy <= config.cubot.lowEnergy) { | ||||||
|                 return config.cubot.lowEnergyTint; |                 return config.cubot.lowEnergyTint; | ||||||
|             } else { |             } else { | ||||||
|                 return config.cubot.tint; |                 return this.baseTint; | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             return config.cubot.hoverTint; |             return config.cubot.hoverTint; | ||||||
| @ -277,7 +284,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 +340,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); | ||||||
| @ -524,13 +531,6 @@ class HarvesterNPC extends Cubot { | |||||||
|         this.text.visible = false; |         this.text.visible = false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Needs to be overridden because Cubot() calls getTint() when initialised |  | ||||||
|      */ |  | ||||||
|     public getTint() { |  | ||||||
|         return config.cubot.tint; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public updateDirection() { |     public updateDirection() { | ||||||
|         switch (this.direction) { |         switch (this.direction) { | ||||||
|             case Direction.NORTH: |             case Direction.NORTH: | ||||||
| @ -548,6 +548,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 1000; //arbitrary number so that the lowEnergy color thresh doesn't trigger
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     updateObject(json) { |     updateObject(json) { | ||||||
|         if (DEBUG) { |         if (DEBUG) { | ||||||
|             console.log("Updating Harvester NPC object") |             console.log("Updating Harvester NPC object") | ||||||
| @ -578,6 +586,26 @@ class HarvesterNPC extends Cubot { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | class HackedNPC extends HarvesterNPC { | ||||||
|  | 
 | ||||||
|  |     constructor(json) { | ||||||
|  |         super(json); | ||||||
|  | 
 | ||||||
|  |         this.updateDirection(); | ||||||
|  |         this.setText("Hacked NPC"); | ||||||
|  |         this.text.visible = false; | ||||||
|  |         this.baseTint = config.hackedNpc.tint; | ||||||
|  |         this.cubotSprite.tint = this.baseTint; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     updateObject(json) { | ||||||
|  |         super.updateObject(json); | ||||||
|  | 
 | ||||||
|  |         let holoHw = json["net.simon987.cubotplugin.CubotHologram"]; | ||||||
|  |         this.updateHologram(holoHw.mode, holoHw.color, holoHw.value, holoHw.string); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class BiomassBlob extends GameObject { | class BiomassBlob extends GameObject { | ||||||
| 
 | 
 | ||||||
| @ -743,7 +771,7 @@ class VaultDoor extends GameObject { | |||||||
| 
 | 
 | ||||||
|         this.inputEnabled = true; |         this.inputEnabled = true; | ||||||
|         this.events.onInputDown.add(function (self: VaultDoor) { |         this.events.onInputDown.add(function (self: VaultDoor) { | ||||||
|             Debug.goToHex("7FFF", "7FFF", "v" + self.id + "-"); |             Debug.goToHex("7FFF", "7FFF", "v" + self.id); | ||||||
|             document.body.style.cursor = 'default'; |             document.body.style.cursor = 'default'; | ||||||
|             document.body.setAttribute("title", "") |             document.body.setAttribute("title", "") | ||||||
|         }, this); |         }, this); | ||||||
| @ -845,7 +873,7 @@ class Portal extends GameObject { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     constructor(json) { |     constructor(json) { | ||||||
|         super(Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/Portal"); |         super(Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/portal"); | ||||||
|         this.anchor.set(0.5, 0.3); |         this.anchor.set(0.5, 0.3); | ||||||
|         this.tint = config.portal.tint; |         this.tint = config.portal.tint; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -18,6 +18,9 @@ let config = { | |||||||
|         lowEnergy: 100, //Low energy threshold to change color
 |         lowEnergy: 100, //Low energy threshold to change color
 | ||||||
|         otherCubotAlpha: 0.6, |         otherCubotAlpha: 0.6, | ||||||
|     }, |     }, | ||||||
|  |     hackedNpc: { | ||||||
|  |         tint: 0xE040FB, | ||||||
|  |     }, | ||||||
|     biomass: { |     biomass: { | ||||||
|         tint: 0x63B85F, |         tint: 0x63B85F, | ||||||
|         tintHover: 0x00FF00, |         tintHover: 0x00FF00, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user