mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-12-13 14:49:03 +00:00
Added basic Radio Tower functionality #32
Keypress buffer is cleared on code upload
This commit is contained in:
@@ -124,7 +124,7 @@ public class Factory extends GameObject implements Updatable {
|
||||
factory.setX((int) (long) json.get("x"));
|
||||
factory.setY((int) (long) json.get("y"));
|
||||
|
||||
factory.tmpNpcArray = (Object[]) ((JSONArray) json.get("n")).toArray();
|
||||
factory.tmpNpcArray = ((JSONArray) json.get("n")).toArray();
|
||||
|
||||
return factory;
|
||||
}
|
||||
|
||||
@@ -1,35 +1,65 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import net.simon987.npcplugin.event.CpuInitialisationListener;
|
||||
import net.simon987.npcplugin.event.WorldCreationListener;
|
||||
import net.simon987.server.ServerConfiguration;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.io.CpuHardwareDeserializer;
|
||||
import net.simon987.server.io.GameObjectDeserializer;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
import net.simon987.server.plugin.ServerPlugin;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer {
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NpcPlugin extends ServerPlugin implements GameObjectDeserializer, CpuHardwareDeserializer {
|
||||
|
||||
/**
|
||||
* Radio tower cache
|
||||
*/
|
||||
private static ArrayList<RadioTower> radioTowers;
|
||||
|
||||
@Override
|
||||
public void init(ServerConfiguration configuration) {
|
||||
|
||||
listeners.add(new WorldCreationListener());
|
||||
listeners.add(new CpuInitialisationListener());
|
||||
|
||||
radioTowers = new ArrayList<>(32);
|
||||
|
||||
LogManager.LOGGER.info("Initialised NPC plugin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameObject deserializeObject(JSONObject object) {
|
||||
public GameObject deserializeObject(JSONObject json) {
|
||||
|
||||
int objType = (int) (long) object.get("t");
|
||||
int objType = (int) (long) json.get("t");
|
||||
|
||||
if (objType == HarvesterNPC.ID) {
|
||||
return HarvesterNPC.deserialize(object);
|
||||
return HarvesterNPC.deserialize(json);
|
||||
} else if (objType == Factory.ID) {
|
||||
return Factory.deserialise(object);
|
||||
return Factory.deserialise(json);
|
||||
} else if (objType == RadioTower.ID) {
|
||||
return RadioTower.deserialize(json);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpuHardware deserializeHardware(JSONObject hwJson) {
|
||||
int hwid = (int) (long) hwJson.get("hwid");
|
||||
|
||||
switch (hwid) {
|
||||
case RadioReceiverHardware.HWID:
|
||||
return RadioReceiverHardware.deserialize(hwJson);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ArrayList<RadioTower> getRadioTowers() {
|
||||
return radioTowers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.assembly.CpuHardware;
|
||||
import net.simon987.server.assembly.Status;
|
||||
import net.simon987.server.assembly.Util;
|
||||
import net.simon987.server.game.Action;
|
||||
import net.simon987.server.game.ControllableUnit;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RadioReceiverHardware extends CpuHardware {
|
||||
|
||||
public static final char HWID = 0xC; //12
|
||||
|
||||
private static final int LISTEN = 1;
|
||||
|
||||
public static final int DEFAULT_ADDRESS = 0xC;
|
||||
|
||||
private ControllableUnit cubot;
|
||||
|
||||
public RadioReceiverHardware(ControllableUnit cubot) {
|
||||
this.cubot = cubot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInterrupt(Status status) {
|
||||
int x = getCpu().getRegisterSet().getRegister("X").getValue();
|
||||
int a = getCpu().getRegisterSet().getRegister("A").getValue();
|
||||
|
||||
if (a == LISTEN) {
|
||||
|
||||
//Find the nearest Radio Tower and query it
|
||||
cubot.setAction(Action.LISTENING);
|
||||
|
||||
ArrayList<char[]> messages = new ArrayList<>(6);
|
||||
|
||||
ArrayList<RadioTower> towers = new ArrayList<>(NpcPlugin.getRadioTowers()); //Avoid ConcurrentModificationException
|
||||
for (RadioTower tower : towers) {
|
||||
if (Util.manhattanDist(tower.getX(), tower.getY(), cubot.getX(), cubot.getY()) <= RadioTower.MAX_RANGE) {
|
||||
//Tower is in range
|
||||
messages.addAll(tower.getMessages());
|
||||
}
|
||||
}
|
||||
|
||||
//Write messages to memory
|
||||
int offset = 0;
|
||||
|
||||
for (char[] message : messages) {
|
||||
|
||||
getCpu().getMemory().write(x + offset, message, 0, message.length);
|
||||
offset += message.length;
|
||||
}
|
||||
|
||||
//Write the amount of messages received to B
|
||||
getCpu().getRegisterSet().getRegister("B").setValue(messages.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char getId() {
|
||||
return HWID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject serialise() {
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("hwid", (int) HWID);
|
||||
json.put("cubot", cubot.getObjectId());
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
public static RadioReceiverHardware deserialize(JSONObject json) {
|
||||
return new RadioReceiverHardware((ControllableUnit) GameServer.INSTANCE.getGameUniverse().getObject((int) (long) json.get("cubot")));
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,103 @@
|
||||
package net.simon987.npcplugin;
|
||||
|
||||
public class RadioTower {
|
||||
import net.simon987.server.game.GameObject;
|
||||
import net.simon987.server.game.Programmable;
|
||||
import net.simon987.server.game.Updatable;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RadioTower extends GameObject implements Programmable, Updatable {
|
||||
|
||||
private static final int MAP_INFO = 0x1000;
|
||||
|
||||
public static final int ID = 4;
|
||||
|
||||
public static final int MAX_RANGE = 3; //todo load from config
|
||||
|
||||
private static final int MAX_MESSAGES = 16;
|
||||
|
||||
@Override
|
||||
public char getMapInfo() {
|
||||
return MAP_INFO;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Messages from the current tick
|
||||
*/
|
||||
private ArrayList<char[]> messages = new ArrayList<>(4);
|
||||
|
||||
/**
|
||||
* Messages from the last tick
|
||||
*/
|
||||
private ArrayList<char[]> lastMessages = new ArrayList<>(4);
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
lastMessages = new ArrayList<>(messages);
|
||||
messages.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(char[] message) {
|
||||
|
||||
if (message.length < MAX_MESSAGES) {
|
||||
messages.add(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject serialise() {
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put("i", getObjectId());
|
||||
json.put("x", getX());
|
||||
json.put("y", getY());
|
||||
json.put("t", ID);
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
public static RadioTower deserialize(JSONObject json) {
|
||||
|
||||
RadioTower tower = new RadioTower();
|
||||
tower.setObjectId((long) json.get("i"));
|
||||
tower.setX((int) (long) json.get("x"));
|
||||
tower.setY((int) (long) json.get("y"));
|
||||
|
||||
NpcPlugin.getRadioTowers().add(tower);
|
||||
|
||||
return tower;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<char[]> getMessages() {
|
||||
return lastMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first directly adjacent tile (starting east, going clockwise)
|
||||
*/
|
||||
public Point getAdjacentTile() {
|
||||
|
||||
if (!getWorld().isTileBlocked(getX() + 1, getY())) {
|
||||
return new Point(getX() + 1, getY());
|
||||
|
||||
} else if (!getWorld().isTileBlocked(getX(), getY() + 1)) {
|
||||
return new Point(getX(), getY() + 1);
|
||||
|
||||
} else if (!getWorld().isTileBlocked(getX() - 1, getY())) {
|
||||
return new Point(getX() - 1, getY());
|
||||
|
||||
} else if (!getWorld().isTileBlocked(getX(), getY() - 1)) {
|
||||
return new Point(getX(), getY() - 1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.simon987.npcplugin.event;
|
||||
|
||||
import net.simon987.npcplugin.RadioReceiverHardware;
|
||||
import net.simon987.server.assembly.CPU;
|
||||
import net.simon987.server.event.CpuInitialisationEvent;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
import net.simon987.server.user.User;
|
||||
|
||||
public class CpuInitialisationListener implements GameEventListener {
|
||||
@Override
|
||||
public Class getListenedEventType() {
|
||||
return CpuInitialisationEvent.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(GameEvent event) {
|
||||
CPU cpu = (CPU) event.getSource();
|
||||
User user = ((CpuInitialisationEvent) event).getUser();
|
||||
|
||||
RadioReceiverHardware radioHw = new RadioReceiverHardware(user.getControlledUnit());
|
||||
radioHw.setCpu(cpu);
|
||||
|
||||
cpu.attachHardware(radioHw, RadioReceiverHardware.DEFAULT_ADDRESS);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package net.simon987.npcplugin.event;
|
||||
|
||||
import net.simon987.npcplugin.Factory;
|
||||
import net.simon987.npcplugin.NpcPlugin;
|
||||
import net.simon987.npcplugin.RadioTower;
|
||||
import net.simon987.server.GameServer;
|
||||
import net.simon987.server.event.GameEvent;
|
||||
import net.simon987.server.event.GameEventListener;
|
||||
@@ -8,6 +10,7 @@ import net.simon987.server.event.WorldGenerationEvent;
|
||||
import net.simon987.server.game.World;
|
||||
import net.simon987.server.logging.LogManager;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Random;
|
||||
|
||||
public class WorldCreationListener implements GameEventListener {
|
||||
@@ -31,6 +34,7 @@ public class WorldCreationListener implements GameEventListener {
|
||||
|
||||
World world = ((WorldGenerationEvent) event).getWorld();
|
||||
|
||||
outerLoopFactory:
|
||||
for (int x = 2; x < 12; x++) {
|
||||
for (int y = 2; y < 12; y++) {
|
||||
|
||||
@@ -54,10 +58,40 @@ public class WorldCreationListener implements GameEventListener {
|
||||
|
||||
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.getRandomPassableTile();
|
||||
if (p != null) {
|
||||
while (p.x == 0 || p.x == World.WORLD_SIZE - 1 || p.y == World.WORLD_SIZE - 1 || p.y == 0) {
|
||||
p = world.getRandomPassableTile();
|
||||
|
||||
if (p == null) {
|
||||
//World is full
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RadioTower radioTower = new RadioTower();
|
||||
|
||||
radioTower.setWorld(world);
|
||||
radioTower.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId());
|
||||
radioTower.setX(p.x);
|
||||
radioTower.setY(p.y);
|
||||
|
||||
if (radioTower.getAdjacentTile() != null) {
|
||||
//Radio Tower has adjacent tiles
|
||||
world.getGameObjects().add(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 + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user