mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-12-13 14:49:03 +00:00
NPC Plugin refactoring
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ public class Factory extends Structure implements Updatable, MessageReceiver {
|
||||
private char[] program;
|
||||
private int programIndex = 0;
|
||||
|
||||
private static final int PROGRAM_SIZE = GameServer.INSTANCE.getConfig().getInt("factory_program_size");
|
||||
|
||||
public Factory() {
|
||||
super(2, 2);
|
||||
}
|
||||
@@ -83,47 +85,57 @@ public class Factory extends Structure implements Updatable, MessageReceiver {
|
||||
private NonPlayerCharacter spawnNPC(Point p) {
|
||||
|
||||
NonPlayerCharacter npc;
|
||||
|
||||
if (programIndex == 0) {
|
||||
npc = new HarvesterNPC();
|
||||
npc.setWorld(getWorld());
|
||||
npc.setObjectId(new ObjectId());
|
||||
npc.setX(p.x);
|
||||
npc.setY(p.y);
|
||||
getWorld().addObject(npc);
|
||||
getWorld().incUpdatable();
|
||||
npc = spawnRandomNpc(p);
|
||||
} else {
|
||||
|
||||
npc = new HackedNPC(program);
|
||||
npc.setWorld(getWorld());
|
||||
npc.setObjectId(new ObjectId());
|
||||
npc.setX(p.x);
|
||||
npc.setY(p.y);
|
||||
getWorld().addObject(npc);
|
||||
getWorld().incUpdatable();
|
||||
|
||||
System.out.println("NEW HACKED NPC");
|
||||
this.locked = true;
|
||||
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);
|
||||
getWorld().addObject(npc);
|
||||
getWorld().incUpdatable();
|
||||
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);
|
||||
getWorld().addObject(npc);
|
||||
getWorld().incUpdatable();
|
||||
|
||||
this.locked = true;
|
||||
this.programIndex = 0;
|
||||
|
||||
return npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendMessage(char[] message) {
|
||||
|
||||
String strMessage = String.valueOf(message);
|
||||
|
||||
System.out.println("Received message " + strMessage);
|
||||
if (locked) {
|
||||
Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId());
|
||||
|
||||
if (Arrays.equals(settlement.getPassword(), message)) {
|
||||
System.out.println("Factory unlock");
|
||||
this.locked = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
System.out.println("Wrong password, " + strMessage + "!=" + String.valueOf(settlement.getPassword()));
|
||||
} else if (programIndex <= 2048) { //todo config
|
||||
|
||||
if (programIndex == 0) {
|
||||
@@ -131,13 +143,11 @@ public class Factory extends Structure implements Updatable, MessageReceiver {
|
||||
}
|
||||
|
||||
System.arraycopy(message, 0, program, programIndex, message.length);
|
||||
System.out.println("Factory append code: " + strMessage);
|
||||
System.out.println("Wrote " + message.length + " chars");
|
||||
programIndex += message.length;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import net.simon987.server.game.item.ItemVoid;
|
||||
import net.simon987.server.game.objects.Action;
|
||||
import net.simon987.server.game.objects.ControllableUnit;
|
||||
import net.simon987.server.game.objects.Direction;
|
||||
import net.simon987.server.game.objects.HardwareHost;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.user.User;
|
||||
import org.bson.Document;
|
||||
import org.json.simple.JSONObject;
|
||||
@@ -17,9 +17,10 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, HardwareHost {
|
||||
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;
|
||||
/**
|
||||
@@ -39,15 +40,15 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
|
||||
cpu.setMemory(new Memory(MEM_SIZE));
|
||||
cpu.setHardwareHost(this);
|
||||
//Write program
|
||||
boolean write = cpu.getMemory().write(0, program, 0, program.length);
|
||||
System.out.println("Write " + write);
|
||||
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) {
|
||||
@@ -68,37 +69,14 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
hardware.setCpu(cpu);
|
||||
attachHardware(hardware, ((Document) serialisedHw).getInteger("address"));
|
||||
}
|
||||
|
||||
setTask(new ExecuteCpuTask());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
|
||||
|
||||
System.out.println(Util.toHex(cpu.getMemory().getBytes()));
|
||||
|
||||
//Execute code
|
||||
System.out.println("HACKED NPC " + this.getObjectId());
|
||||
int timeout = Math.min(getEnergy(), 30); //todo get from config
|
||||
cpu.reset();
|
||||
int cost = cpu.execute(timeout);
|
||||
spendEnergy(cost);
|
||||
|
||||
if (currentAction == Action.WALKING) {
|
||||
if (spendEnergy(100)) {
|
||||
if (!incrementLocation()) {
|
||||
//Couldn't walk
|
||||
currentAction = Action.IDLE;
|
||||
}
|
||||
} else {
|
||||
currentAction = Action.IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CurrentAction is set during the code execution and this function is called right after
|
||||
* If no action as been set, the action sent to the client is the action in currentAction that
|
||||
* was set last tick (IDLE)
|
||||
*/
|
||||
lastAction = currentAction;
|
||||
currentAction = Action.IDLE;
|
||||
|
||||
@@ -108,32 +86,49 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
for (HardwareModule module : hardwareAddresses.values()) {
|
||||
module.update();
|
||||
}
|
||||
|
||||
//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;
|
||||
@@ -141,11 +136,14 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
|
||||
@Override
|
||||
public ArrayList<char[]> getConsoleMessagesBuffer() {
|
||||
return null;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -210,6 +208,10 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
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) {
|
||||
@@ -217,6 +219,9 @@ public class HackedNPC extends NonPlayerCharacter implements ControllableUnit, H
|
||||
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);
|
||||
|
||||
@@ -30,7 +30,6 @@ public class HarvesterNPC extends NonPlayerCharacter {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
super.update();
|
||||
|
||||
if (getSettlement() != null) {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class NpcPlugin extends ServerPlugin {
|
||||
ServerConfiguration configuration = gameServer.getConfig();
|
||||
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 VaultWorldUpdateListener(configuration));
|
||||
listeners.add(new VaultCompleteListener());
|
||||
@@ -54,6 +54,8 @@ public class NpcPlugin extends ServerPlugin {
|
||||
|
||||
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();
|
||||
|
||||
@@ -55,8 +55,6 @@ public class Settlement implements MongoSerializable {
|
||||
|
||||
public Settlement(World world) throws WorldGenerationException {
|
||||
|
||||
System.out.println("SETTLING");
|
||||
|
||||
this.world = world;
|
||||
this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ?
|
||||
this.password = "12345678".toCharArray();
|
||||
|
||||
Reference in New Issue
Block a user