mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-10-28 06:56:53 +00:00 
			
		
		
		
	NPC Plugin rewrite.
Plugin-level data can be stored in DB
This commit is contained in:
		
							parent
							
								
									70eeb1442d
								
							
						
					
					
						commit
						94b8ef5395
					
				| @ -67,7 +67,7 @@ public class CubotComPort extends CubotHardwareModule { | |||||||
| 
 | 
 | ||||||
|         } else if (a == COMPORT_FRONT_PORT_OUT) { |         } else if (a == COMPORT_FRONT_PORT_OUT) { | ||||||
| 
 | 
 | ||||||
|             if (cubot.spendEnergy(20)) { |             if (cubot.spendEnergy(5)) { | ||||||
|                 //Get object directly in front of the Cubot |                 //Get object directly in front of the Cubot | ||||||
|                 Point frontTile = cubot.getFrontTile(); |                 Point frontTile = cubot.getFrontTile(); | ||||||
|                 //Todo will have to add getGameObjectsBlockingAt to enable Factory |                 //Todo will have to add getGameObjectsBlockingAt to enable Factory | ||||||
|  | |||||||
| @ -7,8 +7,6 @@ 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.List; |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Game objects that regularly creates NonPlayerCharacters |  * Game objects that regularly creates NonPlayerCharacters | ||||||
| @ -27,35 +25,17 @@ 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; | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 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 |  | ||||||
|      */ |  | ||||||
|     private boolean initialised = false; |  | ||||||
| 
 |  | ||||||
|     public Factory() { |     public Factory() { | ||||||
|         super(2, 2); |         super(2, 2); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     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,26 +50,10 @@ 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; |  | ||||||
| 
 |  | ||||||
|             for (Object id : tmpNpcArray) { |  | ||||||
| 
 |  | ||||||
|                 NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((ObjectId) id); |  | ||||||
| 
 |  | ||||||
|                 if (npc != null) { |  | ||||||
|                     npc.setFactory(this); |  | ||||||
|                     npcs.add(npc); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             tmpNpcArray = null; |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
| 
 | 
 | ||||||
|         if (cooldown == 0) { |         if (cooldown == 0) { | ||||||
|                 if (npcs.size() < MAX_NPC_COUNT) { |             if (settlement.getNpcs().size() < MAX_NPC_COUNT) { | ||||||
|                 Point p = getAdjacentTile(); |                 Point p = getAdjacentTile(); | ||||||
| 
 | 
 | ||||||
|                 if (p != null) { |                 if (p != null) { | ||||||
| @ -100,9 +64,8 @@ public class Factory extends Structure implements Updatable { | |||||||
|                     npc.setY(p.y); |                     npc.setY(p.y); | ||||||
|                     getWorld().addObject(npc); |                     getWorld().addObject(npc); | ||||||
|                     getWorld().incUpdatable(); |                     getWorld().incUpdatable(); | ||||||
|                         npc.setFactory(this); |  | ||||||
| 
 | 
 | ||||||
|                         npcs.add(npc); |                     settlement.addNpc(npc); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -112,24 +75,4 @@ public class Factory extends Structure implements Updatable { | |||||||
|             cooldown--; |             cooldown--; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         List<ObjectId> tmpNpcArray = new ArrayList<>(npcs.size()); |  | ||||||
| 
 |  | ||||||
|         for (NonPlayerCharacter npc : npcs) { |  | ||||||
|             tmpNpcArray.add(npc.getObjectId()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         dbObject.put("npcs", tmpNpcArray); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     ArrayList<NonPlayerCharacter> getNpcs() { |  | ||||||
|         return npcs; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ public class HarvesterNPC extends NonPlayerCharacter { | |||||||
| 
 | 
 | ||||||
|         super.update(); |         super.update(); | ||||||
| 
 | 
 | ||||||
|         if (getFactory() != null) { |         if (getSettlement() != null) { | ||||||
|             if (getTask().checkCompleted()) { |             if (getTask().checkCompleted()) { | ||||||
| 
 | 
 | ||||||
|                 setTask(new HarvestTask()); |                 setTask(new HarvestTask()); | ||||||
| @ -54,8 +54,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,10 +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 |      * If set to true, the NPC will be destroyed next tick if it is | ||||||
| @ -93,8 +90,8 @@ 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) { |             if (selfDestroyNextTick) { | ||||||
|                 setDead(true); |                 setDead(true); | ||||||
|             } |             } | ||||||
| @ -147,7 +144,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 +156,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 +167,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 +178,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 +251,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; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,15 +11,14 @@ 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.util.Map; | ||||||
|  | import java.util.concurrent.ConcurrentHashMap; | ||||||
| 
 | 
 | ||||||
| public class NpcPlugin extends ServerPlugin { | public class NpcPlugin extends ServerPlugin { | ||||||
| 
 | 
 | ||||||
|     /** |     public static Map<String, Settlement> settlementMap; | ||||||
|      * Radio tower cache |  | ||||||
|      */ |  | ||||||
|     private static ArrayList<RadioTower> radioTowers; |  | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void init(GameServer gameServer) { |     public void init(GameServer gameServer) { | ||||||
| @ -46,13 +45,35 @@ public class NpcPlugin extends ServerPlugin { | |||||||
|         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.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 | ||||||
|  | |||||||
							
								
								
									
										219
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								Plugin NPC/src/main/java/net/simon987/npcplugin/Settlement.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,219 @@ | |||||||
|  | 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 { | ||||||
|  | 
 | ||||||
|  |         System.out.println("SETTLING"); | ||||||
|  | 
 | ||||||
|  |         this.world = world; | ||||||
|  |         this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ? | ||||||
|  | 
 | ||||||
|  |         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(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(); | ||||||
|  |             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", "1234567"); //todo | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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,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,13 @@ 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++) { |                 NpcPlugin.settlementMap.put(world.getId(), new Settlement(world)); | ||||||
|                 for (int y = 2; y < 12; y++) { |             } catch (WorldGenerationException e) { | ||||||
| 
 |                 LogManager.LOGGER.fine(String.format("Exception during settlement generation: %s.", | ||||||
|                     if ((!world.isTileBlocked(x, y) && !world.isTileBlocked(x + 1, y) && |                         e.getMessage())); | ||||||
|                             !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(); |  | ||||||
| 
 |  | ||||||
| //                        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 + ")"); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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() + ")"); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -18,6 +18,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; | ||||||
| @ -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() + | ||||||
| @ -267,6 +275,13 @@ 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); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -115,6 +115,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; | ||||||
|  | |||||||
| @ -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"))); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -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\ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user