diff --git a/Plugin Cubot/Plugin Cubot.iml b/Plugin Cubot/Plugin Cubot.iml index 779d178..a6ee292 100644 --- a/Plugin Cubot/Plugin Cubot.iml +++ b/Plugin Cubot/Plugin Cubot.iml @@ -17,6 +17,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java index 97710bc..bc740e6 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/Cubot.java @@ -11,7 +11,6 @@ import net.simon987.server.assembly.Status; import net.simon987.server.assembly.exception.CancelledException; import net.simon987.server.event.GameEvent; import net.simon987.server.game.item.Item; -import net.simon987.server.game.item.ItemVoid; import net.simon987.server.game.objects.*; import net.simon987.server.user.User; import org.bson.Document; @@ -201,7 +200,7 @@ public class Cubot extends GameObject implements Updatable, ControllableUnit, Me JSONObject json = super.jsonSerialise(); json.put("direction", getDirection().ordinal()); CubotInventory inv = (CubotInventory) getHardware(CubotInventory.class); - int heldItem = inv.getInventory().getOrDefault(inv.getPosition(), new ItemVoid()).getId(); + int heldItem = inv.getCurrentItem().getId(); json.put("heldItem", heldItem); json.put("hp", hp); json.put("shield", shield); diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java index 0a344a4..b291460 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotInventory.java @@ -4,6 +4,7 @@ import net.simon987.server.GameServer; import net.simon987.server.assembly.HardwareModule; import net.simon987.server.assembly.Status; import net.simon987.server.game.item.Item; +import net.simon987.server.game.item.ItemVoid; import net.simon987.server.game.objects.ControllableUnit; import org.bson.Document; @@ -55,11 +56,30 @@ public class CubotInventory extends HardwareModule { private void scanItem() { int x = getCpu().getRegisterSet().getRegister("X").getValue(); Item item = inventory.get(position); + if (item == null) { + return; + } item.digitize(unit.getCpu().getMemory(), x); } + public Item getCurrentItem() { + return inventory.getOrDefault(position, new ItemVoid()); + } + + public Item removeItem() { + Item item = inventory.get(position); + if (item == null) { + return new ItemVoid(); + } + inventory.remove(position); + return item; + } + public Item clearItem() { Item item = inventory.get(position); + if (item == null) { + return new ItemVoid(); + } item.clear(unit); inventory.remove(position); diff --git a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java index 040c3ad..7e8587a 100644 --- a/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java +++ b/Plugin Cubot/src/main/java/net/simon987/cubotplugin/CubotLaser.java @@ -3,7 +3,11 @@ package net.simon987.cubotplugin; import net.simon987.server.GameServer; import net.simon987.server.assembly.HardwareModule; import net.simon987.server.assembly.Status; -import net.simon987.server.game.objects.*; +import net.simon987.server.game.item.Item; +import net.simon987.server.game.objects.Action; +import net.simon987.server.game.objects.Attackable; +import net.simon987.server.game.objects.GameObject; +import net.simon987.server.game.objects.InventoryHolder; import org.bson.Document; import java.awt.*; @@ -24,34 +28,36 @@ public class CubotLaser extends HardwareModule { private static final int LASER_DAMAGE = 25; - public CubotLaser(ControllableUnit unit) { + public CubotLaser(Cubot unit) { super(null, unit); } - public CubotLaser(Document document, ControllableUnit cubot) { + public CubotLaser(Document document, Cubot cubot) { super(document, cubot); } + private Cubot getCubot() { + return (Cubot) unit; + } + @Override public char getId() { return HWID; } @Override + //TODO: Refactor this method.. public void handleInterrupt(Status status) { int a = getCpu().getRegisterSet().getRegister("A").getValue(); int b = getCpu().getRegisterSet().getRegister("B").getValue(); - if (a == LASER_WITHDRAW) { - Point frontTile = unit.getFrontTile(); ArrayList objects = unit.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); if (unit.getCurrentAction() == Action.IDLE && objects.size() > 0) { - //FIXME: Problem here if more than 1 object if (objects.get(0) instanceof InventoryHolder) { if (((InventoryHolder) objects.get(0)).canTakeItem(b)) { @@ -65,9 +71,24 @@ public class CubotLaser extends HardwareModule { } } - } else if (a == LASER_DEPOSIT) { - // TODO + Point frontTile = unit.getFrontTile(); + ArrayList objects = unit.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); + + CubotInventory inv = ((CubotInventory) getCubot().getHardware(CubotInventory.class)); + Item item = inv.getCurrentItem(); + + if (unit.getCurrentAction() == Action.IDLE && objects.size() > 0) { + if (objects.get(0) instanceof InventoryHolder) { + if (((InventoryHolder) objects.get(0)).canPlaceItem(item.getId())) { + if (unit.spendEnergy(30)) { + //Place the item + ((InventoryHolder) objects.get(0)).placeItem(inv.removeItem()); + unit.setCurrentAction(Action.DEPOSITING); + } + } + } + } } else if (a == LASER_ATTACK) { if (unit.getCurrentAction() == Action.IDLE) { @@ -81,12 +102,10 @@ public class CubotLaser extends HardwareModule { if (objects.size() > 0 && objects.get(0) instanceof Attackable && !(objects.get(0) instanceof Cubot)) { ((Attackable) objects.get(0)).damage(LASER_DAMAGE); } - } unit.setCurrentAction(Action.ATTACKING); } } - } } diff --git a/Plugin Misc HW/Plugin Misc HW.iml b/Plugin Misc HW/Plugin Misc HW.iml index b60e708..b129737 100644 --- a/Plugin Misc HW/Plugin Misc HW.iml +++ b/Plugin Misc HW/Plugin Misc HW.iml @@ -16,6 +16,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugin NPC/Plugin NPC.iml b/Plugin NPC/Plugin NPC.iml index 277b9e7..63bda44 100644 --- a/Plugin NPC/Plugin NPC.iml +++ b/Plugin NPC/Plugin NPC.iml @@ -16,6 +16,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Plugin Plant/Plugin Plant.iml b/Plugin Plant/Plugin Plant.iml index 277b9e7..63bda44 100644 --- a/Plugin Plant/Plugin Plant.iml +++ b/Plugin Plant/Plugin Plant.iml @@ -16,6 +16,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Server/src/main/java/net/simon987/server/assembly/Memory.java b/Server/src/main/java/net/simon987/server/assembly/Memory.java index 29374fe..dd0efef 100755 --- a/Server/src/main/java/net/simon987/server/assembly/Memory.java +++ b/Server/src/main/java/net/simon987/server/assembly/Memory.java @@ -94,6 +94,23 @@ public class Memory implements Target, MongoSerializable { return true; } + /** + * Read count words from the memory + * + * @return null if out of bounds + */ + public char[] read(int offset, int count) { + + if (offset + count > this.words.length || count < 0 || offset < 0) { + return null; + } + + char[] chars = new char[count]; + System.arraycopy(words, offset, chars, 0, count); + + return chars; + } + /** * Set the value at an address * diff --git a/Server/src/main/java/net/simon987/server/game/objects/InventoryHolder.java b/Server/src/main/java/net/simon987/server/game/objects/InventoryHolder.java index 505b968..f2966ab 100644 --- a/Server/src/main/java/net/simon987/server/game/objects/InventoryHolder.java +++ b/Server/src/main/java/net/simon987/server/game/objects/InventoryHolder.java @@ -20,4 +20,9 @@ public interface InventoryHolder { * @return true if the InventoryHolder can provide this item */ boolean canTakeItem(int itemId); + + /** + * @return true if the InventoryHolder can receive this item + */ + boolean canPlaceItem(int itemId); } diff --git a/Server/src/main/java/net/simon987/server/game/objects/ItemsContainer.java b/Server/src/main/java/net/simon987/server/game/objects/ItemsContainer.java index 7d9e275..5b9ec57 100644 --- a/Server/src/main/java/net/simon987/server/game/objects/ItemsContainer.java +++ b/Server/src/main/java/net/simon987/server/game/objects/ItemsContainer.java @@ -32,7 +32,7 @@ public class ItemsContainer extends GameObject implements InventoryHolder { @Override public boolean placeItem(Item item) { - if (items.size() < containerCapacity) { + if (canPlaceItem(item.getId())) { items.add(item); return true; } else { @@ -40,6 +40,11 @@ public class ItemsContainer extends GameObject implements InventoryHolder { } } + @Override + public boolean canPlaceItem(int itemId) { + return (items.size() < containerCapacity); + } + @Override public void takeItem(int itemId) { Optional first = items.stream() diff --git a/Server/src/main/resources/static/images/sprites.json b/Server/src/main/resources/static/images/sprites.json index 44c8381..c8ec941 100644 --- a/Server/src/main/resources/static/images/sprites.json +++ b/Server/src/main/resources/static/images/sprites.json @@ -11376,120 +11376,24 @@ "y": 0.5 } }, - "objects/GOURD_PLANT": { + "objects/obstacle": { "frame": { "x": 768, "y": 1050, - "w": 32, - "h": 32 + "w": 128, + "h": 114 }, "rotated": false, "trimmed": false, "spriteSourceSize": { "x": 0, "y": 0, - "w": 32, - "h": 32 + "w": 128, + "h": 114 }, "sourceSize": { - "w": 32, - "h": 32 - }, - "pivot": { - "x": 0.5, - "y": 0.5 - } - }, - "objects/kiln": { - "frame": { - "x": 800, - "y": 1050, - "w": 116, - "h": 117 - }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 116, - "h": 117 - }, - "sourceSize": { - "w": 116, - "h": 117 - }, - "pivot": { - "x": 0.5, - "y": 0.5 - } - }, - "objects/kiln_s": { - "frame": { - "x": 916, - "y": 1050, - "w": 116, - "h": 117 - }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 116, - "h": 117 - }, - "sourceSize": { - "w": 116, - "h": 117 - }, - "pivot": { - "x": 0.5, - "y": 0.5 - } - }, - "objects/plant1": { - "frame": { - "x": 1032, - "y": 1050, - "w": 64, - "h": 64 - }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 64, - "h": 64 - }, - "sourceSize": { - "w": 64, - "h": 64 - }, - "pivot": { - "x": 0.5, - "y": 0.5 - } - }, - "objects/plant1_s": { - "frame": { - "x": 1096, - "y": 1050, - "w": 64, - "h": 64 - }, - "rotated": false, - "trimmed": false, - "spriteSourceSize": { - "x": 0, - "y": 0, - "w": 64, - "h": 64 - }, - "sourceSize": { - "w": 64, - "h": 64 + "w": 128, + "h": 114 }, "pivot": { "x": 0.5, @@ -11498,7 +11402,7 @@ }, "objects/portal": { "frame": { - "x": 1160, + "x": 896, "y": 1050, "w": 128, "h": 110 @@ -11522,7 +11426,7 @@ }, "objects/RadioTower": { "frame": { - "x": 1288, + "x": 1024, "y": 1050, "w": 168, "h": 237 @@ -11546,7 +11450,7 @@ }, "objects/rocket": { "frame": { - "x": 1456, + "x": 1192, "y": 1050, "w": 135, "h": 189 @@ -11570,7 +11474,7 @@ }, "objects/shieldBack": { "frame": { - "x": 1591, + "x": 1327, "y": 1050, "w": 128, "h": 70 @@ -11594,7 +11498,7 @@ }, "objects/shieldFront": { "frame": { - "x": 1719, + "x": 1455, "y": 1050, "w": 128, "h": 70 @@ -11618,7 +11522,7 @@ }, "objects/VaultDoor": { "frame": { - "x": 1847, + "x": 1583, "y": 1050, "w": 213, "h": 170 @@ -11642,7 +11546,7 @@ }, "objects/VaultDoor1": { "frame": { - "x": 2060, + "x": 1796, "y": 1050, "w": 139, "h": 150 @@ -11666,7 +11570,7 @@ }, "objects/VaultDoorCrop": { "frame": { - "x": 2199, + "x": 1935, "y": 1050, "w": 137, "h": 150 @@ -11690,7 +11594,7 @@ }, "objects/VaultDoorScreen/1": { "frame": { - "x": 2336, + "x": 2072, "y": 1050, "w": 20, "h": 18 @@ -11714,7 +11618,7 @@ }, "objects/VaultDoorScreen/2": { "frame": { - "x": 2356, + "x": 2092, "y": 1050, "w": 20, "h": 18 @@ -11738,7 +11642,7 @@ }, "objects/VaultDoorScreen/3": { "frame": { - "x": 2376, + "x": 2112, "y": 1050, "w": 20, "h": 18 @@ -11762,7 +11666,7 @@ }, "objects/VaultDoorScreen/4": { "frame": { - "x": 2396, + "x": 2132, "y": 1050, "w": 20, "h": 18 @@ -11786,7 +11690,7 @@ }, "objects/VaultDoorScreen/5": { "frame": { - "x": 2416, + "x": 2152, "y": 1050, "w": 20, "h": 18 @@ -11810,7 +11714,7 @@ }, "objects/VaultDoorScreen/6": { "frame": { - "x": 2436, + "x": 2172, "y": 1050, "w": 20, "h": 18 @@ -11834,7 +11738,7 @@ }, "tiles/bigTile": { "frame": { - "x": 2456, + "x": 2192, "y": 1050, "w": 128, "h": 140 @@ -11858,7 +11762,7 @@ }, "tiles/bigTile2": { "frame": { - "x": 2584, + "x": 2320, "y": 1050, "w": 128, "h": 153 @@ -11882,7 +11786,7 @@ }, "tiles/magneticTile": { "frame": { - "x": 2712, + "x": 2448, "y": 1050, "w": 128, "h": 114 @@ -11906,7 +11810,7 @@ }, "tiles/tile": { "frame": { - "x": 2840, + "x": 2576, "y": 1050, "w": 128, "h": 114 @@ -11930,7 +11834,7 @@ }, "ui/arrow_east": { "frame": { - "x": 2968, + "x": 2704, "y": 1050, "w": 102, "h": 51 @@ -11954,7 +11858,7 @@ }, "ui/arrow_east_s": { "frame": { - "x": 3070, + "x": 2806, "y": 1050, "w": 102, "h": 51 @@ -11978,7 +11882,7 @@ }, "ui/arrow_north": { "frame": { - "x": 3172, + "x": 2908, "y": 1050, "w": 102, "h": 51 @@ -12002,7 +11906,7 @@ }, "ui/arrow_north_s": { "frame": { - "x": 3274, + "x": 3010, "y": 1050, "w": 102, "h": 51 @@ -12026,7 +11930,7 @@ }, "ui/arrow_south": { "frame": { - "x": 3376, + "x": 3112, "y": 1050, "w": 102, "h": 51 @@ -12050,7 +11954,7 @@ }, "ui/arrow_south_s": { "frame": { - "x": 3478, + "x": 3214, "y": 1050, "w": 102, "h": 51 @@ -12074,7 +11978,7 @@ }, "ui/arrow_west": { "frame": { - "x": 3580, + "x": 3316, "y": 1050, "w": 102, "h": 51 @@ -12098,7 +12002,7 @@ }, "ui/arrow_west_s": { "frame": { - "x": 3682, + "x": 3418, "y": 1050, "w": 102, "h": 51 @@ -12122,7 +12026,7 @@ }, "ui/compass": { "frame": { - "x": 3784, + "x": 3520, "y": 1050, "w": 162, "h": 147 @@ -12155,6 +12059,6 @@ "h": 1287 }, "scale": "1", - "smartupdate": "$TexturePacker:SmartUpdate:73c963294f55ee095af7f9f7c60b9d3d:93610d7ee804aa39ff18e2974a508abb:1eabdf11f75e3a4fe3147baf7b5be24b$" + "smartupdate": "$TexturePacker:SmartUpdate:cabd9bbebff623bfa01a63c764edf16e:8b226981e250398faa4378b63606c23e:1eabdf11f75e3a4fe3147baf7b5be24b$" } } diff --git a/Server/src/main/resources/static/images/sprites.png b/Server/src/main/resources/static/images/sprites.png index 8d1e5c0..ae5ddb0 100644 Binary files a/Server/src/main/resources/static/images/sprites.png and b/Server/src/main/resources/static/images/sprites.png differ diff --git a/Server/src/main/resources/static/js/mar.js b/Server/src/main/resources/static/js/mar.js index 6ea23c9..c0541cd 100644 --- a/Server/src/main/resources/static/js/mar.js +++ b/Server/src/main/resources/static/js/mar.js @@ -8,7 +8,7 @@ var __extends = (this && this.__extends) || (function () { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); - } + }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } @@ -336,6 +336,12 @@ var config = { }, world: { defaultSize: 16 + }, + obstacle: { + tint: 0x0aced6, + }, + constructionSite: { + tint: 0x0aced6, } }; var Util = (function () { @@ -822,6 +828,7 @@ var GameClient = (function () { }; return GameClient; }()); +var game = PIXI.game; var ObjectType; (function (ObjectType) { ObjectType["CUBOT"] = "net.simon987.cubotplugin.Cubot"; @@ -830,10 +837,11 @@ var ObjectType; ObjectType["FACTORY"] = "net.simon987.npcplugin.Factory"; ObjectType["RADIO_TOWER"] = "net.simon987.npcplugin.RadioTower"; ObjectType["VAULT_DOOR"] = "net.simon987.npcplugin.VaultDoor"; - ObjectType["OBSTACLE"] = "net.simon987.npcplugin.Obstacle"; + ObjectType["OBSTACLE"] = "net.simon987.constructionplugin.Obstacle"; ObjectType["ELECTRIC_BOX"] = "net.simon987.npcplugin.ElectricBox"; ObjectType["PORTAL"] = "net.simon987.npcplugin.Portal"; ObjectType["HACKED_NPC"] = "net.simon987.npcplugin.HackedNPC"; + ObjectType["CONSTRUCTION_SITE"] = "net.simon987.constructionplugin.ConstructionSite"; })(ObjectType || (ObjectType = {})); var ItemType; (function (ItemType) { @@ -872,13 +880,15 @@ var GameObject = (function (_super) { case ObjectType.VAULT_DOOR: return new VaultDoor(json); case ObjectType.OBSTACLE: - return null; + return new Obstacle(json); case ObjectType.ELECTRIC_BOX: return new ElectricBox(json); case ObjectType.PORTAL: return new Portal(json); case ObjectType.HACKED_NPC: return new HackedNPC(json); + case ObjectType.CONSTRUCTION_SITE: + return new ConstructionSite(json); default: return null; } @@ -1287,7 +1297,7 @@ var BiomassBlob = (function (_super) { mar.game.tweens.removeFrom(this); mar.game.add.tween(this).to({ isoZ: 15 }, 400, Phaser.Easing.Bounce.Out, true); mar.game.add.tween(this.scale).to({ x: 1, y: 1 }, 200, Phaser.Easing.Linear.None, true); - this.tint = config.biomass.tintHover; + this.tint = config.biomass.tint; this.text.visible = false; }; BiomassBlob.prototype.updateObject = function (json) { @@ -1446,6 +1456,83 @@ var ElectricBox = (function (_super) { }; return ElectricBox; }(GameObject)); +var Obstacle = (function (_super) { + __extends(Obstacle, _super); + + function Obstacle(json) { + var _this = _super.call(this, Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/obstacle") || this; + _this.anchor.set(0.5, 0.3); + _this.tint = config.obstacle.tint; + _this.setText("Obstacle"); + _this.text.visible = false; + _this.id = json.i; + _this.tileX = json.x; + _this.tileY = json.y; + return _this; + } + + Obstacle.prototype.updateObject = function (json) { + }; + Obstacle.prototype.onTileHover = function () { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 25}, 200, Phaser.Easing.Quadratic.InOut, true); + mar.game.add.tween(this.scale).to({x: 1.1, y: 1.1}, 200, Phaser.Easing.Linear.None, true); + this.tint = config.cubot.hoverTint; + this.text.visible = true; + }; + Obstacle.prototype.onTileExit = function () { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); + mar.game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); + this.tint = config.portal.tint; + this.text.visible = false; + }; + return Obstacle; +}(GameObject)); +var ConstructionSite = (function (_super) { + __extends(ConstructionSite, _super); + + function ConstructionSite(json) { + var _this = _super.call(this, Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", ConstructionSite.getTargetSprite(json.blueprint.target)) || this; + _this.anchor.set(0.5, 0.31); + _this.tint = config.constructionSite.tint; + _this.setText("Construction site"); + _this.text.visible = false; + _this.setUpAlphaTween(); + _this.id = json.i; + _this.tileX = json.x; + _this.tileY = json.y; + return _this; + } + + ConstructionSite.getTargetSprite = function (targetType) { + switch (targetType) { + case ObjectType.OBSTACLE: + return "objects/obstacle"; + } + }; + ConstructionSite.prototype.updateObject = function (json) { + }; + ConstructionSite.prototype.setUpAlphaTween = function () { + var alphaTween = mar.game.add.tween(this).to({alpha: 0.5}, 2000, Phaser.Easing.Linear.None, true, 0, -1); + alphaTween.yoyo(true, 3000); + }; + ConstructionSite.prototype.onTileHover = function () { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 19}, 200, Phaser.Easing.Quadratic.InOut, true); + mar.game.add.tween(this.scale).to({x: 1.03, y: 1.03}, 200, Phaser.Easing.Linear.None, true); + this.setUpAlphaTween(); + this.text.visible = true; + }; + ConstructionSite.prototype.onTileExit = function () { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); + mar.game.add.tween(this.scale).to({x: 1.03, y: 1.03}, 200, Phaser.Easing.Linear.None, true); + this.setUpAlphaTween(); + this.text.visible = false; + }; + return ConstructionSite; +}(GameObject)); var Portal = (function (_super) { __extends(Portal, _super); function Portal(json) { diff --git a/Server/src/main/typescript/GameObject.ts b/Server/src/main/typescript/GameObject.ts index c37c0a0..ba2eb14 100644 --- a/Server/src/main/typescript/GameObject.ts +++ b/Server/src/main/typescript/GameObject.ts @@ -5,10 +5,11 @@ enum ObjectType { FACTORY = "net.simon987.npcplugin.Factory", RADIO_TOWER = "net.simon987.npcplugin.RadioTower", VAULT_DOOR = "net.simon987.npcplugin.VaultDoor", - OBSTACLE = "net.simon987.npcplugin.Obstacle", + OBSTACLE = "net.simon987.constructionplugin.Obstacle", ELECTRIC_BOX = "net.simon987.npcplugin.ElectricBox", PORTAL = "net.simon987.npcplugin.Portal", - HACKED_NPC = "net.simon987.npcplugin.HackedNPC" + HACKED_NPC = "net.simon987.npcplugin.HackedNPC", + CONSTRUCTION_SITE = "net.simon987.constructionplugin.ConstructionSite" } enum ItemType { @@ -71,13 +72,15 @@ abstract class GameObject extends Phaser.Plugin.Isometric.IsoSprite { case ObjectType.VAULT_DOOR: return new VaultDoor(json); case ObjectType.OBSTACLE: - return null; + return new Obstacle(json); case ObjectType.ELECTRIC_BOX: return new ElectricBox(json); case ObjectType.PORTAL: return new Portal(json); case ObjectType.HACKED_NPC: return new HackedNPC(json); + case ObjectType.CONSTRUCTION_SITE: + return new ConstructionSite(json); default: return null; @@ -622,7 +625,7 @@ class BiomassBlob extends GameObject { mar.game.tweens.removeFrom(this); mar.game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); mar.game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); - this.tint = config.biomass.tintHover; + this.tint = config.biomass.tint; this.text.visible = false; } @@ -848,6 +851,97 @@ class ElectricBox extends GameObject { } } +class Obstacle extends GameObject { + + constructor(json) { + super(Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", "objects/obstacle"); + this.anchor.set(0.5, 0.3); + this.tint = config.obstacle.tint; + + this.setText("Obstacle"); + this.text.visible = false; + + this.id = json.i; + this.tileX = json.x; + this.tileY = json.y; + } + + updateObject(json): void { + //noop + } + + public onTileHover() { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 25}, 200, Phaser.Easing.Quadratic.InOut, true); + mar.game.add.tween(this.scale).to({x: 1.1, y: 1.1}, 200, Phaser.Easing.Linear.None, true); + this.tint = config.cubot.hoverTint; + + this.text.visible = true; + } + + public onTileExit() { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); + mar.game.add.tween(this.scale).to({x: 1, y: 1}, 200, Phaser.Easing.Linear.None, true); + this.tint = config.portal.tint; + + this.text.visible = false; + } +} + +class ConstructionSite extends GameObject { + + private static getTargetSprite(targetType: string): string { + switch (targetType) { + case ObjectType.OBSTACLE: + return "objects/obstacle"; + } + } + + constructor(json) { + + super(Util.getIsoX(json.x), Util.getIsoY(json.y), 15, "sheet", ConstructionSite.getTargetSprite(json.blueprint.target)); + this.anchor.set(0.5, 0.31); + this.tint = config.constructionSite.tint; + + this.setText("Construction site"); + this.text.visible = false; + + this.setUpAlphaTween(); + + this.id = json.i; + this.tileX = json.x; + this.tileY = json.y; + } + + updateObject(json): void { + //noop + } + + private setUpAlphaTween() { + let alphaTween = mar.game.add.tween(this).to({alpha: 0.5}, + 2000, Phaser.Easing.Linear.None, true, 0, -1); + alphaTween.yoyo(true, 3000); + } + + public onTileHover() { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 19}, 200, Phaser.Easing.Quadratic.InOut, true); + mar.game.add.tween(this.scale).to({x: 1.03, y: 1.03}, 200, Phaser.Easing.Linear.None, true); + this.setUpAlphaTween(); + + this.text.visible = true; + } + + public onTileExit() { + mar.game.tweens.removeFrom(this); + mar.game.add.tween(this).to({isoZ: 15}, 400, Phaser.Easing.Bounce.Out, true); + mar.game.add.tween(this.scale).to({x: 1.03, y: 1.03}, 200, Phaser.Easing.Linear.None, true); + this.setUpAlphaTween(); + + this.text.visible = false; + } +} class Portal extends GameObject { public onTileHover() { diff --git a/Server/src/main/typescript/mar.ts b/Server/src/main/typescript/mar.ts index a7b6388..da4b76b 100644 --- a/Server/src/main/typescript/mar.ts +++ b/Server/src/main/typescript/mar.ts @@ -78,6 +78,12 @@ let config = { }, world: { defaultSize: 16 //Will fallback to this when server does not provide world width + }, + obstacle: { + tint: 0x0aced6, //todo + }, + constructionSite: { + tint: 0x0aced6, //todo } }; diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrint.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrint.java index b4620f6..d5d683f 100644 --- a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrint.java +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrint.java @@ -24,17 +24,25 @@ public abstract class BluePrint implements InventoryHolder, JSONSerializable, Mo */ protected Class targetObject; + static final int DATA_LENGTH = 1024; + /** * Set to true when all the requirements are met */ private boolean completed; - public BluePrint() { + BluePrint() { requiredItems = new HashMap<>(); } public BluePrint(Document document) { - requiredItems = (Map) document.get("required_items"); + Map bsonCompatibleRequiredItems = (Map) document.get("required_items"); + requiredItems = new HashMap<>(bsonCompatibleRequiredItems.size()); + + for (String key : bsonCompatibleRequiredItems.keySet()) { + requiredItems.put(Integer.valueOf(key), bsonCompatibleRequiredItems.get(key)); + } + completed = document.getBoolean("completed"); try { targetObject = Class.forName(document.getString("target")).asSubclass(GameObject.class); @@ -57,7 +65,7 @@ public abstract class BluePrint implements InventoryHolder, JSONSerializable, Mo @Override public boolean placeItem(Item item) { - if (requiredItems.containsKey(item.getId()) && requiredItems.get(item.getId()) > 0) { + if (canPlaceItem(item.getId())) { requiredItems.put(item.getId(), requiredItems.get(item.getId()) - 1); checkCompleted(); return true; @@ -65,6 +73,11 @@ public abstract class BluePrint implements InventoryHolder, JSONSerializable, Mo return false; } + @Override + public boolean canPlaceItem(int itemId) { + return requiredItems.containsKey(itemId) && requiredItems.get(itemId) > 0; + } + @Override public void takeItem(int itemId) { @@ -92,7 +105,7 @@ public abstract class BluePrint implements InventoryHolder, JSONSerializable, Mo public JSONObject jsonSerialise() { JSONObject json = new JSONObject(); - json.put("target", targetObject); + json.put("target", targetObject.getName()); json.put("required_items", requiredItems); return json; @@ -103,8 +116,15 @@ public abstract class BluePrint implements InventoryHolder, JSONSerializable, Mo Document document = new Document(); document.put("completed", completed); - document.put("target", targetObject); - document.put("required_items", requiredItems); + document.put("target", targetObject.getName()); + document.put("type", this.getClass().getName()); + + Map bsonCompatibleRequiredItems = new HashMap<>(); + for (Integer key : requiredItems.keySet()) { + bsonCompatibleRequiredItems.put(String.valueOf(key), requiredItems.get(key)); + } + + document.put("required_items", bsonCompatibleRequiredItems); return document; } diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintRegistry.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintRegistry.java index 15e57ba..8bb63c3 100644 --- a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintRegistry.java +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintRegistry.java @@ -9,7 +9,7 @@ import java.util.Map; public class BluePrintRegistry { - public static final BluePrintRegistry INSTANCE = new BluePrintRegistry(); + static final BluePrintRegistry INSTANCE = new BluePrintRegistry(); private Map> blueprints; private Map digitizedBlueprints; @@ -19,13 +19,13 @@ public class BluePrintRegistry { digitizedBlueprints = new HashMap<>(); } - public void registerBluePrint(Class clazz) { + void registerBluePrint(Class clazz) { blueprints.put(clazz.getCanonicalName(), clazz); String bpData = new String(BluePrintUtil.bluePrintData(clazz)); digitizedBlueprints.put(bpData, clazz.getCanonicalName()); } - public BluePrint deserializeBlueprint(Document document) { + BluePrint deserializeBlueprint(Document document) { String type = document.getString("type"); @@ -48,7 +48,7 @@ public class BluePrintRegistry { } } - public BluePrint deserializeBluePrint(char[] chars) { + BluePrint deserializeBluePrint(char[] chars) { String bpData = new String(chars); diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintUtil.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintUtil.java index f3052d7..f0eef04 100644 --- a/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintUtil.java +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/BluePrintUtil.java @@ -52,7 +52,7 @@ class BluePrintUtil { char[] result = new char[ARBITRARY_STRING.length * 32]; - for (int i = ARBITRARY_STRING.length - 1; i > 0; --i) { + for (int i = ARBITRARY_STRING.length - 1; i >= 0; --i) { char[] hashedBlueprint = hashMessage(ARBITRARY_STRING[i] + blueprint.getName()); if (hashedBlueprint != null) { System.arraycopy(hashedBlueprint, 0, result, diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionArmHardware.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionArmHardware.java new file mode 100644 index 0000000..e97e4cc --- /dev/null +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionArmHardware.java @@ -0,0 +1,88 @@ +package net.simon987.constructionplugin; + +import net.simon987.server.assembly.HardwareModule; +import net.simon987.server.assembly.Register; +import net.simon987.server.assembly.Status; +import net.simon987.server.game.objects.ControllableUnit; +import net.simon987.server.game.objects.GameObject; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.awt.*; + +public class ConstructionArmHardware extends HardwareModule { + + public static final char HWID = 0x0010; + + public static final int DEFAULT_ADDRESS = 0x0010; + + private static final int ERR_TILE_BLOCKED = 1; + private static final int ERR_NOT_ENOUGH_ENERGY = 2; + private static final int ERR_MEM_READ = 3; + private static final int ERR_INVALID_BLUEPRINT = 4; + + private static final int PLACE_CONSTRUCTION_SITE = 1; + private static final int PLACE_CONSTRUCTION_SITE_COST = 10; + + + public ConstructionArmHardware(ControllableUnit unit) { + super(null, unit); + } + + public ConstructionArmHardware(Document document, ControllableUnit unit) { + super(document, unit); + } + + @Override + public void handleInterrupt(Status status) { + + int a = getCpu().getRegisterSet().getRegister("A").getValue(); + int x = getCpu().getRegisterSet().getRegister("X").getValue(); + Register regB = getCpu().getRegisterSet().getRegister("B"); + + if (a == PLACE_CONSTRUCTION_SITE) { + System.out.println("DEBUG PLACE CONTRUCTION SITE"); + + char[] bluePrintData = getCpu().getMemory().read(x, BluePrint.DATA_LENGTH); + + if (bluePrintData == null) { + regB.setValue(ERR_MEM_READ); + return; + } + + BluePrint bluePrint = BluePrintRegistry.INSTANCE.deserializeBluePrint(bluePrintData); + if (bluePrint == null) { + regB.setValue(ERR_INVALID_BLUEPRINT); + return; + } + + Point frontTile = unit.getFrontTile(); + + if (unit.getWorld().isTileBlocked(frontTile.x, frontTile.y)) { + regB.setValue(ERR_TILE_BLOCKED); + return; + } + + if (!unit.spendEnergy(PLACE_CONSTRUCTION_SITE_COST)) { + regB.setValue(ERR_NOT_ENOUGH_ENERGY); + return; + } + + GameObject constructionSite = new ConstructionSite(bluePrint); + constructionSite.setX(frontTile.x); + constructionSite.setY(frontTile.y); + constructionSite.setObjectId(new ObjectId()); + + unit.getWorld().addObject(constructionSite); + regB.setValue(0); + + System.out.println("OK"); + } + } + + @Override + public char getId() { + return HWID; + } +} + diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionPlugin.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionPlugin.java index d11666c..23912b4 100644 --- a/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionPlugin.java +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionPlugin.java @@ -1,5 +1,6 @@ package net.simon987.constructionplugin; +import net.simon987.constructionplugin.event.CpuInitialisationListener; import net.simon987.server.GameServer; import net.simon987.server.game.objects.GameRegistry; import net.simon987.server.logging.LogManager; @@ -17,8 +18,12 @@ public class ConstructionPlugin extends ServerPlugin { gameRegistry.registerGameObject(Obstacle.class); gameRegistry.registerGameObject(ConstructionSite.class); + gameRegistry.registerHardware(ConstructionArmHardware.class); + BluePrintRegistry.INSTANCE.registerBluePrint(ObstacleBlueprint.class); + listeners.add(new CpuInitialisationListener()); + LogManager.LOGGER.info("(Construction Plugin) Initialized construction plugin"); } } diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionSite.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionSite.java index 84dc8bb..76e4e10 100644 --- a/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionSite.java +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/ConstructionSite.java @@ -50,6 +50,11 @@ public class ConstructionSite extends Structure implements Updatable, InventoryH return bluePrint.placeItem(item); } + @Override + public boolean canPlaceItem(int itemId) { + return bluePrint.canPlaceItem(itemId); + } + @Override public void takeItem(int itemId) { //NOOP diff --git a/plugin-contruction/src/main/java/net/simon987/constructionplugin/event/CpuInitialisationListener.java b/plugin-contruction/src/main/java/net/simon987/constructionplugin/event/CpuInitialisationListener.java new file mode 100644 index 0000000..3e174f0 --- /dev/null +++ b/plugin-contruction/src/main/java/net/simon987/constructionplugin/event/CpuInitialisationListener.java @@ -0,0 +1,27 @@ +package net.simon987.constructionplugin.event; + +import net.simon987.constructionplugin.ConstructionArmHardware; +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.game.objects.ControllableUnit; + +public class CpuInitialisationListener implements GameEventListener { + @Override + public Class getListenedEventType() { + return CpuInitialisationEvent.class; + } + + @Override + public void handle(GameEvent event) { + + CPU cpu = (CPU) event.getSource(); + ControllableUnit unit = ((CpuInitialisationEvent) event).getUnit(); + + ConstructionArmHardware constructionArmHardware = new ConstructionArmHardware(unit); + constructionArmHardware.setCpu(cpu); + + unit.attachHardware(constructionArmHardware, ConstructionArmHardware.DEFAULT_ADDRESS); + } +}