Browse Source

Merge remote-tracking branch 'origin/magicbox-1.5.2' into feature-workorder

feature-workorder
MagicBot 1 year ago
parent
commit
db015f7007
  1. 8
      src/engine/Enum.java
  2. 463
      src/engine/InterestManagement/HeightMap.java
  3. 226
      src/engine/InterestManagement/Terrain.java
  4. 2
      src/engine/db/archive/CityRecord.java
  5. 2
      src/engine/db/archive/MineRecord.java
  6. 2
      src/engine/db/archive/PvpRecord.java
  7. 85
      src/engine/db/handlers/dbBuildingHandler.java
  8. 6
      src/engine/db/handlers/dbCityHandler.java
  9. 43
      src/engine/db/handlers/dbHeightMapHandler.java
  10. 37
      src/engine/db/handlers/dbMobHandler.java
  11. 7
      src/engine/db/handlers/dbNPCHandler.java
  12. 75
      src/engine/db/handlers/dbZoneHandler.java
  13. 2
      src/engine/devcmd/cmds/AddMobCmd.java
  14. 6
      src/engine/devcmd/cmds/AuditMobsCmd.java
  15. 48
      src/engine/devcmd/cmds/GetHeightCmd.java
  16. 2
      src/engine/devcmd/cmds/GetOffsetCmd.java
  17. 2
      src/engine/devcmd/cmds/GetZoneCmd.java
  18. 6
      src/engine/devcmd/cmds/GotoCmd.java
  19. 4
      src/engine/devcmd/cmds/HotzoneCmd.java
  20. 4
      src/engine/devcmd/cmds/InfoCmd.java
  21. 6
      src/engine/devcmd/cmds/MakeBaneCmd.java
  22. 67
      src/engine/devcmd/cmds/PrintEffectsCmd.java
  23. 67
      src/engine/devcmd/cmds/PrintRunesCmd.java
  24. 2
      src/engine/devcmd/cmds/PurgeObjectsCmd.java
  25. 6
      src/engine/devcmd/cmds/RealmInfoCmd.java
  26. 51
      src/engine/devcmd/cmds/RegionCmd.java
  27. 4
      src/engine/devcmd/cmds/RemoveBaneCmd.java
  28. 2
      src/engine/devcmd/cmds/RemoveObjectCmd.java
  29. 4
      src/engine/devcmd/cmds/SetBaneActiveCmd.java
  30. 4
      src/engine/devcmd/cmds/SetForceRenameCityCmd.java
  31. 7
      src/engine/devcmd/cmds/SetRankCmd.java
  32. 2
      src/engine/devcmd/cmds/SummonCmd.java
  33. 37
      src/engine/devcmd/cmds/ZoneInfoCmd.java
  34. 2
      src/engine/devcmd/cmds/ZoneSetCmd.java
  35. 135
      src/engine/gameManager/BuildingManager.java
  36. 1
      src/engine/gameManager/DbManager.java
  37. 3
      src/engine/gameManager/DevCmdManager.java
  38. 4
      src/engine/gameManager/LootManager.java
  39. 28
      src/engine/gameManager/MovementManager.java
  40. 16
      src/engine/gameManager/NPCManager.java
  41. 6
      src/engine/gameManager/PowersManager.java
  42. 198
      src/engine/gameManager/ZoneManager.java
  43. 2
      src/engine/jobs/FinishSummonsJob.java
  44. 3
      src/engine/jobs/UpgradeBuildingJob.java
  45. 5
      src/engine/math/Bounds.java
  46. 31
      src/engine/mobileAI/MobAI.java
  47. 6
      src/engine/mobileAI/utilities/MovementUtilities.java
  48. 6
      src/engine/net/client/ClientMessagePump.java
  49. 2
      src/engine/net/client/handlers/AbandonAssetMsgHandler.java
  50. 2
      src/engine/net/client/handlers/AssetSupportMsgHandler.java
  51. 2
      src/engine/net/client/handlers/ChannelMuteMsgHandler.java
  52. 4
      src/engine/net/client/handlers/ClaimGuildTreeMsgHandler.java
  53. 2
      src/engine/net/client/handlers/DestroyBuildingHandler.java
  54. 6
      src/engine/net/client/handlers/ManageCityAssetMsgHandler.java
  55. 4
      src/engine/net/client/handlers/ObjectActionMsgHandler.java
  56. 6
      src/engine/net/client/handlers/OpenFriendsCondemnListMsgHandler.java
  57. 2
      src/engine/net/client/handlers/OrderNPCMsgHandler.java
  58. 77
      src/engine/net/client/handlers/PlaceAssetMsgHandler.java
  59. 4
      src/engine/net/client/handlers/RepairBuildingMsgHandler.java
  60. 1
      src/engine/net/client/handlers/RequestEnterWorldHandler.java
  61. 2
      src/engine/net/client/msg/CityAssetMsg.java
  62. 4
      src/engine/net/client/msg/GuildTreeStatusMsg.java
  63. 12
      src/engine/net/client/msg/ManageCityAssetsMsg.java
  64. 48
      src/engine/net/client/msg/OpenFriendsCondemnListMsg.java
  65. 151
      src/engine/net/client/msg/SyncMessage.java
  66. 2
      src/engine/net/client/msg/ViewResourcesMessage.java
  67. 17
      src/engine/net/client/msg/WorldDataMsg.java
  68. 42
      src/engine/objects/AbstractCharacter.java
  69. 2
      src/engine/objects/AbstractIntelligenceAgent.java
  70. 13
      src/engine/objects/AbstractWorldObject.java
  71. 7
      src/engine/objects/Bane.java
  72. 402
      src/engine/objects/Building.java
  73. 20
      src/engine/objects/BuildingFriends.java
  74. 180
      src/engine/objects/City.java
  75. 47
      src/engine/objects/Condemned.java
  76. 62
      src/engine/objects/Guild.java
  77. 4
      src/engine/objects/ItemFactory.java
  78. 4
      src/engine/objects/Mine.java
  79. 22
      src/engine/objects/Mob.java
  80. 10
      src/engine/objects/NPC.java
  81. 81
      src/engine/objects/PlayerCharacter.java
  82. 3
      src/engine/objects/Portal.java
  83. 82
      src/engine/objects/Realm.java
  84. 9
      src/engine/objects/Regions.java
  85. 2
      src/engine/objects/Runegate.java
  86. 2
      src/engine/objects/Warehouse.java
  87. 336
      src/engine/objects/Zone.java
  88. 59
      src/engine/objects/ZoneTemplate.java
  89. 2
      src/engine/powers/poweractions/CreateMobPowerAction.java
  90. 2
      src/engine/powers/poweractions/MobRecallPowerAction.java
  91. 2
      src/engine/powers/poweractions/RecallPowerAction.java
  92. 2
      src/engine/powers/poweractions/SummonPowerAction.java
  93. 2
      src/engine/powers/poweractions/TeleportPowerAction.java
  94. 24
      src/engine/server/login/LoginServerMsgHandler.java
  95. 151
      src/engine/server/world/WorldServer.java
  96. 55
      src/engine/util/MapLoader.java
  97. 7
      src/engine/workthreads/DestroyCityThread.java
  98. 8
      src/engine/workthreads/HourlyJobThread.java
  99. 2
      src/engine/workthreads/TransferCityThread.java

8
src/engine/Enum.java

@ -469,7 +469,7 @@ public class Enum {
// 14001 does not have a banestone to bind at // 14001 does not have a banestone to bind at
if (ruinZone.getLoadNum() == 14001) if (ruinZone.templateID == 14001)
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30); spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
else else
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc() spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
@ -2310,10 +2310,10 @@ public class Enum {
ZONE(875), ZONE(875),
PLACEMENT(876); PLACEMENT(876);
public final float extents; public final float halfExtents;
CityBoundsType(float extents) { CityBoundsType(float halfExtents) {
this.extents = extents; this.halfExtents = halfExtents;
} }
} }

463
src/engine/InterestManagement/HeightMap.java

@ -1,463 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.InterestManagement;
import engine.Enum;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
public class HeightMap {
// Class variables
// Heightmap data for all zones.
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
// Bootstrap Tracking
public static int heightMapsCreated = 0;
public static HeightMap PlayerCityHeightMap;
// Heightmap data for this heightmap
public BufferedImage heightmapImage;
private int heightMapID;
private int maxHeight;
private int fullExtentsX;
private int fullExtentsY;
private float bucketWidthX;
private float bucketWidthY;
private int zoneLoadID;
private float seaLevel = 0;
private float outsetX;
private float outsetZ;
private int[][] pixelColorValues;
public HeightMap(ResultSet rs) throws SQLException {
this.heightMapID = rs.getInt("heightMapID");
this.maxHeight = rs.getInt("maxHeight");
int halfExtentsX = rs.getInt("xRadius");
int halfExtentsY = rs.getInt("zRadius");
this.zoneLoadID = rs.getInt("zoneLoadID");
this.seaLevel = rs.getFloat("seaLevel");
this.outsetX = rs.getFloat("outsetX");
this.outsetZ = rs.getFloat("outsetZ");
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
this.heightmapImage = null;
File imageFile = new File(ConfigManager.DEFAULT_DATA_DIR + "heightmaps/" + this.heightMapID + ".bmp");
// early exit if no image file was found. Will log in caller.
if (!imageFile.exists())
return;
// load the heightmap image.
try {
this.heightmapImage = ImageIO.read(imageFile);
} catch (IOException e) {
Logger.error("***Error loading heightmap data for heightmap " + this.heightMapID + e.toString());
}
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
// this.heightmapImage = MapLoader.flipImage(this.heightmapImage);
// Calculate the data we do not load from table
float numOfBuckets = this.heightmapImage.getWidth() - 1;
float calculatedWidth = this.fullExtentsX / numOfBuckets;
this.bucketWidthX = calculatedWidth;
this.bucketWidthY = this.bucketWidthX; // This makes no sense.
// Generate pixel array from image data
generatePixelData();
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
heightMapsCreated++;
}
//Created for PlayerCities
public HeightMap() {
this.heightMapID = 999999;
this.maxHeight = 5; // for real...
int halfExtentsX = (int) Enum.CityBoundsType.ZONE.extents;
int halfExtentsY = (int) Enum.CityBoundsType.ZONE.extents;
this.zoneLoadID = 0;
this.seaLevel = 0;
this.outsetX = 128;
this.outsetZ = 128;
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = halfExtentsX;
this.bucketWidthY = halfExtentsY;
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
for (int y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255;
}
}
}
public HeightMap(Zone zone) {
this.heightMapID = 999999;
this.maxHeight = 0;
int halfExtentsX = (int) zone.getBounds().getHalfExtents().x;
int halfExtentsY = (int) zone.getBounds().getHalfExtents().y;
this.zoneLoadID = 0;
this.seaLevel = 0;
this.outsetX = 0;
this.outsetZ = 0;
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = halfExtentsX;
this.bucketWidthY = halfExtentsY;
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
for (int y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 0;
}
}
}
public static void GeneratePlayerCityHeightMap() {
HeightMap.PlayerCityHeightMap = new HeightMap();
}
public static void GenerateCustomHeightMap(Zone zone) {
HeightMap heightMap = new HeightMap(zone);
HeightMap.heightmapByLoadNum.put(zone.getLoadNum(), heightMap);
}
public static Zone getNextZoneWithTerrain(Zone zone) {
Zone nextZone = zone;
if (zone.getHeightMap() != null)
return zone;
if (zone.equals(ZoneManager.getSeaFloor()))
return zone;
while (nextZone.getHeightMap() == null)
nextZone = nextZone.getParent();
return nextZone;
}
public static float getWorldHeight(Zone currentZone, Vector3fImmutable worldLoc) {
Vector2f parentLoc = new Vector2f(-1, -1);
if (currentZone == null)
return 0;
currentZone = getNextZoneWithTerrain(currentZone);
if (currentZone == ZoneManager.getSeaFloor())
return currentZone.getAbsY();
Zone parentZone = getNextZoneWithTerrain(currentZone.getParent());
HeightMap heightMap = currentZone.getHeightMap();
if ((heightMap == null) || (currentZone == ZoneManager.getSeaFloor()))
return currentZone.getAbsY();
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(worldLoc, currentZone);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldLoc, currentZone);
if ((parentZone != null) && (parentZone.getHeightMap() != null))
parentLoc = ZoneManager.worldToZoneSpace(worldLoc, parentZone);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.worldAltitude;
float realWorldAltitude = interaltitude + worldAltitude;
//OUTSET
if (parentZone != null) {
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = heightMap.outsetX / parentXRadius;
float bucketScaleZ = heightMap.outsetZ / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt;
}
}
return realWorldAltitude;
}
public static float getWorldHeight(Vector3fImmutable worldLoc) {
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
if (currentZone == null)
return 0;
return getWorldHeight(currentZone, worldLoc);
}
public static void loadAlHeightMaps() {
// Load the heightmaps into staging hashmap keyed by HashMapID
DbManager.HeightMapQueries.LOAD_ALL_HEIGHTMAPS();
//generate static player city heightmap.
HeightMap.GeneratePlayerCityHeightMap();
// Clear all heightmap image data as it's no longer needed.
for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) {
heightMap.heightmapImage = null;
}
Logger.info(HeightMap.heightmapByLoadNum.size() + " Heightmaps cached.");
}
public static boolean isLocUnderwater(Vector3fImmutable currentLoc) {
float localAltitude = HeightMap.getWorldHeight(currentLoc);
Zone zone = ZoneManager.findSmallestZone(currentLoc);
if (localAltitude < zone.getSeaLevel())
return true;
return false;
}
public Vector2f getGridSquare(Vector2f zoneLoc) {
if (zoneLoc.x < 0)
zoneLoc.setX(0);
if (zoneLoc.x >= this.fullExtentsX)
zoneLoc.setX(this.fullExtentsX);
if (zoneLoc.y < 0)
zoneLoc.setY(0);
if (zoneLoc.y > this.fullExtentsY)
zoneLoc.setY(this.fullExtentsY);
// Flip Y coordinates
zoneLoc.setY(this.fullExtentsY - zoneLoc.y);
float xBucket = (zoneLoc.x / this.bucketWidthX);
float yBucket = (zoneLoc.y / this.bucketWidthY);
return new Vector2f(xBucket, yBucket);
}
public float getInterpolatedTerrainHeight(Vector2f zoneLoc) {
Vector2f gridSquare;
if (zoneLoc.x < 0 || zoneLoc.x > this.fullExtentsX)
return -1;
if (zoneLoc.y < 0 || zoneLoc.y > this.fullExtentsY)
return -1;
int maxX = (int) (this.fullExtentsX / this.bucketWidthX);
int maxY = (int) (this.fullExtentsY / this.bucketWidthY);
gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x;
int gridY = (int) gridSquare.y;
if (gridX > maxX)
gridX = maxX;
if (gridY > maxY)
gridY = maxY;
float offsetX = (gridSquare.x - gridX);
float offsetY = gridSquare.y - gridY;
//get height of the 4 vertices.
float topLeftHeight = 0;
float topRightHeight = 0;
float bottomLeftHeight = 0;
float bottomRightHeight = 0;
int nextY = gridY + 1;
int nextX = gridX + 1;
if (nextY > maxY)
nextY = gridY;
if (nextX > maxX)
nextX = gridX;
topLeftHeight = pixelColorValues[gridX][gridY];
topRightHeight = pixelColorValues[nextX][gridY];
bottomLeftHeight = pixelColorValues[gridX][nextY];
bottomRightHeight = pixelColorValues[nextX][nextY];
float interpolatedHeight;
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height
return interpolatedHeight;
}
private void generatePixelData() {
Color color;
// Generate altitude lookup table for this heightmap
this.pixelColorValues = new int[this.heightmapImage.getWidth()][this.heightmapImage.getHeight()];
for (int y = 0; y < this.heightmapImage.getHeight(); y++) {
for (int x = 0; x < this.heightmapImage.getWidth(); x++) {
color = new Color(this.heightmapImage.getRGB(x, y));
pixelColorValues[x][y] = color.getRed();
}
}
}
public float getBucketWidthX() {
return bucketWidthX;
}
public float getBucketWidthY() {
return bucketWidthY;
}
public int getHeightMapID() {
return heightMapID;
}
public BufferedImage getHeightmapImage() {
return heightmapImage;
}
public float getSeaLevel() {
return seaLevel;
}
}

226
src/engine/InterestManagement/Terrain.java

@ -0,0 +1,226 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.InterestManagement;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.HashMap;
import static java.lang.Math.PI;
public class Terrain {
public static final HashMap<Integer, short[][]> _heightmap_pixel_cache = new HashMap<>();
public short[][] terrain_pixel_data;
public Vector2f terrain_size = new Vector2f();
public Vector2f cell_size = new Vector2f();
public Vector2f cell_count = new Vector2f();
public float terrain_scale;
public Vector2f blend_ratio = new Vector2f();
public int heightmap;
Zone zone;
public Terrain(Zone zone) {
this.zone = zone;
this.heightmap = this.zone.template.terrain_image;
// Configure PLANAR zones to use the same 16x16 pixel image
// that all similar terrains share. (See JSON)
if (this.zone.template.terrain_type.equals("PLANAR"))
this.heightmap = 1006300; // all 0
// Load pixel data for this terrain from cache
this.terrain_pixel_data = Terrain._heightmap_pixel_cache.get(heightmap);
if (terrain_pixel_data == null)
Logger.error("Pixel map empty for zone: " + this.zone.getObjectUUID() + ":" + this.zone.zoneName);
// Configure terrain based on zone properties
this.terrain_size.x = this.zone.major_radius * 2;
this.terrain_size.y = this.zone.minor_radius * 2;
this.cell_count.x = this.terrain_pixel_data.length - 1;
this.cell_count.y = this.terrain_pixel_data[0].length - 1;
this.cell_size.x = terrain_size.x / this.cell_count.x;
this.cell_size.y = terrain_size.y / this.cell_count.y;
// Blending configuration. These ratios are used to calculate
// the blending area between child and parent terrains when
// they are stitched together.
Vector2f major_blend = new Vector2f(this.zone.template.max_blend / this.zone.major_radius,
this.zone.template.min_blend / this.zone.major_radius);
Vector2f minor_blend = new Vector2f(this.zone.template.max_blend / this.zone.minor_radius,
this.zone.template.min_blend / this.zone.minor_radius);
if (major_blend.y > 0.4f)
blend_ratio.x = major_blend.y;
else
blend_ratio.x = Math.min(major_blend.x, 0.4f);
if (minor_blend.y > 0.4f)
blend_ratio.y = minor_blend.y;
else
blend_ratio.y = Math.min(minor_blend.x, 0.4f);
// Scale coefficient for this terrain
this.terrain_scale = this.zone.template.terrain_max_y / 255f;
}
public static Zone getNextZoneWithTerrain(Zone zone) {
// Not all zones have a terrain. Some are for display only
// and heights returned are from the parent heightmap. This
// is controlled in the JSON via the has_terrain_gen field.
Zone terrain_zone = zone;
if (zone == null)
return ZoneManager.seaFloor;
if (zone.terrain != null)
return zone;
if (zone.equals(ZoneManager.seaFloor))
return zone;
while (terrain_zone.terrain == null)
terrain_zone = terrain_zone.parent;
return terrain_zone;
}
public static float getWorldHeight(Zone zone, Vector3fImmutable world_loc) {
// Retrieve the next zone with a terrain defined.
Zone terrainZone = getNextZoneWithTerrain(zone);
Zone parentZone = getNextZoneWithTerrain(zone.parent);
// Transform world loc into zone space coordinate system
Vector2f terrainLoc = ZoneManager.worldToTerrainSpace(world_loc, terrainZone);
Vector2f parentLoc = ZoneManager.worldToTerrainSpace(world_loc, parentZone);
// Offset from origin needed for blending function
Vector2f terrainOffset = ZoneManager.worldToZoneOffset(world_loc, terrainZone);
// Interpolate height for this position in both terrains
float interpolatedChildHeight = terrainZone.terrain.getInterpolatedTerrainHeight(terrainLoc);
interpolatedChildHeight += terrainZone.global_height;
float interpolatedParentTerrainHeight = parentZone.terrain.getInterpolatedTerrainHeight(parentLoc);
interpolatedParentTerrainHeight += parentZone.global_height;
// Blend between terrains
float blendCoefficient = terrainZone.terrain.getTerrainBlendCoefficient(terrainOffset);
float terrainHeight = interpolatedChildHeight * blendCoefficient;
terrainHeight += interpolatedParentTerrainHeight * (1 - blendCoefficient);
return terrainHeight;
}
public static float getWorldHeight(Vector3fImmutable world_loc) {
Zone currentZone = ZoneManager.findSmallestZone(world_loc);
return getWorldHeight(currentZone, world_loc);
}
public Vector2f getTerrainCell(Vector2f terrain_loc) {
// Calculate terrain cell with offset
Vector2f terrain_cell = new Vector2f(terrain_loc.x / this.cell_size.x, terrain_loc.y / this.cell_size.y);
// Clamp values when standing directly on pole
terrain_cell.x = Math.max(0, Math.min(this.cell_count.x - 1, terrain_cell.x));
terrain_cell.y = Math.max(0, Math.min(this.cell_count.y - 1, terrain_cell.y));
return terrain_cell;
}
public float getInterpolatedTerrainHeight(Vector2f terrain_loc) {
float interpolatedHeight;
// Early exit for guild zones
if (this.zone.guild_zone)
return 5.0f;
// Determine terrain and offset from top left vertex
Vector2f terrain_cell = getTerrainCell(terrain_loc);
int pixel_x = (int) Math.floor(terrain_cell.x);
int pixel_y = (int) Math.floor(terrain_cell.y);
Vector2f pixel_offset = new Vector2f(terrain_cell.x % 1, terrain_cell.y % 1);
// 4 surrounding vertices from the pixel array.
short top_left_pixel = terrain_pixel_data[pixel_x][pixel_y];
short top_right_pixel = terrain_pixel_data[pixel_x + 1][pixel_y];
short bottom_left_pixel = terrain_pixel_data[pixel_x][pixel_y + 1];
short bottom_right_pixel = terrain_pixel_data[pixel_x + 1][pixel_y + 1];
// Interpolate between the 4 vertices
interpolatedHeight = top_left_pixel * (1 - pixel_offset.x) * (1 - pixel_offset.y);
interpolatedHeight += top_right_pixel * (1 - pixel_offset.y) * (pixel_offset.x);
interpolatedHeight += (bottom_left_pixel * (1 - pixel_offset.x) * pixel_offset.y);
interpolatedHeight += (bottom_right_pixel * pixel_offset.y * pixel_offset.x);
interpolatedHeight *= this.terrain_scale; // Scale height
return interpolatedHeight;
}
public float getTerrainBlendCoefficient(Vector2f zone_offset) {
// Normalize terrain offset
Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.template.major_radius,
Math.abs(zone_offset.y) / this.zone.template.minor_radius);
float blendCoefficient;
if (normalizedOffset.x <= 1 - blend_ratio.x || normalizedOffset.x <= normalizedOffset.y) {
if (normalizedOffset.y < 1 - blend_ratio.y)
return 1;
blendCoefficient = (normalizedOffset.y - (1 - blend_ratio.y)) / blend_ratio.y;
} else
blendCoefficient = (normalizedOffset.x - (1 - blend_ratio.x)) / blend_ratio.x;
blendCoefficient = (float) Math.atan((0.5f - blendCoefficient) * PI);
return (blendCoefficient + 1) * 0.5f;
}
}

2
src/engine/db/archive/CityRecord.java

@ -67,7 +67,7 @@ public class CityRecord extends DataRecord {
cityRecord.locX = cityRecord.city.getTOL().getLoc().x; cityRecord.locX = cityRecord.city.getTOL().getLoc().x;
cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate
cityRecord.zoneHash = cityRecord.city.getParent().getHash(); cityRecord.zoneHash = cityRecord.city.getParent().hash;
if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE)) if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE))
cityRecord.establishedDatetime = cityRecord.city.established; cityRecord.establishedDatetime = cityRecord.city.established;

2
src/engine/db/archive/MineRecord.java

@ -52,7 +52,7 @@ public class MineRecord extends DataRecord {
mineRecord.eventType = eventType; mineRecord.eventType = eventType;
} }
mineRecord.zoneHash = mine.getParentZone().getHash(); mineRecord.zoneHash = mine.getParentZone().hash;
if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
player = (PlayerCharacter) character; player = (PlayerCharacter) character;

2
src/engine/db/archive/PvpRecord.java

@ -281,7 +281,7 @@ public class PvpRecord extends DataRecord {
outStatement.setInt(8, this.victim.getLevel()); outStatement.setInt(8, this.victim.getLevel());
outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID())); outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID()));
outStatement.setString(10, zone.getName()); outStatement.setString(10, zone.zoneName);
outStatement.setFloat(11, this.location.getX()); outStatement.setFloat(11, this.location.getX());
outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate
outStatement.setBoolean(13, this.pvpExp); outStatement.setBoolean(13, this.pvpExp);

85
src/engine/db/handlers/dbBuildingHandler.java

@ -13,6 +13,7 @@ import engine.Enum;
import engine.Enum.DbObjectType; import engine.Enum.DbObjectType;
import engine.Enum.ProtectionState; import engine.Enum.ProtectionState;
import engine.Enum.TaxType; import engine.Enum.TaxType;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.*; import engine.objects.*;
@ -27,6 +28,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class dbBuildingHandler extends dbHandlerBase { public class dbBuildingHandler extends dbHandlerBase {
@ -88,14 +90,12 @@ public class dbBuildingHandler extends dbHandlerBase {
return removeFromBuildings(b); return removeFromBuildings(b);
} }
public ArrayList<Building> GET_ALL_BUILDINGS_FOR_ZONE(Zone zone) { public ArrayList<Building> GET_ALL_BUILDINGS() {
ArrayList<Building> buildings = new ArrayList<>(); ArrayList<Building> buildings = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, zone.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
buildings = getObjectsFromRs(rs, 1000); buildings = getObjectsFromRs(rs, 1000);
@ -425,26 +425,28 @@ public class dbBuildingHandler extends dbHandlerBase {
return false; return false;
} }
public void LOAD_ALL_FRIENDS_FOR_BUILDING(Building building) { public void LOAD_BUILDING_FRIENDS() {
if (building == null)
return;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_friends` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_friends`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
BuildingFriends friend = new BuildingFriends(rs); BuildingFriends friend = new BuildingFriends(rs);
switch (friend.getFriendType()) {
// Create map if it does not yet exist
if (!BuildingManager._buildingFriends.containsKey(friend.buildingUID))
BuildingManager._buildingFriends.put(friend.buildingUID, new ConcurrentHashMap<>());
switch (friend.friendType) {
case 7: case 7:
building.getFriends().put(friend.getPlayerUID(), friend); BuildingManager._buildingFriends.get(friend.buildingUID).put(friend.playerUID, friend);
break; break;
case 8: case 8:
case 9: case 9:
building.getFriends().put(friend.getGuildUID(), friend); BuildingManager._buildingFriends.get(friend.buildingUID).put(friend.guildUID, friend);
break; break;
} }
} }
@ -455,26 +457,29 @@ public class dbBuildingHandler extends dbHandlerBase {
} }
public void LOAD_ALL_CONDEMNED_FOR_BUILDING(Building building) { public void LOAD_BUILDING_CONDEMNED() {
if (building == null)
return;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_condemned` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_condemned`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
Condemned condemned = new Condemned(rs); Condemned condemned = new Condemned(rs);
switch (condemned.getFriendType()) {
// Create map if it does not yet exist
if (!BuildingManager._buildingCondemned.containsKey(condemned.buildingUUID))
BuildingManager._buildingCondemned.put(condemned.buildingUUID, new ConcurrentHashMap<>());
switch (condemned.friendType) {
case 2: case 2:
building.getCondemned().put(condemned.getPlayerUID(), condemned); BuildingManager._buildingCondemned.get(condemned.buildingUUID).put(condemned.playerUID, condemned);
break; break;
case 4: case 4:
case 5: case 5:
building.getCondemned().put(condemned.getGuildUID(), condemned); BuildingManager._buildingCondemned.get(condemned.buildingUUID).put(condemned.guildUID, condemned);
break; break;
} }
} }
@ -484,35 +489,27 @@ public class dbBuildingHandler extends dbHandlerBase {
} }
} }
public ArrayList<Vector3fImmutable> LOAD_PATROL_POINTS(Building building) { public void LOAD_BARRACKS_PATROL_POINTS() {
if (building == null)
return null;
ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_patrol_points` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_patrol_points`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
float x1 = rs.getFloat("patrolX");
float y1 = rs.getFloat("patrolY"); int buildingUUID = rs.getInt("buildingUID");
float z1 = rs.getFloat("patrolZ");
Vector3fImmutable patrolPoint = new Vector3fImmutable(x1, y1, z1); if (!BuildingManager._buildingPatrolPoints.containsKey(buildingUUID))
patrolPoints.add(patrolPoint); BuildingManager._buildingPatrolPoints.put(buildingUUID, new ArrayList<>());
Vector3fImmutable patrolPoint = new Vector3fImmutable(rs.getFloat("patrolX"), rs.getFloat("patrolY"), rs.getFloat("patrolZ"));
BuildingManager._buildingPatrolPoints.get(buildingUUID).add(patrolPoint);
} }
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
return patrolPoints;
} }
public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) { public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) {
@ -722,10 +719,10 @@ public class dbBuildingHandler extends dbHandlerBase {
+ "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?")) { + "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?")) {
preparedStatement.setBoolean(1, active); preparedStatement.setBoolean(1, active);
preparedStatement.setInt(2, condemn.getParent()); preparedStatement.setInt(2, condemn.buildingUUID);
preparedStatement.setInt(3, condemn.getPlayerUID()); preparedStatement.setInt(3, condemn.playerUID);
preparedStatement.setInt(4, condemn.getGuildUID()); preparedStatement.setInt(4, condemn.guildUID);
preparedStatement.setInt(5, condemn.getFriendType()); preparedStatement.setInt(5, condemn.friendType);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);

6
src/engine/db/handlers/dbCityHandler.java

@ -96,14 +96,12 @@ public class dbCityHandler extends dbHandlerBase {
return objectList; return objectList;
} }
public ArrayList<City> GET_CITIES_BY_ZONE(final int objectUUID) { public ArrayList<City> GET_ALL_CITIES() {
ArrayList<City> cityList = new ArrayList<>(); ArrayList<City> cityList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`parent`=?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
cityList = getObjectsFromRs(rs, 100); cityList = getObjectsFromRs(rs, 100);

43
src/engine/db/handlers/dbHeightMapHandler.java

@ -1,43 +0,0 @@
package engine.db.handlers;
import engine.InterestManagement.HeightMap;
import engine.gameManager.DbManager;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class dbHeightMapHandler extends dbHandlerBase {
public dbHeightMapHandler() {
}
public void LOAD_ALL_HEIGHTMAPS() {
HeightMap thisHeightmap;
HeightMap.heightMapsCreated = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_zone_heightmap INNER JOIN static_zone_size ON static_zone_size.loadNum = static_zone_heightmap.zoneLoadID")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
thisHeightmap = new HeightMap(rs);
if (thisHeightmap.getHeightmapImage() == null) {
Logger.info("Imagemap for " + thisHeightmap.getHeightMapID() + " was null");
continue;
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
}

37
src/engine/db/handlers/dbMobHandler.java

@ -11,7 +11,6 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.Zone;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -65,6 +64,23 @@ public class dbMobHandler extends dbHandlerBase {
return mobile; return mobile;
} }
public ArrayList<Mob> GET_ALL_MOBS() {
ArrayList<Mob> mobileList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
ResultSet rs = preparedStatement.executeQuery();
mobileList = getObjectsFromRs(rs, 1000);
} catch (SQLException e) {
Logger.error(e);
}
return mobileList;
}
public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) { public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
@ -174,25 +190,6 @@ public class dbMobHandler extends dbHandlerBase {
} }
} }
public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) {
ArrayList<Mob> mobileList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) {
preparedStatement.setLong(1, zone.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
mobileList = getObjectsFromRs(rs, 1000);
} catch (SQLException e) {
Logger.error(e);
}
return mobileList;
}
public Mob GET_MOB(final int objectUUID) { public Mob GET_MOB(final int objectUUID) {
Mob mobile = null; Mob mobile = null;

7
src/engine/db/handlers/dbNPCHandler.java

@ -15,7 +15,6 @@ import engine.math.Vector3fImmutable;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.NPCProfits; import engine.objects.NPCProfits;
import engine.objects.ProducedItem; import engine.objects.ProducedItem;
import engine.objects.Zone;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -94,14 +93,12 @@ public class dbNPCHandler extends dbHandlerBase {
return row_count; return row_count;
} }
public ArrayList<NPC> GET_ALL_NPCS_FOR_ZONE(Zone zone) { public ArrayList<NPC> GET_ALL_NPCS() {
ArrayList<NPC> npcList = new ArrayList<>(); ArrayList<NPC> npcList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, zone.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
npcList = getObjectsFromRs(rs, 1000); npcList = getObjectsFromRs(rs, 1000);

75
src/engine/db/handlers/dbZoneHandler.java

@ -12,8 +12,8 @@ package engine.db.handlers;
import engine.Enum; import engine.Enum;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.objects.Zone; import engine.objects.Zone;
import engine.objects.ZoneTemplate;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@ -29,25 +29,21 @@ public class dbZoneHandler extends dbHandlerBase {
this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public ArrayList<Zone> GET_ALL_NODES(Zone zone) { public ArrayList<Zone> GET_ALL_ZONES() {
ArrayList<Zone> wsmList = new ArrayList<>();
wsmList.addAll(zone.getNodes()); ArrayList<Zone> zoneList = new ArrayList<>();
if (zone.absX == 0.0f) {
zone.absX = zone.getXCoord(); try (Connection connection = DbManager.getConnection();
} PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
if (zone.absY == 0.0f) {
zone.absY = zone.getYCoord(); ResultSet rs = preparedStatement.executeQuery();
} zoneList = getObjectsFromRs(rs, 2000);
if (zone.absZ == 0.0f) {
zone.absZ = zone.getZCoord(); } catch (SQLException e) {
} Logger.error(e);
for (Zone child : zone.getNodes()) {
child.absX = child.getXCoord() + zone.absX;
child.absY = child.getYCoord() + zone.absY;
child.absZ = child.getZCoord() + zone.absZ;
wsmList.addAll(this.GET_ALL_NODES(child));
} }
return wsmList;
return zoneList;
} }
public Zone GET_BY_UID(long ID) { public Zone GET_BY_UID(long ID) {
@ -72,43 +68,38 @@ public class dbZoneHandler extends dbHandlerBase {
return zone; return zone;
} }
public ArrayList<Zone> GET_MAP_NODES(final int objectUUID) { public void LOAD_ALL_ZONE_TEMPLATES() {
ArrayList<Zone> zoneList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_zone_templates")) {
preparedStatement.setLong(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
zoneList = getObjectsFromRs(rs, 2000);
} catch (SQLException e) {
Logger.error(e);
}
return zoneList; while (rs.next()) {
ZoneTemplate zoneTemplate = new ZoneTemplate(rs);
ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
} }
public void LOAD_ZONE_EXTENTS() { // Add player city
try (Connection connection = DbManager.getConnection(); ZoneTemplate zoneTemplate = new ZoneTemplate();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_zone_size`;")) {
ResultSet rs = preparedStatement.executeQuery(); zoneTemplate.templateID = 0;
zoneTemplate.sea_level_type = "PARENT";
zoneTemplate.sea_level = 0;
zoneTemplate.max_blend = 128;
zoneTemplate.min_blend = 128;
zoneTemplate.terrain_max_y = 5;
zoneTemplate.major_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
zoneTemplate.minor_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
zoneTemplate.terrain_type = "PLANAR";
while (rs.next()) { ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
Vector2f zoneSize = new Vector2f();
int loadNum = rs.getInt("loadNum");
zoneSize.x = rs.getFloat("xRadius");
zoneSize.y = rs.getFloat("zRadius");
ZoneManager._zone_size_data.put(loadNum, zoneSize);
}
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
} }
public boolean DELETE_ZONE(final Zone zone) { public boolean DELETE_ZONE(final Zone zone) {

2
src/engine/devcmd/cmds/AddMobCmd.java

@ -78,7 +78,7 @@ public class AddMobCmd extends AbstractDevCmd {
return; return;
} }
if (zone.isPlayerCity()) { if (zone.guild_zone) {
throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead."); throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead.");
return; return;
} }

6
src/engine/devcmd/cmds/AuditMobsCmd.java

@ -40,8 +40,8 @@ public class AuditMobsCmd extends AbstractDevCmd {
if (size >= count) { if (size >= count) {
plusplus++; plusplus++;
throwbackInfo(pcSender, zoneMicro.getName() + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. "); throwbackInfo(pcSender, zoneMicro.zoneName + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. ");
System.out.println(zoneMicro.getName() + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. "); System.out.println(zoneMicro.zoneName + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. ");
} }
@ -80,7 +80,7 @@ public class AuditMobsCmd extends AbstractDevCmd {
//ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap(); //ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap();
// ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap(); // ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap();
throwbackInfo(pcSender, zone.getName() + ", numMobs: " + zone.zoneMobSet.size()); throwbackInfo(pcSender, zone.zoneName + ", numMobs: " + zone.zoneMobSet.size());
throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc"); throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc");

48
src/engine/devcmd/cmds/GetHeightCmd.java

@ -9,7 +9,7 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f; import engine.math.Vector2f;
@ -21,7 +21,6 @@ public class GetHeightCmd extends AbstractDevCmd {
public GetHeightCmd() { public GetHeightCmd() {
super("getHeight"); super("getHeight");
this.addCmdString("height");
} }
@Override @Override
@ -33,23 +32,42 @@ public class GetHeightCmd extends AbstractDevCmd {
Zone heightmapZone; Zone heightmapZone;
currentZone = ZoneManager.findSmallestZone(playerCharacter.getLoc()); currentZone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
heightmapZone = HeightMap.getNextZoneWithTerrain(currentZone); heightmapZone = Terrain.getNextZoneWithTerrain(currentZone);
parentZone = HeightMap.getNextZoneWithTerrain(currentZone.getParent()); parentZone = Terrain.getNextZoneWithTerrain(currentZone.parent);
float currentHeight = HeightMap.getWorldHeight(currentZone, playerCharacter.getLoc()); Vector2f childZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), heightmapZone);
float parentHeight = HeightMap.getWorldHeight(parentZone, playerCharacter.getLoc()); Vector2f childZoneOffset = ZoneManager.worldToZoneOffset(playerCharacter.getLoc(), heightmapZone);
Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.template.major_radius,
Math.abs(childZoneOffset.y) / heightmapZone.template.minor_radius);
Vector2f parentZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), parentZone);
this.throwbackInfo(playerCharacter, "Current Zone : " + currentZone.getName()); float childHeight = heightmapZone.terrain.getInterpolatedTerrainHeight(childZoneLoc);
this.throwbackInfo(playerCharacter, "Heightmap Zone : " + heightmapZone.getName()); childHeight = childHeight + heightmapZone.global_height;
this.throwbackInfo(playerCharacter, "Height returned: " + currentHeight);
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(playerCharacter.getLoc(), heightmapZone); float parentHeight = parentZone.terrain.getInterpolatedTerrainHeight(parentZoneLoc);
Vector2f gridSquare = heightmapZone.getHeightMap().getGridSquare(zoneLoc); parentHeight += parentZone.global_height;
float blendedHeight = Terrain.getWorldHeight(currentZone, playerCharacter.getLoc());
Vector2f gridSquare = heightmapZone.terrain.getTerrainCell(childZoneLoc);
gridSquare.x = (float) Math.floor(gridSquare.x);
gridSquare.y = (float) Math.floor(gridSquare.y);
this.throwbackInfo(playerCharacter, "Current Zone : " + currentZone.zoneName);
this.throwbackInfo(playerCharacter, "Heightmap Zone : " + heightmapZone.zoneName);
this.throwbackInfo(playerCharacter, "Parent Zone: " + parentZone.zoneName);
this.throwbackInfo(playerCharacter, "Grid : " + "[" + gridSquare.x + "]" + "[" + gridSquare.y + "]");
this.throwbackInfo(playerCharacter, "offset: " + "[" + childZoneOffset.x + "]" + "[" + childZoneOffset.y + "]");
this.throwbackInfo(playerCharacter, "Normalized offset: " + "[" + normalizedOffset.x + "]" + "[" + normalizedOffset.y + "]");
this.throwbackInfo(playerCharacter, "Blend coefficient: " + heightmapZone.terrain.getTerrainBlendCoefficient(childZoneOffset));
this.throwbackInfo(playerCharacter, "------------");
this.throwbackInfo(playerCharacter, "Child Height at loc: " + Math.ceil(childHeight));
this.throwbackInfo(playerCharacter, "Parent Height at loc: " + Math.ceil(parentHeight));
this.throwbackInfo(playerCharacter, "Blended Height (Ceil): " + blendedHeight + " (" + Math.ceil(blendedHeight) + ")");
this.throwbackInfo(playerCharacter, "Grid : " + (int) gridSquare.x + "x" + (int) gridSquare.y);
this.throwbackInfo(playerCharacter, "Parent : " + parentZone.getName());
this.throwbackInfo(playerCharacter, "Height returned : " + parentHeight);
this.throwbackInfo(playerCharacter, "Character Height: " + playerCharacter.getCharacterHeight());
} }
@Override @Override

2
src/engine/devcmd/cmds/GetOffsetCmd.java

@ -48,7 +48,7 @@ public class GetOffsetCmd extends AbstractDevCmd {
float difY = pcSender.getLoc().y - zone.absY; float difY = pcSender.getLoc().y - zone.absY;
float difZ = pcSender.getLoc().z - zone.absZ; float difZ = pcSender.getLoc().z - zone.absZ;
throwbackInfo(pcSender, zone.getName() + ": (x: " + difX + ", y: " + difY + ", z: " + difZ + ')'); throwbackInfo(pcSender, zone.zoneName + ": (x: " + difX + ", y: " + difY + ", z: " + difZ + ')');
} }
@Override @Override

2
src/engine/devcmd/cmds/GetZoneCmd.java

@ -51,7 +51,7 @@ public class GetZoneCmd extends AbstractDevCmd {
} }
for (Zone zone : allIn) for (Zone zone : allIn)
throwbackInfo(pcSender, zone.getName() + "; UUID: " + zone.getObjectUUID() + ", loadNum: " + zone.getLoadNum()); throwbackInfo(pcSender, zone.zoneName + "; UUID: " + zone.getObjectUUID() + ", loadNum: " + zone.templateID);
} }
@Override @Override

6
src/engine/devcmd/cmds/GotoCmd.java

@ -81,7 +81,7 @@ public class GotoCmd extends AbstractDevCmd {
continue; continue;
Zone zone = city.getParent(); Zone zone = city.getParent();
if (zone != null) { if (zone != null) {
if (zone.isNPCCity() || zone.isPlayerCity()) if (zone.isNPCCity || zone.guild_zone)
loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS); loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
else else
loc = zone.getLoc(); loc = zone.getLoc();
@ -97,10 +97,10 @@ public class GotoCmd extends AbstractDevCmd {
Zone zone = (Zone) zoneAgo; Zone zone = (Zone) zoneAgo;
if (zone == null) if (zone == null)
continue; continue;
if (!zone.getName().equalsIgnoreCase(cityName)) if (!zone.zoneName.equalsIgnoreCase(cityName))
continue; continue;
if (zone != null) { if (zone != null) {
if (zone.isNPCCity() || zone.isPlayerCity()) if (zone.isNPCCity || zone.guild_zone)
loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS); loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
else else
loc = zone.getLoc(); loc = zone.getLoc();

4
src/engine/devcmd/cmds/HotzoneCmd.java

@ -40,7 +40,7 @@ public class HotzoneCmd extends AbstractDevCmd {
String input = data.toString().trim(); String input = data.toString().trim();
if (input.length() == 0) { if (input.length() == 0) {
outString = "Current hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; outString = "Current hotZone: " + ZoneManager.hotZone.zoneName + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones(); outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString); throwbackInfo(playerCharacter, outString);
return; return;
@ -48,7 +48,7 @@ public class HotzoneCmd extends AbstractDevCmd {
if (input.equalsIgnoreCase("random")) { if (input.equalsIgnoreCase("random")) {
ZoneManager.generateAndSetRandomHotzone(); ZoneManager.generateAndSetRandomHotzone();
outString = "New hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; outString = "New hotZone: " + ZoneManager.hotZone.zoneName + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones(); outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString); throwbackInfo(playerCharacter, outString);
return; return;

4
src/engine/devcmd/cmds/InfoCmd.java

@ -387,7 +387,7 @@ public class InfoCmd extends AbstractDevCmd {
output += newline; output += newline;
output += "EquipSet: " + targetNPC.getEquipmentSetID(); output += "EquipSet: " + targetNPC.getEquipmentSetID();
output += newline; output += newline;
output += "Parent Zone LoadNum : " + targetNPC.getParentZone().getLoadNum(); output += "Parent Zone LoadNum : " + targetNPC.getParentZone().templateID;
} }
@ -473,7 +473,7 @@ public class InfoCmd extends AbstractDevCmd {
output += "EquipSet: " + targetMob.equipmentSetID; output += "EquipSet: " + targetMob.equipmentSetID;
output += newline; output += newline;
try { try {
output += "Parent Zone LoadNum : " + targetMob.getParentZone().getLoadNum(); output += "Parent Zone LoadNum : " + targetMob.getParentZone().templateID;
} catch (Exception ex) { } catch (Exception ex) {
//who cares //who cares
} }

6
src/engine/devcmd/cmds/MakeBaneCmd.java

@ -111,12 +111,12 @@ public class MakeBaneCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;
@ -167,7 +167,7 @@ public class MakeBaneCmd extends AbstractDevCmd {
return; return;
} }
stone.addEffectBit((1 << 19)); stone.addEffectBit((1 << 19));
stone.setRank((byte) rank); BuildingManager.setRank(stone, (byte) rank);
stone.setMaxHitPoints(blueprint.getMaxHealth(stone.getRank())); stone.setMaxHitPoints(blueprint.getMaxHealth(stone.getRank()));
stone.setCurrentHitPoints(stone.getMaxHitPoints()); stone.setCurrentHitPoints(stone.getMaxHitPoints());
BuildingManager.setUpgradeDateTime(stone, null, 0); BuildingManager.setUpgradeDateTime(stone, null, 0);

67
src/engine/devcmd/cmds/PrintEffectsCmd.java

@ -0,0 +1,67 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintEffectsCmd extends AbstractDevCmd {
public PrintEffectsCmd() {
super("printeffects");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Effects For Character: " + tar.getName() + newline;
for(String effect : tar.effects.keySet()){
output += effect + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}

67
src/engine/devcmd/cmds/PrintRunesCmd.java

@ -0,0 +1,67 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintRunesCmd extends AbstractDevCmd {
public PrintRunesCmd() {
super("printrunes");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Applied Runes For Character: " + ((AbstractCharacter) target).getName() + newline;
for(CharacterRune rune : ((AbstractCharacter)target).runes){
output += rune.getRuneBaseID() + " " + rune.getRuneBase().getName() + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}

2
src/engine/devcmd/cmds/PurgeObjectsCmd.java

@ -42,7 +42,7 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
private static void PurgeWalls(Zone zone, PlayerCharacter pc) { private static void PurgeWalls(Zone zone, PlayerCharacter pc) {
if (!zone.isPlayerCity()) if (!zone.guild_zone)
return; return;
for (Building building : zone.zoneBuildingSet) { for (Building building : zone.zoneBuildingSet) {

6
src/engine/devcmd/cmds/RealmInfoCmd.java

@ -60,12 +60,12 @@ public class RealmInfoCmd extends AbstractDevCmd {
outString += ")"; outString += ")";
outString += newline; outString += newline;
outString += " Zone: " + serverZone.getName(); outString += " Zone: " + serverZone.zoneName;
outString += newline; outString += newline;
if (serverZone.getParent() != null) if (serverZone.parent != null)
outString += " Parent: " + serverZone.getParent().getName(); outString += " Parent: " + serverZone.parent.zoneName;
else else
outString += "Parent: NONE"; outString += "Parent: NONE";

51
src/engine/devcmd/cmds/RegionCmd.java

@ -9,9 +9,10 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.AbstractGameObject; import engine.gameManager.BuildingManager;
import engine.objects.PlayerCharacter; import engine.objects.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -25,42 +26,28 @@ public class RegionCmd extends AbstractDevCmd {
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
String newline = "\r\n ";
String output;
output = "Target Region Information:" + newline;
if (pc.region == null) { Building building = BuildingManager.getBuildingAtLocation(((AbstractCharacter) target).loc);
if(building == null){
this.throwbackInfo(pc, "No Building At This Location.") ;
}
Regions region = ((AbstractCharacter)target).region;
if (region == null) {
this.throwbackInfo(pc, "No Region Found."); this.throwbackInfo(pc, "No Region Found.");
return; return;
} }
if(region != null) {
String newLine = System.getProperty("line.separator"); output += "Player Info: " + ((AbstractCharacter) target).getName() + newline;
String result = ""; output += "Region Building: " + building.getName() + newline;
result += (pc.region.getClass().getSimpleName()); output += "Region Height: " + region.lerpY((AbstractCharacter)target) + newline;
result += (" {"); output += "is Stairs: " + region.isStairs() + newline;
result += (newLine); output += "is Outside: " + region.isOutside();
Field[] fields = pc.region.getClass().getDeclaredFields(); this.throwbackInfo(pc, output);
//print field names paired with their values
for (Field field : fields) {
field.setAccessible(true);
result += (" ");
try {
if (field.getName().contains("Furniture"))
continue;
result += (field.getName());
result += (": ");
//requires access to private field:
result += (field.get(pc.region).toString());
} catch (IllegalAccessException ex) {
System.out.println(ex);
} }
result.trim();
result += (newLine);
}
result += ("}");
this.throwbackInfo(pc, result.toString());
} }

4
src/engine/devcmd/cmds/RemoveBaneCmd.java

@ -34,12 +34,12 @@ public class RemoveBaneCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;

2
src/engine/devcmd/cmds/RemoveObjectCmd.java

@ -130,7 +130,7 @@ public class RemoveObjectCmd extends AbstractDevCmd {
building.disableSpire(false); building.disableSpire(false);
if ((building.getBlueprint() != null) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.WAREHOUSE)) { if ((building.getBlueprint() != null) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.WAREHOUSE)) {
City city = City.getCity(building.getParentZone().getPlayerCityUUID()); City city = City.getCity(building.getParentZone().playerCityUUID);
if (city != null) { if (city != null) {
city.setWarehouseBuildingID(0); city.setWarehouseBuildingID(0);
} }

4
src/engine/devcmd/cmds/SetBaneActiveCmd.java

@ -41,12 +41,12 @@ public class SetBaneActiveCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;

4
src/engine/devcmd/cmds/SetForceRenameCityCmd.java

@ -31,9 +31,9 @@ public class SetForceRenameCityCmd extends AbstractDevCmd {
if (zone == null) if (zone == null)
return; return;
boolean rename = words[0].equalsIgnoreCase("true") ? true : false; boolean rename = words[0].equalsIgnoreCase("true") ? true : false;
if (zone.getPlayerCityUUID() == 0) if (zone.playerCityUUID == 0)
return; return;
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) if (city == null)
return; return;
city.setForceRename(rename); city.setForceRename(rename);

7
src/engine/devcmd/cmds/SetRankCmd.java

@ -57,7 +57,7 @@ public class SetRankCmd extends AbstractDevCmd {
Blueprint blueprint = targetBuilding.getBlueprint(); Blueprint blueprint = targetBuilding.getBlueprint();
if (blueprint == null) { if (blueprint == null) {
targetBuilding.setRank(targetRank); BuildingManager.setRank(targetBuilding, targetRank);
ChatManager.chatSayInfo(player, "Building ranked without blueprint" + targetBuilding.getObjectUUID()); ChatManager.chatSayInfo(player, "Building ranked without blueprint" + targetBuilding.getObjectUUID());
return; return;
} }
@ -68,9 +68,8 @@ public class SetRankCmd extends AbstractDevCmd {
} }
// Set the current targetRank // Set the current targetRank
int lastMeshID = targetBuilding.getMeshUUID();
targetBuilding.setRank(targetRank);
BuildingManager.setRank(targetBuilding, targetRank);
ChatManager.chatSayInfo(player, "Rank set for building with ID " + targetBuilding.getObjectUUID() + " to rank " + targetRank); ChatManager.chatSayInfo(player, "Rank set for building with ID " + targetBuilding.getObjectUUID() + " to rank " + targetRank);
break; break;
case NPC: case NPC:
@ -114,7 +113,7 @@ public class SetRankCmd extends AbstractDevCmd {
// Set the current targetRank // Set the current targetRank
int lastMeshID = targetBuilding.getMeshUUID(); int lastMeshID = targetBuilding.getMeshUUID();
targetBuilding.setRank(targetRank); BuildingManager.setRank(targetBuilding, targetRank);
if (lastMeshID != targetBuilding.getMeshUUID()) if (lastMeshID != targetBuilding.getMeshUUID())
targetBuilding.refresh(true); targetBuilding.refresh(true);

2
src/engine/devcmd/cmds/SummonCmd.java

@ -40,7 +40,7 @@ public class SummonCmd extends AbstractDevCmd {
Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
String location = "Somewhere"; String location = "Somewhere";
if (zone != null) if (zone != null)
location = zone.getName(); location = zone.zoneName;
RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), pc.getFirstName(), RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), pc.getFirstName(),
location, false); location, false);
toSummon.getClientConnection().sendMsg(rsrm); toSummon.getClientConnection().sendMsg(rsrm);

37
src/engine/devcmd/cmds/ZoneInfoCmd.java

@ -73,44 +73,41 @@ public class ZoneInfoCmd extends AbstractDevCmd {
output = "Target Information:" + newline; output = "Target Information:" + newline;
output += StringUtils.addWS("UUID: " + objectUUID, 20); output += StringUtils.addWS("UUID: " + objectUUID, 20);
output += newline; output += newline;
output += "name: " + zone.getName(); output += "name: " + zone.zoneName;
output += newline; output += newline;
output += "loadNum: " + zone.getLoadNum(); output += "loadNum: " + zone.templateID;
if (zone.getParent() != null) { if (zone.parent != null) {
output += StringUtils.addWS(", parent: " + zone.getParent().getObjectUUID(), 30); output += StringUtils.addWS(", parent: " + zone.parent.getObjectUUID(), 30);
output += "Parentabs: x: " + zone.getParent().getAbsX() + ", y: " + zone.getParent().getAbsY() + ", z: " + zone.getParent().getAbsZ(); output += "Parentabs: x: " + zone.parent.absX + ", y: " + zone.parent.absY + ", z: " + zone.parent.absZ;
} else } else
output += StringUtils.addWS(", parent: none", 30); output += StringUtils.addWS(", parent: none", 30);
output += newline; output += newline;
output += "absLoc: x: " + zone.getAbsX() + ", y: " + zone.getAbsY() + ", z: " + zone.getAbsZ(); output += "absLoc: x: " + zone.absX + ", y: " + zone.absY + ", z: " + zone.absZ;
output += newline; output += newline;
output += "offset: x: " + zone.getXCoord() + ", y: " + zone.getYCoord() + ", z: " + zone.getZCoord(); output += "offset: x: " + zone.xOffset + ", y: " + zone.yOffset + ", z: " + zone.zOffset;
output += newline; output += newline;
output += "radius: x: " + zone.getBounds().getHalfExtents().x + ", z: " + zone.getBounds().getHalfExtents().y; output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
output += newline; output += newline;
if (zone.getHeightMap() != null) { if (zone.terrain != null) {
output += "HeightMap ID: " + zone.getHeightMap().getHeightMapID(); output += "Terrain image: " + zone.template.terrain_image;
output += newline; output += newline;
output += "Bucket Width X : " + zone.getHeightMap().getBucketWidthX();
output += newline;
output += "Bucket Width Y : " + zone.getHeightMap().getBucketWidthY();
} }
output += "radius: x: " + zone.getBounds().getHalfExtents().x + ", z: " + zone.getBounds().getHalfExtents().y;
output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
output += newline; output += newline;
// output += "minLvl = " + zone.getMinLvl() + " | maxLvl = " + zone.getMaxLvl(); // output += "minLvl = " + zone.getMinLvl() + " | maxLvl = " + zone.getMaxLvl();
output += newline; output += newline;
output += "Sea Level = " + zone.getSeaLevel(); output += "Sea Level = " + zone.sea_level;
output += newline; output += newline;
output += "World Altitude = " + zone.worldAltitude; output += "World Altitude = " + zone.global_height;
throwbackInfo(player, output); throwbackInfo(player, output);
City city = ZoneManager.getCityAtLocation(player.getLoc()); City city = ZoneManager.getCityAtLocation(player.getLoc());
output += newline; output += newline;
output += (city == null) ? "None" : city.getParent().getName(); output += (city == null) ? "None" : city.getParent().zoneName;
if (city != null) { if (city != null) {
@ -123,14 +120,14 @@ public class ZoneInfoCmd extends AbstractDevCmd {
} else { } else {
output = "children:"; output = "children:";
ArrayList<Zone> nodes = zone.getNodes(); ArrayList<Zone> nodes = zone.nodes;
if (nodes.isEmpty()) if (nodes.isEmpty())
output += " none"; output += " none";
for (Zone child : nodes) { for (Zone child : nodes) {
output += newline; output += newline;
output += child.getName() + " (" + child.getLoadNum() + ')'; output += child.zoneName + " (" + child.templateID + ')';
} }
} }
throwbackInfo(player, output); throwbackInfo(player, output);

2
src/engine/devcmd/cmds/ZoneSetCmd.java

@ -40,7 +40,7 @@ public class ZoneSetCmd extends AbstractDevCmd {
zone = ZoneManager.findSmallestZone(playerCharacter.getLoc()); zone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
throwbackInfo(playerCharacter, zone.getName() + " (" + zone.getLoadNum() + ") " + zone.getObjectUUID()); throwbackInfo(playerCharacter, zone.zoneName + " (" + zone.templateID + ") " + zone.getObjectUUID());
// NPC // NPC

135
src/engine/gameManager/BuildingManager.java

@ -31,6 +31,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public enum BuildingManager { public enum BuildingManager {
@ -40,6 +41,9 @@ public enum BuildingManager {
public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>();
public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>();
public static HashMap<Integer, ConcurrentHashMap<Integer, BuildingFriends>> _buildingFriends = new HashMap<>();
public static HashMap<Integer, ConcurrentHashMap<Integer, Condemned>> _buildingCondemned = new HashMap<>();
public static HashMap<Integer, ArrayList<Vector3fImmutable>> _buildingPatrolPoints = new HashMap<>();
public static int getAvailableSlot(Building building) { public static int getAvailableSlot(Building building) {
ArrayList<BuildingLocation> slotLocations = _slotLocations.get(building.meshUUID); ArrayList<BuildingLocation> slotLocations = _slotLocations.get(building.meshUUID);
@ -104,7 +108,6 @@ public enum BuildingManager {
if (building == null) if (building == null)
return false; return false;
if (building.getRank() == -1) if (building.getRank() == -1)
return false; return false;
@ -112,26 +115,25 @@ public enum BuildingManager {
return true; return true;
//individual friend. //individual friend.
if (building.getFriends().get(player.getObjectUUID()) != null) if (building.getFriends() != null && building.getFriends().get(player.getObjectUUID()) != null)
return true; return true;
//Admin's can access stuff //Admins can access stuff
if (player.isCSR()) if (player.isCSR())
return true; return true;
//Guild stuff //Guild stuff
if (building.getGuild().isGuildLeader(player.getObjectUUID()))
if (building.getGuild() != null && building.getGuild().isGuildLeader(player.getObjectUUID()))
return true; return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).getFriendType() == 8) && building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 8)
return true; return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).getFriendType() == 9 && building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 9
&& GuildStatusController.isInnerCouncil(player.getGuildStatus())) && GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true; return true;
@ -494,18 +496,18 @@ public enum BuildingManager {
Condemned condemn = building.getCondemned().get(player.getObjectUUID()); Condemned condemn = building.getCondemned().get(player.getObjectUUID());
if (condemn != null && condemn.isActive()) if (condemn != null && condemn.active)
return true; return true;
if (player.getGuild() != null) { if (player.getGuild() != null) {
Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID()); Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID());
if (guildCondemn != null && guildCondemn.isActive()) if (guildCondemn != null && guildCondemn.active)
return true; return true;
Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID()); Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID());
return nationCondemn != null && nationCondemn.isActive() && nationCondemn.getFriendType() == Condemned.NATION; return nationCondemn != null && nationCondemn.active && nationCondemn.friendType == Condemned.NATION;
} else { } else {
//TODO ADD ERRANT KOS CHECK //TODO ADD ERRANT KOS CHECK
} }
@ -513,18 +515,18 @@ public enum BuildingManager {
Condemned condemn = building.getCondemned().get(player.getObjectUUID()); Condemned condemn = building.getCondemned().get(player.getObjectUUID());
if (condemn != null && condemn.isActive()) if (condemn != null && condemn.active)
return false; return false;
if (player.getGuild() != null) { if (player.getGuild() != null) {
Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID()); Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID());
if (guildCondemn != null && guildCondemn.isActive()) if (guildCondemn != null && guildCondemn.active)
return false; return false;
Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID()); Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID());
return nationCondemn == null || !nationCondemn.isActive() || nationCondemn.getFriendType() != Condemned.NATION; return nationCondemn == null || !nationCondemn.active || nationCondemn.friendType != Condemned.NATION;
} else { } else {
//TODO ADD ERRANT KOS CHECK //TODO ADD ERRANT KOS CHECK
} }
@ -851,4 +853,111 @@ public enum BuildingManager {
} }
} }
public static void rebuildMine(Building mineBuilding) {
setRank(mineBuilding, 1);
mineBuilding.meshUUID = mineBuilding.getBlueprint().getMeshForRank(mineBuilding.rank);
// New rank mean new max hit points.
mineBuilding.healthMax = mineBuilding.getBlueprint().getMaxHealth(mineBuilding.rank);
mineBuilding.setCurrentHitPoints(mineBuilding.healthMax);
mineBuilding.getBounds().setBounds(mineBuilding);
}
public static void setRank(Building building, int rank) {
int newMeshUUID;
boolean success;
// If this building has no blueprint then set rank and exit immediatly.
if (building.blueprintUUID == 0 || building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)) {
building.rank = rank;
DbManager.BuildingQueries.CHANGE_RANK(building.getObjectUUID(), rank);
return;
}
// Delete any upgrade jobs before doing anything else. It won't quite work
// if in a few lines we happen to delete this building.
JobContainer jc = building.getTimers().get("UPGRADE");
if (jc != null) {
if (!JobScheduler.getInstance().cancelScheduledJob(jc))
Logger.error("failed to cancel existing upgrade job.");
}
// Attempt write to database, or delete the building
// if we are destroying it.
if (rank == -1)
success = DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
else
success = DbManager.BuildingQueries.updateBuildingRank(building, rank);
if (success == false) {
Logger.error("Error writing to database UUID: " + building.getObjectUUID());
return;
}
building.isDeranking.compareAndSet(false, true);
// Change the building's rank
building.rank = rank;
// New rank means new mesh
newMeshUUID = building.getBlueprint().getMeshForRank(building.rank);
building.meshUUID = newMeshUUID;
// New rank mean new max hitpoints.
building.healthMax = building.getBlueprint().getMaxHealth(building.rank);
building.setCurrentHitPoints(building.healthMax);
if (building.getUpgradeDateTime() != null)
setUpgradeDateTime(building, null, 0);
// If we destroyed this building make sure to turn off
// protection
if (building.rank == -1)
building.protectionState = Enum.ProtectionState.NONE;
if ((building.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
&& (building.rank == 8))
building.meshUUID = Realm.getRealmMesh(building.getCity());
// update object to clients
building.refresh(true);
if (building.getBounds() != null)
building.getBounds().setBounds(building);
// Cleanup hirelings resulting from rank change
cleanupHirelings(building);
building.isDeranking.compareAndSet(true, false);
}
public static Building getBuildingAtLocation(Vector3fImmutable loc) {
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(loc, 64, MBServerStatics.MASK_BUILDING)) {
Building building = (Building) awo;
if (building == null)
continue;
if (Bounds.collide(loc, building.getBounds()))
return building;
}
return null;
}
} }

1
src/engine/gameManager/DbManager.java

@ -70,7 +70,6 @@ public enum DbManager {
public static final dbBlueprintHandler BlueprintQueries = new dbBlueprintHandler(); public static final dbBlueprintHandler BlueprintQueries = new dbBlueprintHandler();
public static final dbBoonHandler BoonQueries = new dbBoonHandler(); public static final dbBoonHandler BoonQueries = new dbBoonHandler();
public static final dbShrineHandler ShrineQueries = new dbShrineHandler(); public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
public static final dbHeightMapHandler HeightMapQueries = new dbHeightMapHandler();
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler(); public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
public static final dbPowerHandler PowerQueries = new dbPowerHandler(); public static final dbPowerHandler PowerQueries = new dbPowerHandler();

3
src/engine/gameManager/DevCmdManager.java

@ -46,9 +46,11 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new GetZoneCmd()); DevCmdManager.registerDevCmd(new GetZoneCmd());
DevCmdManager.registerDevCmd(new ZoneSetCmd()); DevCmdManager.registerDevCmd(new ZoneSetCmd());
DevCmdManager.registerDevCmd(new PrintBankCmd()); DevCmdManager.registerDevCmd(new PrintBankCmd());
DevCmdManager.registerDevCmd(new PrintEffectsCmd());
DevCmdManager.registerDevCmd(new PrintEquipCmd()); DevCmdManager.registerDevCmd(new PrintEquipCmd());
DevCmdManager.registerDevCmd(new PrintInventoryCmd()); DevCmdManager.registerDevCmd(new PrintInventoryCmd());
DevCmdManager.registerDevCmd(new PrintVaultCmd()); DevCmdManager.registerDevCmd(new PrintVaultCmd());
DevCmdManager.registerDevCmd(new PrintRunesCmd());
DevCmdManager.registerDevCmd(new PrintStatsCmd()); DevCmdManager.registerDevCmd(new PrintStatsCmd());
DevCmdManager.registerDevCmd(new PrintSkillsCmd()); DevCmdManager.registerDevCmd(new PrintSkillsCmd());
DevCmdManager.registerDevCmd(new PrintPowersCmd()); DevCmdManager.registerDevCmd(new PrintPowersCmd());
@ -142,7 +144,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new ApplyBonusCmd()); DevCmdManager.registerDevCmd(new ApplyBonusCmd());
DevCmdManager.registerDevCmd(new AuditFailedItemsCmd()); DevCmdManager.registerDevCmd(new AuditFailedItemsCmd());
DevCmdManager.registerDevCmd(new SlotTestCmd()); DevCmdManager.registerDevCmd(new SlotTestCmd());
} }
private static void registerDevCmd(AbstractDevCmd cmd) { private static void registerDevCmd(AbstractDevCmd cmd) {

4
src/engine/gameManager/LootManager.java

@ -86,7 +86,7 @@ public enum LootManager {
if(ib == null) if(ib == null)
break; break;
if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) { if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg); DispatchMessage.dispatchMsgToAll(chatMsg);
@ -330,6 +330,8 @@ public enum LootManager {
public static void GenerateEquipmentDrop(Mob mob) { public static void GenerateEquipmentDrop(Mob mob) {
if(mob.behaviourType.equals(Enum.MobBehaviourType.HamletGuard))
return; // safehold guards don't drop their equipment
//do equipment here //do equipment here
int dropCount = 0; int dropCount = 0;
if (mob.getEquip() != null) if (mob.getEquip() != null)

28
src/engine/gameManager/MovementManager.java

@ -267,7 +267,7 @@ public enum MovementManager {
Zone serverZone = null; Zone serverZone = null;
serverZone = ZoneManager.findSmallestZone(player.getLoc()); serverZone = ZoneManager.findSmallestZone(player.getLoc());
cityObject = (City) DbManager.getFromCache(GameObjectType.City, serverZone.getPlayerCityUUID()); cityObject = (City) DbManager.getFromCache(GameObjectType.City, serverZone.playerCityUUID);
// Do not send group messages if player is on grid // Do not send group messages if player is on grid
@ -464,34 +464,20 @@ public enum MovementManager {
} }
} }
public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc, Regions region) { public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc) {
if (targetLoc == null) if (targetLoc == null)
return; return;
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(targetLoc); teleporter.stopMovement(targetLoc);
teleporter.setRegion(region); Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.setLoc(targetLoc);
//mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)) {
teleporter.setInBuildingID(0);
teleporter.setInBuilding(-1);
teleporter.setInFloorID(-1);
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
return;
}
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1);
//we shouldnt need to send teleport message to new area, as loadjob should pick it up.
// DispatchMessage.dispatchMsgToInterestArea(teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
if (teleporter.getObjectType().equals(GameObjectType.PlayerCharacter)) if (teleporter.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) teleporter); InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) teleporter);
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, teleporter.loc.getX(), teleporter.loc.getY(), teleporter.loc.getZ(), 0, -1, -1);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
private static void syncLoc(AbstractCharacter ac, Vector3fImmutable clientLoc, boolean useClientLoc) { private static void syncLoc(AbstractCharacter ac, Vector3fImmutable clientLoc, boolean useClientLoc) {

16
src/engine/gameManager/NPCManager.java

@ -458,4 +458,20 @@ public enum NPCManager {
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains())); mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
} }
} }
public static void applyRunesForNPC(NPC npc){
npc.runes = new ArrayList<>();
RuneBase shopkeeperBase = RuneBase.getRuneBase(252620);
CharacterRune shopkeeper = new CharacterRune(shopkeeperBase,npc.getObjectUUID());
npc.runes.add(shopkeeper);
if(NPCManager._runeSetMap.containsKey(npc.runeSetID)) {
for (int runeID : _runeSetMap.get(npc.runeSetID)) {
RuneBase rb = RuneBase.getRuneBase(runeID);
if(rb != null) {
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
npc.runes.add(toApply);
}
}
}
}
} }

6
src/engine/gameManager/PowersManager.java

@ -9,7 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.handlers.dbEffectsBaseHandler; import engine.db.handlers.dbEffectsBaseHandler;
import engine.db.handlers.dbPowerHandler; import engine.db.handlers.dbPowerHandler;
@ -1772,7 +1772,7 @@ public enum PowersManager {
} else { } else {
targetLoc = tl; targetLoc = tl;
try { try {
targetLoc = targetLoc.setY(HeightMap.getWorldHeight(targetLoc)); //on ground targetLoc = targetLoc.setY(Terrain.getWorldHeight(targetLoc)); //on ground
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
targetLoc = tl; targetLoc = tl;
@ -1974,7 +1974,7 @@ public enum PowersManager {
} else { } else {
targetLoc = tl; targetLoc = tl;
try { try {
targetLoc = targetLoc.setY(HeightMap.getWorldHeight(targetLoc)); //on ground targetLoc = targetLoc.setY(Terrain.getWorldHeight(targetLoc)); //on ground
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
} }

198
src/engine/gameManager/ZoneManager.java

@ -9,9 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.Enum; import engine.Enum;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3f; import engine.math.Vector3f;
@ -19,6 +17,7 @@ import engine.math.Vector3fImmutable;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
import engine.objects.Zone; import engine.objects.Zone;
import engine.objects.ZoneTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -37,6 +36,8 @@ public enum ZoneManager {
ZONEMANAGER; ZONEMANAGER;
public static HashMap<Integer, ZoneTemplate> _zone_templates = new HashMap<>();
public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>());
private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
private static final ConcurrentHashMap<Integer, Zone> zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); private static final ConcurrentHashMap<Integer, Zone> zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
@ -46,9 +47,9 @@ public enum ZoneManager {
public static Instant hotZoneLastUpdate; public static Instant hotZoneLastUpdate;
public static Zone hotZone = null; public static Zone hotZone = null;
public static int hotZoneCycle = 0; // Used with HOTZONE_DURATION from config. public static int hotZoneCycle = 0; // Used with HOTZONE_DURATION from config.
public static HashMap<Integer, Vector2f> _zone_size_data = new HashMap<>();
/* Instance variables */ /* Instance variables */
private static Zone seaFloor = null; public static Zone seaFloor = null;
// Find all zones coordinates fit into, starting with Sea Floor // Find all zones coordinates fit into, starting with Sea Floor
@ -61,8 +62,8 @@ public enum ZoneManager {
if (zone != null) { if (zone != null) {
allIn.add(zone); allIn.add(zone);
while (zone.getParent() != null) { while (zone.parent != null) {
zone = zone.getParent(); zone = zone.parent;
allIn.add(zone); allIn.add(zone);
} }
} }
@ -71,7 +72,7 @@ public enum ZoneManager {
// Find smallest zone coordinates fit into. // Find smallest zone coordinates fit into.
public static final Zone findSmallestZone(final Vector3fImmutable loc) { public static Zone findSmallestZone(final Vector3fImmutable loc) {
Zone zone = ZoneManager.seaFloor; Zone zone = ZoneManager.seaFloor;
@ -84,13 +85,13 @@ public enum ZoneManager {
childFound = false; childFound = false;
ArrayList<Zone> nodes = zone.getNodes(); ArrayList<Zone> nodes = zone.nodes;
// Logger.info("soze", "" + nodes.size()); // Logger.info("soze", "" + nodes.size());
if (nodes != null) if (nodes != null)
for (Zone child : nodes) { for (Zone child : nodes) {
if (Bounds.collide(loc, child.getBounds()) == true) { if (Bounds.collide(loc, child.bounds)) {
zone = child; zone = child;
childFound = true; childFound = true;
break; break;
@ -100,16 +101,6 @@ public enum ZoneManager {
return zone; return zone;
} }
public static void addZone(final int zoneID, final Zone zone) {
ZoneManager.zonesByID.put(zoneID, zone);
ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone);
ZoneManager.zonesByName.put(zone.getName().toLowerCase(), zone);
}
// Returns the number of available hotZones // Returns the number of available hotZones
// remaining in this cycle (1am) // remaining in this cycle (1am)
@ -148,11 +139,11 @@ public enum ZoneManager {
return ZoneManager.zonesByName.get(zoneName); return ZoneManager.zonesByName.get(zoneName);
} }
public static final Collection<Zone> getAllZones() { public static Collection<Zone> getAllZones() {
return ZoneManager.zonesByUUID.values(); return ZoneManager.zonesByUUID.values();
} }
public static final void setHotZone(final Zone zone) { public static void setHotZone(final Zone zone) {
if (!zone.isMacroZone()) if (!zone.isMacroZone())
return; return;
@ -169,37 +160,32 @@ public enum ZoneManager {
if (ZoneManager.hotZone == null) if (ZoneManager.hotZone == null)
return false; return false;
return (Bounds.collide(loc, ZoneManager.hotZone.getBounds()) == true); return (Bounds.collide(loc, ZoneManager.hotZone.bounds));
} }
public static Zone getSeaFloor() { public static void populateZoneCollections(final Zone zone) {
return ZoneManager.seaFloor;
}
public static void setSeaFloor(final Zone value) {
ZoneManager.seaFloor = value;
}
public static final void populateWorldZones(final Zone zone) {
int loadNum = zone.getLoadNum();
// Zones are added to separate // Zones are added to separate
// collections for quick access // collections for quick access
// based upon their type. // based upon their type.
ZoneManager.zonesByID.put(zone.templateID, zone);
ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone);
ZoneManager.zonesByName.put(zone.zoneName.toLowerCase(), zone);
if (zone.isMacroZone()) { if (zone.isMacroZone()) {
addMacroZone(zone); addMacroZone(zone);
return; return;
} }
if (zone.guild_zone) {
if (zone.isPlayerCity()) { ZoneManager.playerCityZones.add(zone);
addPlayerCityZone(zone);
return; return;
} }
if (zone.isNPCCity()) if (zone.isNPCCity)
addNPCCityZone(zone); addNPCCityZone(zone);
} }
@ -209,15 +195,10 @@ public enum ZoneManager {
} }
private static void addNPCCityZone(final Zone zone) { private static void addNPCCityZone(final Zone zone) {
zone.setNPCCity(true); zone.isNPCCity = true;
ZoneManager.npcCityZones.add(zone); ZoneManager.npcCityZones.add(zone);
} }
public static final void addPlayerCityZone(final Zone zone) {
zone.setPlayerCity(true);
ZoneManager.playerCityZones.add(zone);
}
public static final void generateAndSetRandomHotzone() { public static final void generateAndSetRandomHotzone() {
Zone hotZone; Zone hotZone;
@ -250,13 +231,13 @@ public enum ZoneManager {
public static final boolean validHotZone(Zone zone) { public static final boolean validHotZone(Zone zone) {
if (zone.getSafeZone() == (byte) 1) if (zone.peace_zone == (byte) 1)
return false; // no safe zone hotzones// if (this.hotzone == null) return false; // no safe zone hotzones// if (this.hotzone == null)
if (zone.getNodes().isEmpty()) if (zone.equals(ZoneManager.seaFloor))
return false; return false;
if (zone.equals(ZoneManager.seaFloor)) if (zone.nodes.isEmpty())
return false; return false;
//no duplicate hotZones //no duplicate hotZones
@ -266,7 +247,7 @@ public enum ZoneManager {
// Enforce min level // Enforce min level
if (zone.minLvl < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue())) if (zone.min_level < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue()))
return false; return false;
if (ZoneManager.hotZone != null) if (ZoneManager.hotZone != null)
@ -278,55 +259,50 @@ public enum ZoneManager {
// Converts world coordinates to coordinates local to a given zone. // Converts world coordinates to coordinates local to a given zone.
public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector, public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector,
Zone serverZone) { Zone zone) {
Vector3fImmutable localCoords; Vector3fImmutable localCoords;
localCoords = new Vector3fImmutable(worldVector.x - serverZone.absX, localCoords = new Vector3fImmutable(worldVector.x - zone.absX,
worldVector.y - serverZone.absY, worldVector.z worldVector.y - zone.absY, worldVector.z
- serverZone.absZ); - zone.absZ);
return localCoords; return localCoords;
} }
public static Vector2f worldToZoneSpace(Vector3fImmutable worldVector, public static Vector2f worldToZoneOffset(Vector3fImmutable worldLoc,
Zone serverZone) { Zone zone) {
Vector2f zoneLoc;
zoneLoc = new Vector2f(worldLoc.x, worldLoc.z).subtract(zone.getLoc().x, zone.getLoc().z);
zoneLoc.y *= -1;
return zoneLoc;
}
public static Vector2f worldToTerrainSpace(Vector3fImmutable worldLoc,
Zone zone) {
Vector2f localCoords; Vector2f localCoords;
Vector2f zoneOrigin; Vector2f zoneOrigin;
// Top left corner of zone is calculated in world space by the center and it's extents. // Top left corner of zone is calculated in world space by the center and it's extents.
zoneOrigin = new Vector2f(serverZone.getLoc().x, serverZone.getLoc().z); zoneOrigin = new Vector2f(zone.getLoc().x, zone.getLoc().z);
zoneOrigin = zoneOrigin.subtract(new Vector2f(serverZone.getBounds().getHalfExtents().x, serverZone.getBounds().getHalfExtents().y)); zoneOrigin = zoneOrigin.subtract(new Vector2f(zone.bounds.getHalfExtents().x, zone.bounds.getHalfExtents().y));
// Local coordinate in world space translated to an offset from the calculated zone origin. // Local coordinate in world space translated to an offset from the calculated zone origin.
localCoords = new Vector2f(worldVector.x, worldVector.z); localCoords = new Vector2f(worldLoc.x, worldLoc.z);
localCoords = localCoords.subtract(zoneOrigin); localCoords = localCoords.subtract(zoneOrigin);
localCoords.setY((serverZone.getBounds().getHalfExtents().y * 2) - localCoords.y);
// TODO : Make sure this value does not go outside the zone's bounds.
return localCoords; return localCoords;
} }
// Converts local zone coordinates to world coordinates // Converts local zone coordinates to world coordinates
public static Vector3fImmutable localToWorld(Vector3fImmutable worldVector,
Zone serverZone) {
Vector3fImmutable worldCoords;
worldCoords = new Vector3fImmutable(worldVector.x + serverZone.absX,
worldVector.y + serverZone.absY, worldVector.z
+ serverZone.absZ);
return worldCoords;
}
/** /**
* Converts from local (relative to this building) to world. * Converts from local (relative to this building) to world.
@ -342,9 +318,10 @@ public enum ZoneManager {
if (building.getBounds().getQuaternion() == null) if (building.getBounds().getQuaternion() == null)
return building.getLoc(); return building.getLoc();
// handle building rotation
Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion()); Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion());
// handle building rotation
// handle building translation // handle building translation
return building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z); return building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z);
@ -354,12 +331,10 @@ public enum ZoneManager {
//used for regions, Building bounds not set yet. //used for regions, Building bounds not set yet.
public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) { public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) {
// convert from SB rotation value to radians // handle building rotation
Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion()); Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion());
// handle building rotation
// handle building translation // handle building translation
return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z)); return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z));
@ -382,13 +357,11 @@ public enum ZoneManager {
public static City getCityAtLocation(Vector3fImmutable worldLoc) { public static City getCityAtLocation(Vector3fImmutable worldLoc) {
Zone currentZone; Zone currentZone;
ArrayList<Zone> zoneList;
City city;
currentZone = ZoneManager.findSmallestZone(worldLoc); currentZone = ZoneManager.findSmallestZone(worldLoc);
if (currentZone.isPlayerCity()) if (currentZone.guild_zone)
return City.getCity(currentZone.getPlayerCityUUID()); return City.getCity(currentZone.playerCityUUID);
return null; return null;
} }
@ -411,16 +384,16 @@ public enum ZoneManager {
treeBounds = Bounds.borrow(); treeBounds = Bounds.borrow();
treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.PLACEMENT.extents, Enum.CityBoundsType.PLACEMENT.extents), 0.0f); treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.PLACEMENT.halfExtents, Enum.CityBoundsType.PLACEMENT.halfExtents), 0.0f);
zoneList = currentZone.getNodes(); zoneList = currentZone.nodes;
for (Zone zone : zoneList) { for (Zone zone : zoneList) {
if (zone.isContinent()) if (zone.isContinent())
continue; continue;
if (Bounds.collide(treeBounds, zone.getBounds(), 0.0f)) if (Bounds.collide(treeBounds, zone.bounds, 0.0f))
validLocation = false; validLocation = false;
} }
@ -428,57 +401,36 @@ public enum ZoneManager {
return validLocation; return validLocation;
} }
public static void loadCities(Zone zone) { public static float calculateGlobalZoneHeight(Zone zone) {
ArrayList<City> cities = DbManager.CityQueries.GET_CITIES_BY_ZONE(zone.getObjectUUID());
for (City city : cities) {
city.setParent(zone);
city.setObjectTypeMask(MBServerStatics.MASK_CITY);
city.setLoc(city.getLoc()); // huh?
//not player city, must be npc city..
if (!zone.isPlayerCity())
zone.setNPCCity(true);
if ((ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER)) && (city.getHash() == null)) {
city.setHash();
if (DataWarehouse.recordExists(Enum.DataRecordType.CITY, city.getObjectUUID()) == false) {
CityRecord cityRecord = CityRecord.borrow(city, Enum.RecordEventType.CREATE);
DataWarehouse.pushToWarehouse(cityRecord);
}
}
}
}
public static float caclulateWorldAltitude(Zone zone) {
float worldAlttitude = MBServerStatics.SEA_FLOOR_ALTITUDE; float worldAltitude = MBServerStatics.SEA_FLOOR_ALTITUDE;
// Seafloor // Seafloor
if (zone.getParent() == null) if (ZoneManager.seaFloor.equals(zone))
return worldAlttitude; return worldAltitude;
Zone parentZone = zone.getParent();
// Children of seafloor // Children of seafloor
if (parentZone.getParent() == null) if (ZoneManager.seaFloor.equals(zone.parent))
return worldAlttitude + zone.getYCoord(); return worldAltitude + zone.yOffset;
// return height from heightmap engine at zone location // return height from heightmap engine at zone location
worldAlttitude = HeightMap.getWorldHeight(parentZone, zone.getLoc()); worldAltitude = Terrain.getWorldHeight(zone.parent, zone.getLoc());
// Add zone offset to value // Add zone offset to value
worldAlttitude += zone.getYCoord(); worldAltitude += zone.yOffset;
return worldAltitude;
}
public static boolean isLocUnderwater(Vector3fImmutable currentLoc) {
float localAltitude = Terrain.getWorldHeight(currentLoc);
Zone zone = findSmallestZone(currentLoc);
return worldAlttitude; return localAltitude < zone.sea_level;
} }
} }

2
src/engine/jobs/FinishSummonsJob.java

@ -61,8 +61,6 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return; return;
} }
if (this.source.region != null)
this.target.setRegion(this.source.region);
//teleport target to source //teleport target to source
target.teleport(source.getLoc()); target.teleport(source.getLoc());
} }

3
src/engine/jobs/UpgradeBuildingJob.java

@ -1,5 +1,6 @@
package engine.jobs; package engine.jobs;
import engine.gameManager.BuildingManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.objects.Building; import engine.objects.Building;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -39,7 +40,7 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
// SetCurrentRank also changes the mesh and maxhp // SetCurrentRank also changes the mesh and maxhp
// accordingly for buildings with blueprints // accordingly for buildings with blueprints
rankingBuilding.setRank(rankingBuilding.getRank() + 1); BuildingManager.setRank(rankingBuilding, rankingBuilding.getRank() + 1);
// Reload the object // Reload the object

5
src/engine/math/Bounds.java

@ -422,7 +422,7 @@ public class Bounds {
this.origin.set(building.getLoc().x, building.getLoc().z); this.origin.set(building.getLoc().x, building.getLoc().z);
// Magicbane uses half halfExtents // Magicbane uses halfExtents
if (meshBounds == null) { if (meshBounds == null) {
halfExtentX = 1; halfExtentX = 1;
@ -438,8 +438,10 @@ public class Bounds {
// The rotation is reset after the new aabb is calculated. // The rotation is reset after the new aabb is calculated.
this.rotation = building.getRot().y; this.rotation = building.getRot().y;
// Caclculate and set the new half halfExtents for the rotated bounding box // Caclculate and set the new half halfExtents for the rotated bounding box
// and reset the rotation to 0 for this bounds. // and reset the rotation to 0 for this bounds.
this.halfExtents.set(halfExtentX, (halfExtentY)); this.halfExtents.set(halfExtentX, (halfExtentY));
this.rotation = 0; this.rotation = 0;
@ -453,7 +455,6 @@ public class Bounds {
this.halfExtents.set(blueprint.getExtents()); this.halfExtents.set(blueprint.getExtents());
this.flipExtents = Bounds.calculateFlipExtents(this); this.flipExtents = Bounds.calculateFlipExtents(this);
this.setRegions(building); this.setRegions(building);
this.setColliders(building); this.setColliders(building);

31
src/engine/mobileAI/MobAI.java

@ -657,7 +657,7 @@ public class MobAI {
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = (int) playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(playerID);
//Player is null, let's remove them from the list. //Player is null, let's remove them from the list.
@ -736,7 +736,7 @@ public class MobAI {
//mob no longer has its owner loaded, translate pet to owner //mob no longer has its owner loaded, translate pet to owner
if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) { if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc(), null); MovementManager.translocate(mob, mob.guardCaptain.getLoc());
return; return;
} }
@ -896,6 +896,13 @@ public class MobAI {
try { try {
if(mob.getTimestamps().containsKey("lastChase") == false)
mob.getTimestamps().put("lastChase",System.currentTimeMillis());
else if(System.currentTimeMillis() < mob.getTimestamps().get("lastChase").longValue() + (750 + ThreadLocalRandom.current().nextInt(0,500)))
return;
mob.getTimestamps().put("lastChase",System.currentTimeMillis());
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (mob.getRange() > 15) { if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
@ -991,7 +998,7 @@ public class MobAI {
try { try {
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob)) if (ZoneManager.seaFloor.zoneMobSet.contains(mob))
mob.killCharacter("no owner"); mob.killCharacter("no owner");
if (MovementUtilities.canMove(mob) && mob.behaviourType.canRoam) if (MovementUtilities.canMove(mob) && mob.behaviourType.canRoam)
@ -1098,7 +1105,7 @@ public class MobAI {
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = (int) playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(playerID);
//Player is null, let's remove them from the list. //Player is null, let's remove them from the list.
@ -1168,17 +1175,17 @@ public class MobAI {
//target is listed individually //target is listed individually
if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) if (entry.getValue().playerUID == target.getObjectUUID() && entry.getValue().active)
return false; return false;
//target's guild is listed //target's guild is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild())
return false; return false;
//target's nation is listed //target's nation is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild().getNation())
return false; return false;
} }
return true; return true;
@ -1190,17 +1197,17 @@ public class MobAI {
//target is listed individually //target is listed individually
if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) if (entry.getValue().playerUID == target.getObjectUUID() && entry.getValue().active)
return true; return true;
//target's guild is listed //target's guild is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild())
return true; return true;
//target's nation is listed //target's nation is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild().getNation())
return true; return true;
} }
} }
@ -1256,7 +1263,7 @@ public class MobAI {
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e);
} }
} }
@ -1273,7 +1280,7 @@ public class MobAI {
for (Entry playerEntry : mob.playerAgroMap.entrySet()) { for (Entry playerEntry : mob.playerAgroMap.entrySet()) {
PlayerCharacter potentialTarget = PlayerCharacter.getFromCache((int) playerEntry.getKey()); PlayerCharacter potentialTarget = PlayerCharacter.getPlayerCharacter((int) playerEntry.getKey());
if (potentialTarget.equals(mob.getCombatTarget())) if (potentialTarget.equals(mob.getCombatTarget()))
continue; continue;

6
src/engine/mobileAI/utilities/MovementUtilities.java

@ -51,7 +51,7 @@ public class MovementUtilities {
//Guards recall distance = 814. //Guards recall distance = 814.
if (tol != null) { if (tol != null) {
return !(agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.ZONE.extents)); return !(agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.ZONE.halfExtents));
} }
} }
@ -68,8 +68,8 @@ public class MovementUtilities {
float zoneRange = 250; float zoneRange = 250;
if (agent.getParentZone() != null) { if (agent.getParentZone() != null) {
if (agent.getParentZone().getBounds() != null) if (agent.getParentZone().bounds != null)
zoneRange = agent.getParentZone().getBounds().getHalfExtents().x * 2; zoneRange = agent.getParentZone().bounds.getHalfExtents().x * 2;
} }
if (zoneRange > 300) if (zoneRange > 300)

6
src/engine/net/client/ClientMessagePump.java

@ -1196,7 +1196,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (npc.getCharItemManager().getInventoryCount() > 150) { if (npc.getCharItemManager().getInventoryCount() > 150) {
if (npc.getParentZone() != null && npc.getParentZone().getPlayerCityUUID() == 0) { if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID == 0) {
ArrayList<Item> inv = npc.getInventory(); ArrayList<Item> inv = npc.getInventory();
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
try { try {
@ -1229,7 +1229,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (ib == null) if (ib == null)
return; return;
if (npc.getParentZone() != null && npc.getParentZone().getPlayerCityUUID() != 0) if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
if (!npc.getCharItemManager().hasRoomInventory(ib.getWeight())) { if (!npc.getCharItemManager().hasRoomInventory(ib.getWeight())) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
@ -1280,7 +1280,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (building != null && building.getProtectionState().equals(ProtectionState.NPC)) if (building != null && building.getProtectionState().equals(ProtectionState.NPC))
building = null; building = null;
if (npc.getParentZone().getPlayerCityUUID() == 0) if (npc.getParentZone().playerCityUUID == 0)
building = null; building = null;
//make sure npc can afford item //make sure npc can afford item

2
src/engine/net/client/handlers/AbandonAssetMsgHandler.java

@ -151,7 +151,7 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler {
cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc()); cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc());
// Can't abandon a tree not within a player city zone // Can't abandon a tree not within a player city zone
if (cityZone.isPlayerCity() == false) if (cityZone.guild_zone == false)
return; return;
if (targetBuilding.getCity() == null) if (targetBuilding.getCity() == null)

2
src/engine/net/client/handlers/AssetSupportMsgHandler.java

@ -45,7 +45,7 @@ public class AssetSupportMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return; return;
serverCity = City.GetCityFromCache(serverZone.getPlayerCityUUID()); serverCity = City.GetCityFromCache(serverZone.playerCityUUID);
if (serverCity == null) if (serverCity == null)
return; return;

2
src/engine/net/client/handlers/ChannelMuteMsgHandler.java

@ -65,7 +65,7 @@ public class ChannelMuteMsgHandler extends AbstractClientMsgHandler {
cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc()); cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc());
// Can't abandon a tree not within a player city zone // Can't abandon a tree not within a player city zone
if (cityZone.isPlayerCity() == false) if (cityZone.guild_zone == false)
return; return;
if (targetBuilding.getCity().hasBeenTransfered == true) { if (targetBuilding.getCity().hasBeenTransfered == true) {

4
src/engine/net/client/handlers/ClaimGuildTreeMsgHandler.java

@ -69,7 +69,7 @@ public class ClaimGuildTreeMsgHandler extends AbstractClientMsgHandler {
playerZone = building.getParentZone(); playerZone = building.getParentZone();
if (playerZone != null) if (playerZone != null)
playerCity = City.getCity(playerZone.getPlayerCityUUID()); playerCity = City.getCity(playerZone.playerCityUUID);
// Oops! *** Refactor: Log error // Oops! *** Refactor: Log error
switch (msg.getMessageType()) { switch (msg.getMessageType()) {
@ -117,7 +117,7 @@ public class ClaimGuildTreeMsgHandler extends AbstractClientMsgHandler {
dispatch = Dispatch.borrow(sourcePlayer, gtsm); dispatch = Dispatch.borrow(sourcePlayer, gtsm);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
CityZoneMsg czm = new CityZoneMsg(2, playerZone.getLoc().x, playerZone.getLoc().y, playerZone.getLoc().z, playerCity.getCityName(), playerZone, Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents); CityZoneMsg czm = new CityZoneMsg(2, playerZone.getLoc().x, playerZone.getLoc().y, playerZone.getLoc().z, playerCity.getCityName(), playerZone, Enum.CityBoundsType.ZONE.halfExtents, Enum.CityBoundsType.ZONE.halfExtents);
DispatchMessage.dispatchMsgToAll(czm); DispatchMessage.dispatchMsgToAll(czm);
break; break;

2
src/engine/net/client/handlers/DestroyBuildingHandler.java

@ -95,7 +95,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
city.setWarehouseBuildingID(0); city.setWarehouseBuildingID(0);
} }
building.setRank(-1); BuildingManager.setRank(building, -1);
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().zoneBuildingSet.remove(building); building.getParentZone().zoneBuildingSet.remove(building);

6
src/engine/net/client/handlers/ManageCityAssetMsgHandler.java

@ -75,12 +75,12 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
Zone zone = ZoneManager.findSmallestZone(player.getLoc()); Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
return true; return true;
} }
City city = City.GetCityFromCache(zone.getPlayerCityUUID()); City city = City.GetCityFromCache(zone.playerCityUUID);
if (city == null) { if (city == null) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
@ -254,7 +254,7 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
if (baneZone == null) if (baneZone == null)
return true; return true;
City banedCity = City.getCity(baneZone.getPlayerCityUUID()); City banedCity = City.getCity(baneZone.playerCityUUID);
if (banedCity == null) if (banedCity == null)
return true; return true;

4
src/engine/net/client/handlers/ObjectActionMsgHandler.java

@ -182,7 +182,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
realm.claimRealmForCity(city, charterUUID); realm.claimRealmForCity(city, charterUUID);
tol.setRank(8); BuildingManager.setRank(tol, 8);
WorldGrid.updateObject(tol); WorldGrid.updateObject(tol);
for (Building building : city.getParent().zoneBuildingSet) { for (Building building : city.getParent().zoneBuildingSet) {
@ -334,7 +334,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
Zone zone = ZoneManager.findSmallestZone(player.getLoc()); Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (zone != null) { if (zone != null) {
if (zone.isPlayerCity()) { if (zone.guild_zone) {
loc = zone.getLoc(); loc = zone.getLoc();
} }
} }

6
src/engine/net/client/handlers/OpenFriendsCondemnListMsgHandler.java

@ -151,7 +151,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
if (removeCondemn == null) if (removeCondemn == null)
return true; return true;
if (!DbManager.BuildingQueries.REMOVE_FROM_CONDEMNED_LIST(removeCondemn.getParent(), removeCondemn.getPlayerUID(), removeCondemn.getGuildUID(), removeCondemn.getFriendType())) if (!DbManager.BuildingQueries.REMOVE_FROM_CONDEMNED_LIST(removeCondemn.buildingUUID, removeCondemn.playerUID, removeCondemn.guildUID, removeCondemn.friendType))
return true; return true;
sourceBuilding.getCondemned().remove(msg.getRemoveFriendID()); sourceBuilding.getCondemned().remove(msg.getRemoveFriendID());
@ -175,7 +175,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
return true; return true;
condemn.setActive(msg.isReverseKOS()); condemn.setActive(msg.isReverseKOS());
openFriendsCondemnListMsg.setReverseKOS(condemn.isActive()); openFriendsCondemnListMsg.setReverseKOS(condemn.active);
dispatch = Dispatch.borrow(player, msg); dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
break; break;
@ -354,7 +354,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
if (friend == null) if (friend == null)
return true; return true;
if (!DbManager.BuildingQueries.REMOVE_FROM_FRIENDS_LIST(sourceBuilding.getObjectUUID(), friend.getPlayerUID(), friend.getGuildUID(), friend.getFriendType())) { if (!DbManager.BuildingQueries.REMOVE_FROM_FRIENDS_LIST(sourceBuilding.getObjectUUID(), friend.playerUID, friend.guildUID, friend.friendType)) {
Logger.debug("Failed to remove Friend: " + msg.getRemoveFriendID() + " from Building With UID " + sourceBuilding.getObjectUUID()); Logger.debug("Failed to remove Friend: " + msg.getRemoveFriendID() + " from Building With UID " + sourceBuilding.getObjectUUID());
return true; return true;
} }

2
src/engine/net/client/handlers/OrderNPCMsgHandler.java

@ -288,7 +288,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (zone == null) if (zone == null)
return false; return false;
if (zone.getPlayerCityUUID() == 0) if (zone.playerCityUUID == 0)
return false; return false;
City city = building.getCity(); City city = building.getCity();

77
src/engine/net/client/handlers/PlaceAssetMsgHandler.java

@ -2,7 +2,6 @@ package engine.net.client.handlers;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
@ -112,7 +111,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place a tree underwater // Cannot place a tree underwater
if (HeightMap.isLocUnderwater(placementInfo.getLoc())) { if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@ -138,7 +137,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) { private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
if (serverZone.isPlayerCity() == false) { if (serverZone.guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName()); PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
return false; return false;
} }
@ -157,7 +156,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Retrieve the building details we're placing // Retrieve the building details we're placing
if (serverZone.isNPCCity() == true) { if (serverZone.isNPCCity == true) {
PlaceAssetMsg.sendPlaceAssetError(origin, 15, ""); // Cannot place in a peace zone PlaceAssetMsg.sendPlaceAssetError(origin, 15, ""); // Cannot place in a peace zone
return false; return false;
} }
@ -178,7 +177,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place a building underwater // Cannot place a building underwater
if (HeightMap.isLocUnderwater(placementInfo.getLoc())) { if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@ -186,7 +185,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Players cannot place buildings in mob zones. // Players cannot place buildings in mob zones.
if ((serverZone.isMacroZone() == true) if ((serverZone.isMacroZone() == true)
|| (serverZone.getParent().isMacroZone() == true)) { || (serverZone.parent.isMacroZone() == true)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory
return false; return false;
} }
@ -202,8 +201,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place assets on a dead tree // Cannot place assets on a dead tree
if ((serverZone.isPlayerCity()) if ((serverZone.guild_zone)
&& (City.getCity(serverZone.getPlayerCityUUID()).getTOL().getRank() == -1)) { && (City.getCity(serverZone.playerCityUUID).getTOL().getRank() == -1)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot place asset on dead tree until world heals"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot place asset on dead tree until world heals");
return false; return false;
} }
@ -262,14 +261,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Must be a player city // Must be a player city
if (serverZone.isPlayerCity() == false) { if (serverZone.guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); // Cannot place outside a guild zone PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); // Cannot place outside a guild zone
return false; return false;
} }
//Test zone has a city object //Test zone has a city object
City city = City.getCity(serverZone.getPlayerCityUUID()); City city = City.getCity(serverZone.playerCityUUID);
if (city == null) { if (city == null) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); //"no city to associate asset with" PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); //"no city to associate asset with"
@ -513,7 +512,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Early exit if something went horribly wrong // Early exit if something went horribly wrong
@ -572,7 +571,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// No valid player city found // No valid player city found
if (serverCity == null || serverCity.getParent().isPlayerCity() == false) { if (serverCity == null || serverCity.getParent().guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); // Cannot place outisde a guild zone PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); // Cannot place outisde a guild zone
return false; return false;
} }
@ -661,7 +660,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (!building.getBlueprint().isSiegeEquip()) if (!building.getBlueprint().isSiegeEquip())
continue; continue;
if (!building.getLoc().isInsideCircle(serverCity.getLoc(), CityBoundsType.ZONE.extents)) if (!building.getLoc().isInsideCircle(serverCity.getLoc(), CityBoundsType.ZONE.halfExtents))
continue; continue;
if (building.getGuild() == null) if (building.getGuild() == null)
@ -750,8 +749,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(), cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(),
serverRealm.getRealmID(), serverRealm.getRealmID(),
plantLoc.x - serverZone.getAbsX(), plantLoc.y, plantLoc.x - serverZone.absX, plantLoc.y,
plantLoc.z - serverZone.getAbsZ(), treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now()); plantLoc.z - serverZone.absZ, treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now());
// Uh oh! // Uh oh!
@ -781,37 +780,19 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
playerNation = playerCharacter.getGuild(); playerNation = playerCharacter.getGuild();
playerNation.setGuildState(GuildState.Sovereign); playerNation.setGuildState(GuildState.Sovereign);
// Link the zone with the city and then add // Update guild binds and tags
// to the appropriate hash tables and cache
zoneObject.setPlayerCity(true);
if (zoneObject.getParent() != null)
zoneObject.getParent().addNode(zoneObject); //add as child to parent
ZoneManager.addZone(zoneObject.getObjectUUID(), zoneObject);
ZoneManager.addPlayerCityZone(zoneObject);
serverZone.addNode(zoneObject);
zoneObject.worldAltitude = ZoneManager.caclulateWorldAltitude(zoneObject);
cityObject.setParent(zoneObject);
cityObject.setObjectTypeMask(MBServerStatics.MASK_CITY); // *** Refactor : should have it already
//Link the tree of life with the new zone
treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING); GuildManager.updateAllGuildBinds(playerNation, cityObject);
treeObject.setParentZone(zoneObject); GuildManager.updateAllGuildTags(playerNation);
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7));
// Update guild binds and tags
//load the new city on the clients //load the new city on the clients
CityZoneMsg czm = new CityZoneMsg(1, treeObject.getLoc().x, treeObject.getLoc().y, treeObject.getLoc().z, cityObject.getCityName(), zoneObject, Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents); CityZoneMsg czm = new CityZoneMsg(1, treeObject.getLoc().x, treeObject.getLoc().y, treeObject.getLoc().z, cityObject.getCityName(), zoneObject, Enum.CityBoundsType.ZONE.halfExtents, Enum.CityBoundsType.ZONE.halfExtents);
DispatchMessage.dispatchMsgToAll(czm); DispatchMessage.dispatchMsgToAll(czm);
GuildManager.updateAllGuildBinds(playerNation, cityObject); // Set maintenance date
GuildManager.updateAllGuildTags(playerNation);
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7));
// Send all the cities to the clients? // Send all the cities to the clients?
// *** Refactor : figure out how to send like, one? // *** Refactor : figure out how to send like, one?
@ -858,7 +839,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
if (cityObject == null) if (cityObject == null)
return false; return false;
@ -932,7 +913,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
int shrineCount = 0; int shrineCount = 0;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Cannot place shrine in abandoned city. Shrines must be owned // Cannot place shrine in abandoned city. Shrines must be owned
// by the tol owner not the person placing them. // by the tol owner not the person placing them.
@ -1002,7 +983,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
int barracksCount = 0; int barracksCount = 0;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Cannot place barracks in abandoned city. // Cannot place barracks in abandoned city.
@ -1062,7 +1043,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (validateCityBuildingPlacement(serverZone, msg, origin, player, msg.getFirstPlacementInfo()) == false) if (validateCityBuildingPlacement(serverZone, msg, origin, player, msg.getFirstPlacementInfo()) == false)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// We need to be able to access how much gold a character is carrying // We need to be able to access how much gold a character is carrying
@ -1118,7 +1099,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
building.removeFromCache(); building.removeFromCache();
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().getParent().zoneBuildingSet.remove(building); building.getParentZone().parent.zoneBuildingSet.remove(building);
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) { if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) {
building.RemoveFromBarracksList(); building.RemoveFromBarracksList();
} }
@ -1230,7 +1211,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
shrineType = Shrine.getShrineTypeByBlueprintUUID(blueprint.getBlueprintUUID()); shrineType = Shrine.getShrineTypeByBlueprintUUID(blueprint.getBlueprintUUID());
city = City.getCity(currentZone.getPlayerCityUUID()); city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return false; return false;
@ -1295,7 +1276,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
city = City.getCity(currentZone.getPlayerCityUUID()); city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return false; return false;
@ -1370,7 +1351,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
newMesh.runAfterLoad(); newMesh.runAfterLoad();
} else if (ago.getObjectType() == GameObjectType.Warehouse) { } else if (ago.getObjectType() == GameObjectType.Warehouse) {
Warehouse warehouse = (Warehouse) ago; Warehouse warehouse = (Warehouse) ago;
City city = City.getCity(currentZone.getPlayerCityUUID()); City city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return true; return true;

4
src/engine/net/client/handlers/RepairBuildingMsgHandler.java

@ -44,11 +44,11 @@ public class RepairBuildingMsgHandler extends AbstractClientMsgHandler {
serverZone = ZoneManager.findSmallestZone(pc.getLoc()); serverZone = ZoneManager.findSmallestZone(pc.getLoc());
if (serverZone.getPlayerCityUUID() == 0 && targetBuilding.getBlueprint() != null && targetBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.MINE) if (serverZone.playerCityUUID == 0 && targetBuilding.getBlueprint() != null && targetBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.MINE)
return; return;
City city = City.GetCityFromCache(serverZone.getPlayerCityUUID()); City city = City.GetCityFromCache(serverZone.playerCityUUID);
if (city != null) { if (city != null) {
if (city.getBane() != null && city.protectionEnforced == false) if (city.getBane() != null && city.protectionEnforced == false)

1
src/engine/net/client/handlers/RequestEnterWorldHandler.java

@ -110,7 +110,6 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
player.stopMovement(player.getBindLoc()); player.stopMovement(player.getBindLoc());
player.setSafeMode(); player.setSafeMode();
player.updateLocation(); player.updateLocation();
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
} }
player.setTimeStamp("logout", 0); player.setTimeStamp("logout", 0);

2
src/engine/net/client/msg/CityAssetMsg.java

@ -92,7 +92,7 @@ public class CityAssetMsg extends ClientNetMsg {
return; return;
} }
city = City.getCity(zone.getPlayerCityUUID()); city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
Logger.debug("Failed to load city data for Tree of life."); Logger.debug("Failed to load city data for Tree of life.");

4
src/engine/net/client/msg/GuildTreeStatusMsg.java

@ -117,8 +117,8 @@ public class GuildTreeStatusMsg extends ClientNetMsg {
city = null; city = null;
if (cityZone != null) if (cityZone != null)
if (cityZone.isPlayerCity()) if (cityZone.guild_zone)
city = City.GetCityFromCache(cityZone.getPlayerCityUUID()); city = City.GetCityFromCache(cityZone.playerCityUUID);
else if (this.treeOfLife != null && this.treeOfLife.getGuild() != null) else if (this.treeOfLife != null && this.treeOfLife.getGuild() != null)
city = this.treeOfLife.getGuild().getOwnedCity(); city = this.treeOfLife.getGuild().getOwnedCity();

12
src/engine/net/client/msg/ManageCityAssetsMsg.java

@ -299,8 +299,8 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
Set<Building> buildings = ZoneManager.findSmallestZone(assetManager.getLoc()).zoneBuildingSet; Set<Building> buildings = ZoneManager.findSmallestZone(assetManager.getLoc()).zoneBuildingSet;
Building tol = null; Building tol = null;
if (playerZone.getPlayerCityUUID() != 0) if (playerZone.playerCityUUID != 0)
city = City.GetCityFromCache(playerZone.getPlayerCityUUID()); city = City.GetCityFromCache(playerZone.playerCityUUID);
if (city != null) if (city != null)
tol = city.getTOL(); tol = city.getTOL();
@ -368,7 +368,7 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
if (zone == null) if (zone == null)
return; return;
City banedCity = City.getCity(zone.getPlayerCityUUID()); City banedCity = City.getCity(zone.playerCityUUID);
if (banedCity == null) if (banedCity == null)
return; return;
@ -479,7 +479,7 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
if (zone == null) if (zone == null)
writer.putString("Forlord"); writer.putString("Forlord");
else else
writer.putString(zone.getName()); writer.putString(zone.zoneName);
writer.putString(building.getGuild().getName()); writer.putString(building.getGuild().getName());
@ -621,9 +621,9 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
} else { } else {
writer.putInt(1); //kos on/off? writer.putInt(1); //kos on/off?
writer.putInt(3); // was 3 writer.putInt(3); // was 3
if (zone.getPlayerCityUUID() != 0 && asset.assetIsProtected()) { if (zone.playerCityUUID != 0 && asset.assetIsProtected()) {
writer.putInt(GameObjectType.Building.ordinal()); writer.putInt(GameObjectType.Building.ordinal());
writer.putInt(City.getCity(zone.getPlayerCityUUID()).getTOL().getObjectUUID()); writer.putInt(City.getCity(zone.playerCityUUID).getTOL().getObjectUUID());
} else { } else {
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);

48
src/engine/net/client/msg/OpenFriendsCondemnListMsg.java

@ -513,17 +513,17 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.put((byte) 1); writer.put((byte) 1);
switch (condemned.getFriendType()) { switch (condemned.friendType) {
case 2: case 2:
PlayerCharacter playerCharacter = (PlayerCharacter) DbManager.getObject(engine.Enum.GameObjectType.PlayerCharacter, condemned.getPlayerUID()); PlayerCharacter playerCharacter = (PlayerCharacter) DbManager.getObject(engine.Enum.GameObjectType.PlayerCharacter, condemned.playerUID);
guild = playerCharacter.getGuild(); guild = playerCharacter.getGuild();
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(condemned.getPlayerUID()); writer.putInt(condemned.playerUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(condemned.getPlayerUID()); writer.putInt(condemned.playerUID);
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
@ -531,9 +531,9 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.putInt(guild.getObjectUUID()); writer.putInt(guild.getObjectUUID());
else else
writer.putInt(0); writer.putInt(0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
if (playerCharacter != null) if (playerCharacter != null)
writer.putString(playerCharacter.getFirstName()); writer.putString(playerCharacter.getFirstName());
@ -547,16 +547,16 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
} }
break; break;
case 4: case 4:
guild = Guild.getGuild(condemned.getGuildUID()); guild = Guild.getGuild(condemned.guildUID);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putLong(0); writer.putLong(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putLong(0); writer.putLong(0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
if (guild != null) if (guild != null)
writer.putString(guild.getName()); writer.putString(guild.getName());
@ -570,17 +570,17 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
GuildTag._serializeForDisplay(GuildTag.ERRANT, writer); GuildTag._serializeForDisplay(GuildTag.ERRANT, writer);
break; break;
case 5: case 5:
guild = Guild.getGuild(condemned.getGuildUID()); guild = Guild.getGuild(condemned.guildUID);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putLong(0); writer.putLong(0);
writer.putLong(0); writer.putLong(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
if (guild != null) if (guild != null)
writer.putString(guild.getName()); writer.putString(guild.getName());
else else
@ -619,22 +619,22 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.putInt(listSize); writer.putInt(listSize);
for (BuildingFriends friend : this.friends.values()) { for (BuildingFriends friend : this.friends.values()) {
pc = PlayerCharacter.getFromCache(friend.getPlayerUID()); pc = PlayerCharacter.getFromCache(friend.playerUID);
guild = Guild.getGuild(friend.getGuildUID()); guild = Guild.getGuild(friend.guildUID);
if (friend.getFriendType() == 7) { if (friend.friendType == 7) {
if (pc != null) if (pc != null)
name = pc.getCombinedName(); name = pc.getCombinedName();
} else if (guild != null) } else if (guild != null)
name = guild.getName(); name = guild.getName();
writer.put((byte) 1); writer.put((byte) 1);
if (friend.getFriendType() == 7) { if (friend.friendType == 7) {
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(friend.getPlayerUID()); writer.putInt(friend.playerUID);
} else { } else {
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(friend.getGuildUID()); writer.putInt(friend.guildUID);
} }
writer.putInt(friend.getFriendType()); writer.putInt(friend.friendType);
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);

151
src/engine/net/client/msg/SyncMessage.java

@ -1,151 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net.client.msg;
import engine.exception.SerializationException;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.net.AbstractConnection;
import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter;
import engine.net.client.Protocol;
import engine.objects.Building;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
public class SyncMessage extends ClientNetMsg {
private int type;
private int size;
private int pad = 0;
private int objectType;
private int objectUUID;
/**
* This constructor is used by NetMsgFactory. It attempts to deserialize the
* ByteBuffer into a message. If a BufferUnderflow occurs (based on reading
* past the limit) then this constructor Throws that Exception to the
* caller.
*/
public SyncMessage(AbstractConnection origin, ByteBufferReader reader) {
super(Protocol.CITYASSET, origin, reader);
}
public SyncMessage() {
super(Protocol.CITYASSET);
}
/**
* Deserializes the subclass specific items from the supplied NetMsgReader.
*/
@Override
protected void _deserialize(ByteBufferReader reader) {
//none yet
}
/**
* Serializes the subclass specific items to the supplied NetMsgWriter.
*/
@Override
protected void _serialize(ByteBufferWriter writer) throws SerializationException {
//lets do returns before writing so we don't send improper structures to the client
Building tol = BuildingManager.getBuilding(this.objectUUID);
if (tol == null) {
Logger.debug("TOL is null");
return;
}
Zone zone = ZoneManager.findSmallestZone(tol.getLoc());
if (zone == null) {
Logger.debug("Zone is null");
return;
}
ArrayList<Building> allCityAssets = DbManager.BuildingQueries.GET_ALL_BUILDINGS_FOR_ZONE(zone);
// *** Refactor: collection created but never used?
ArrayList<Building> canProtectAssets = new ArrayList<>();
for (Building b : allCityAssets) {
if (b.getBlueprintUUID() != 0)
canProtectAssets.add(b);
}
// *** Refactor : Not sure what this synch message does
// Get the feeling it should be looping over upgradable
// assets.
writer.putInt(0);
writer.putInt(0);
writer.putInt(this.objectType);
writer.putInt(this.objectUUID);
writer.putInt(allCityAssets.size());
for (Building b : allCityAssets) {
String name = b.getName();
// if (name.equals(""))
// name = b.getBuildingSet().getName();
writer.putInt(b.getObjectType().ordinal());
writer.putInt(b.getObjectUUID());
writer.putString(b.getName()); // Blueprint name?
writer.putString(b.getGuild().getName());
writer.putInt(20);// \/ Temp \/
writer.putInt(b.getRank());
writer.putInt(1); // symbol
writer.putInt(7); //TODO identify these Guild tags??
writer.putInt(17);
writer.putInt(14);
writer.putInt(14);
writer.putInt(98);// /\ Temp /\
}
}
public int getObjectType() {
return objectType;
}
public void setObjectType(int value) {
this.objectType = value;
}
public int getUUID() {
return objectUUID;
}
public int getPad() {
return pad;
}
public void setPad(int value) {
this.pad = value;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}

2
src/engine/net/client/msg/ViewResourcesMessage.java

@ -73,7 +73,7 @@ public class ViewResourcesMessage extends ClientNetMsg {
if (this.warehouseBuilding.getParentZone() == null) if (this.warehouseBuilding.getParentZone() == null)
return false; return false;
this.city = (City) DbManager.getObject(Enum.GameObjectType.City, this.warehouseBuilding.getParentZone().getPlayerCityUUID()); this.city = (City) DbManager.getObject(Enum.GameObjectType.City, this.warehouseBuilding.getParentZone().playerCityUUID);
if (this.city == null) if (this.city == null)
return false; return false;

17
src/engine/net/client/msg/WorldDataMsg.java

@ -10,8 +10,10 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.ConfigManager; import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
import engine.net.AbstractNetMsg; import engine.net.AbstractNetMsg;
@ -44,14 +46,9 @@ public class WorldDataMsg extends ClientNetMsg {
super(Protocol.NEWWORLD, origin, reader); super(Protocol.NEWWORLD, origin, reader);
} }
private static int getTotalMapSize(Zone root) { private static int getTotalMapSize() {
if (root.getNodes().isEmpty())
return 0;
int size = root.getNodes().size(); return DbManager.getList(Enum.GameObjectType.Zone).size();
for (Zone child : root.getNodes())
size += getTotalMapSize(child);
return size;
} }
/** /**
@ -73,7 +70,7 @@ public class WorldDataMsg extends ClientNetMsg {
// TODO replace this return with SerializationException // TODO replace this return with SerializationException
Zone root = ZoneManager.getSeaFloor(); Zone root = ZoneManager.seaFloor;
if (root == null) { if (root == null) {
Logger.error("Failed to find Sea Floor!"); Logger.error("Failed to find Sea Floor!");
return; return;
@ -86,11 +83,10 @@ public class WorldDataMsg extends ClientNetMsg {
writer.putInt(WorldServer.worldMapID); writer.putInt(WorldServer.worldMapID);
writer.putInt(0x00000000); writer.putInt(0x00000000);
writer.putInt(getTotalMapSize(root) + 1); writer.putInt(getTotalMapSize());
Zone.serializeForClientMsg(root, writer); Zone.serializeForClientMsg(root, writer);
Zone hotzone = ZoneManager.hotZone; Zone hotzone = ZoneManager.hotZone;
;
if (hotzone == null) if (hotzone == null)
writer.putLong(0L); writer.putLong(0L);
@ -99,7 +95,6 @@ public class WorldDataMsg extends ClientNetMsg {
writer.putInt(hotzone.getObjectUUID()); writer.putInt(hotzone.getObjectUUID());
} }
writer.putFloat(0); writer.putFloat(0);
writer.putFloat(1); writer.putFloat(1);
writer.putFloat(0); writer.putFloat(0);

42
src/engine/objects/AbstractCharacter.java

@ -12,6 +12,7 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.*; import engine.gameManager.*;
@ -26,6 +27,7 @@ import engine.math.Bounds;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.UpdateStateMsg; import engine.net.client.msg.UpdateStateMsg;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
@ -121,6 +123,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public int hidden = 0; // current rank of hide/sneak/invis public int hidden = 0; // current rank of hide/sneak/invis
public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList(); public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList();
public ArrayList<CharacterRune> runes;
public AbstractCharacter() { public AbstractCharacter() {
super(); super();
this.firstName = ""; this.firstName = "";
@ -512,10 +516,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) { public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
worldObject.locationLock.writeLock().lock(); worldObject.locationLock.writeLock().lock();
try { try {
MovementManager.translocate(worldObject, targetLoc, targetRegion); MovementManager.translocate(worldObject, targetLoc);
if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter)) if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject); InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject);
} catch (Exception e) { } catch (Exception e) {
@ -983,8 +986,38 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
@Override @Override
public final void setLoc(final Vector3fImmutable value) { public final void setLoc(final Vector3fImmutable value) {
super.setLoc(value); // set the location in the world
Building building = BuildingManager.getBuildingAtLocation(this.loc);
Regions region = null;
if(building != null) {
//look for region in the building we are in
for (Regions regionCycle : building.getBounds().getRegions()) {
float regionHeight = regionCycle.highLerp.y - regionCycle.lowLerp.y;
if(regionHeight < 10)
regionHeight = 10;
if (regionCycle.isPointInPolygon(value) && Math.abs(regionCycle.highLerp.y - value.y) < regionHeight)
region = regionCycle;
}
}
float regionHeightOffset = 0;
if(region != null){
this.region = region;
regionHeightOffset = region.lerpY(this);
this.inBuilding = region.level; // -1 not in building 0 on ground floor, 1 on first floor etc
this.inBuildingID = region.parentBuildingID;
this.inFloorID = region.room;
} else {
this.region = null;
this.inBuilding = -1;
this.inBuildingID = 0;
this.inFloorID = -1;
}
float terrainHeight = Terrain.getWorldHeight(value);
Vector3fImmutable finalLocation = new Vector3fImmutable(value.x,terrainHeight + regionHeightOffset, value.z);
super.setLoc(finalLocation); // set the location in the world
this.resetLastSetLocUpdate(); this.resetLastSetLocUpdate();
} }
public Vector3fImmutable getMovementLoc() { public Vector3fImmutable getMovementLoc() {
@ -1449,10 +1482,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public void teleport(final Vector3fImmutable targetLoc) { public void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock(); locationLock.writeLock().lock();
try { try {
MovementManager.translocate(this, targetLoc, targetRegion); MovementManager.translocate(this, targetLoc);
MovementManager.sendRWSSMsg(this); MovementManager.sendRWSSMsg(this);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);

2
src/engine/objects/AbstractIntelligenceAgent.java

@ -130,7 +130,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc()); ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc());
for (Zone zone : allIn) for (Zone zone : allIn)
if (zone.getSafeZone() == (byte) 1) if (zone.peace_zone == (byte) 1)
return true; return true;
return false; return false;

13
src/engine/objects/AbstractWorldObject.java

@ -13,7 +13,7 @@ import engine.Enum.DispatchChannel;
import engine.Enum.EffectSourceType; import engine.Enum.EffectSourceType;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.GridObjectType; import engine.Enum.GridObjectType;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.job.JobContainer; import engine.job.JobContainer;
@ -502,7 +502,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
return; return;
this.lastLoc = new Vector3fImmutable(this.loc); this.lastLoc = new Vector3fImmutable(this.loc);
this.loc = loc; this.loc = loc;
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude());
if(this instanceof AbstractCharacter && this.region != null){
this.loc = this.loc.setY(this.region.lerpY(this) + this.getAltitude());
} else{
this.loc = this.loc.setY(Terrain.getWorldHeight(this.getLoc()) + this.getAltitude());
}
//lets not add mob to world grid if he is currently despawned. //lets not add mob to world grid if he is currently despawned.
if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned) if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned)
@ -610,9 +616,6 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
this.movingUp = movingUp; this.movingUp = movingUp;
} }
public void setRegion(Regions region) {
this.region = region;
}
//used for interestmanager loading and unloading objects to client. //used for interestmanager loading and unloading objects to client.
// if not in grid, unload from player. // if not in grid, unload from player.

7
src/engine/objects/Bane.java

@ -13,7 +13,6 @@ import engine.Enum;
import engine.Enum.ProtectionState; import engine.Enum.ProtectionState;
import engine.Enum.SiegePhase; import engine.Enum.SiegePhase;
import engine.Enum.SiegeResult; import engine.Enum.SiegeResult;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.BaneRecord; import engine.db.archive.BaneRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
@ -135,7 +134,7 @@ public final class Bane {
// Cannot place banestone underwater; // Cannot place banestone underwater;
if (HeightMap.isLocUnderwater(player.getLoc())) { if (ZoneManager.isLocUnderwater(player.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@ -163,8 +162,8 @@ public final class Bane {
// Cannot place assets on a dead tree // Cannot place assets on a dead tree
if ((cityZone.isPlayerCity()) && if ((cityZone.guild_zone) &&
(City.getCity(cityZone.getPlayerCityUUID()).getTOL().getRank() == -1)) { (City.getCity(cityZone.playerCityUUID).getTOL().getRank() == -1)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot bane a dead tree!"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot bane a dead tree!");
return false; return false;
} }

402
src/engine/objects/Building.java

@ -11,8 +11,8 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
@ -55,6 +55,7 @@ public class Building extends AbstractWorldObject {
private final HashMap<Integer, DoorCloseJob> doorJobs = new HashMap<>(); private final HashMap<Integer, DoorCloseJob> doorJobs = new HashMap<>();
public int meshUUID; public int meshUUID;
public Zone parentZone; public Zone parentZone;
public int parentZoneUUID;
public boolean reverseKOS; public boolean reverseKOS;
public int reserve = 0; public int reserve = 0;
public float statLat; public float statLat;
@ -62,7 +63,6 @@ public class Building extends AbstractWorldObject {
public float statAlt; public float statAlt;
public LocalDateTime upgradeDateTime = null; public LocalDateTime upgradeDateTime = null;
public LocalDateTime taxDateTime = null; public LocalDateTime taxDateTime = null;
public ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>();
public ArrayList<Vector3fImmutable> sentryPoints = new ArrayList<>(); public ArrayList<Vector3fImmutable> sentryPoints = new ArrayList<>();
public TaxType taxType = TaxType.NONE; public TaxType taxType = TaxType.NONE;
public int taxAmount; public int taxAmount;
@ -75,11 +75,14 @@ public class Building extends AbstractWorldObject {
public int level; public int level;
public AtomicBoolean isDeranking = new AtomicBoolean(false); public AtomicBoolean isDeranking = new AtomicBoolean(false);
public LocalDateTime maintDateTime; public LocalDateTime maintDateTime;
protected Resists resists;
/* The Blueprint class has methods able to derive /* The Blueprint class has methods able to derive
* all defining characteristics of this building, * all defining characteristics of this building,
*/ */
private int blueprintUUID = 0; public int blueprintUUID = 0;
public int rank;
public ArrayList<Vector3fImmutable> patrolPoints;
public ProtectionState protectionState = ProtectionState.NONE;
protected Resists resists;
private float w = 1.0f; private float w = 1.0f;
private Vector3f meshScale = new Vector3f(1.0f, 1.0f, 1.0f); private Vector3f meshScale = new Vector3f(1.0f, 1.0f, 1.0f);
private int doorState = 0; private int doorState = 0;
@ -88,14 +91,12 @@ public class Building extends AbstractWorldObject {
private int maxGold; private int maxGold;
private int effectFlags = 0; private int effectFlags = 0;
private String name = ""; private String name = "";
private int rank;
private boolean ownerIsNPC = true; private boolean ownerIsNPC = true;
private boolean spireIsActive = false; private boolean spireIsActive = false;
private ConcurrentHashMap<String, JobContainer> timers = null; private ConcurrentHashMap<String, JobContainer> timers = null;
private ConcurrentHashMap<String, Long> timestamps = null; private ConcurrentHashMap<String, Long> timestamps = null;
private ConcurrentHashMap<Integer, BuildingFriends> friends = new ConcurrentHashMap<>(); private ConcurrentHashMap<Integer, BuildingFriends> friends;
private ConcurrentHashMap<Integer, Condemned> condemned = new ConcurrentHashMap<>(); private ConcurrentHashMap<Integer, Condemned> condemned;
private ProtectionState protectionState = ProtectionState.NONE;
private ArrayList<Building> children = null; private ArrayList<Building> children = null;
/** /**
@ -106,27 +107,23 @@ public class Building extends AbstractWorldObject {
super(rs); super(rs);
float scale; float scale;
Blueprint blueprint = null;
try { try {
this.meshUUID = rs.getInt("meshUUID"); this.meshUUID = rs.getInt("meshUUID");
this.setObjectTypeMask(MBServerStatics.MASK_BUILDING); this.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
this.blueprintUUID = rs.getInt("blueprintUUID"); this.blueprintUUID = rs.getInt("blueprintUUID");
this.gridObjectType = GridObjectType.STATIC; this.gridObjectType = GridObjectType.STATIC;
this.parentZone = DbManager.ZoneQueries.GET_BY_UID(rs.getLong("parent")); this.parentZoneUUID = rs.getInt("parent");
this.name = rs.getString("name"); this.name = rs.getString("name");
this.ownerUUID = rs.getInt("ownerUUID"); this.ownerUUID = rs.getInt("ownerUUID");
// Orphaned Object Sanity Check
//This was causing ABANDONED Tols.
// if (objectType == DbObjectType.INVALID)
// this.ownerUUID = 0;
this.doorState = rs.getInt("doorState"); this.doorState = rs.getInt("doorState");
this.setHealth(rs.getInt("currentHP")); this.setHealth(rs.getInt("currentHP"));
this.w = rs.getFloat("w"); this.w = rs.getFloat("w");
this.setRot(new Vector3f(0f, rs.getFloat("rotY"), 0f)); this.setRot(new Vector3f(0f, rs.getFloat("rotY"), 0f));
this.reverseKOS = rs.getByte("reverseKOS") == 1 ? true : false; this.reverseKOS = rs.getByte("reverseKOS") == 1;
this.statLat = rs.getFloat("locationX");
this.statAlt = rs.getFloat("locationY");
this.statLon = rs.getFloat("locationZ");
scale = rs.getFloat("scale"); scale = rs.getFloat("scale");
this.meshScale = new Vector3f(scale, scale, scale); this.meshScale = new Vector3f(scale, scale, scale);
@ -143,79 +140,10 @@ public class Building extends AbstractWorldObject {
this.level = rs.getInt("level"); this.level = rs.getInt("level");
this.isFurniture = (rs.getBoolean("isFurniture")); this.isFurniture = (rs.getBoolean("isFurniture"));
// Lookup building blueprint
if (this.blueprintUUID == 0)
blueprint = Blueprint._meshLookup.get(meshUUID);
else
blueprint = this.getBlueprint();
// Log error if something went horrible wrong
if ((this.blueprintUUID != 0) && (blueprint == null))
Logger.error("Invalid blueprint for object: " + this.getObjectUUID());
// Note: We handle R8 tree edge case for mesh and health
// after city is loaded to avoid recursive result set call
// in City resulting in a stack ovreflow.
if (blueprint != null) {
// Only switch mesh for player dropped structures
if (this.blueprintUUID != 0)
this.meshUUID = blueprint.getMeshForRank(rank);
this.healthMax = blueprint.getMaxHealth(this.rank);
// If this object has no blueprint but is a blueprint
// mesh then set it's current health to max health
if (this.blueprintUUID == 0)
this.setHealth(healthMax);
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
} else {
this.healthMax = 100000; // Structures with no blueprint mesh
this.setHealth(healthMax);
}
// Null out blueprint if not needed (npc building)
if (blueprintUUID == 0)
blueprint = null;
resists = new Resists("Building");
this.statLat = rs.getFloat("locationX");
this.statAlt = rs.getFloat("locationY");
this.statLon = rs.getFloat("locationZ");
if (this.parentZone != null) {
if (this.parentBuildingID != 0) {
Building parentBuilding = BuildingManager.getBuilding(this.parentBuildingID);
if (parentBuilding != null) {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX + parentBuilding.statLat, this.statAlt + this.parentZone.absY + parentBuilding.statAlt, this.statLon + this.parentZone.absZ + parentBuilding.statLon));
} else {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX, this.statAlt + this.parentZone.absY, this.statLon + this.parentZone.absZ));
}
} else {
// Altitude of this building is derived from the heightmap engine.
Vector3fImmutable tempLoc = new Vector3fImmutable(this.statLat + this.parentZone.absX, 0, this.statLon + this.parentZone.absZ);
tempLoc = new Vector3fImmutable(tempLoc.x, HeightMap.getWorldHeight(tempLoc), tempLoc.z);
this.setLoc(tempLoc);
}
}
this._strongboxValue = rs.getInt("currentGold"); this._strongboxValue = rs.getInt("currentGold");
this.maxGold = 15000000; // *** Refactor to blueprint method this.maxGold = 15000000; // *** Refactor to blueprint method
this.reserve = rs.getInt("reserve"); this.reserve = rs.getInt("reserve");
// Does building have a protection contract?
this.taxType = TaxType.valueOf(rs.getString("taxType")); this.taxType = TaxType.valueOf(rs.getString("taxType"));
this.taxAmount = rs.getInt("taxAmount"); this.taxAmount = rs.getInt("taxAmount");
this.protectionState = ProtectionState.valueOf(rs.getString("protectionState")); this.protectionState = ProtectionState.valueOf(rs.getString("protectionState"));
@ -236,8 +164,7 @@ public class Building extends AbstractWorldObject {
this.upgradeDateTime = LocalDateTime.ofInstant(upgradeTimeStamp.toInstant(), ZoneId.systemDefault()); this.upgradeDateTime = LocalDateTime.ofInstant(upgradeTimeStamp.toInstant(), ZoneId.systemDefault());
} catch (Exception e) { } catch (Exception e) {
Logger.error("Failed for object " + this.blueprintUUID + ' ' + this.getObjectUUID() + e);
Logger.error("Failed for object " + this.blueprintUUID + ' ' + this.getObjectUUID() + e.toString());
} }
} }
@ -350,86 +277,6 @@ public class Building extends AbstractWorldObject {
return rank; return rank;
} }
public final void setRank(int newRank) {
int newMeshUUID;
boolean success;
// If this building has no blueprint then set rank and exit immediatly.
if (this.blueprintUUID == 0 || this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)) {
this.rank = newRank;
DbManager.BuildingQueries.CHANGE_RANK(this.getObjectUUID(), newRank);
return;
}
// Delete any upgrade jobs before doing anything else. It won't quite work
// if in a few lines we happen to delete this building.
JobContainer jc = this.getTimers().get("UPGRADE");
if (jc != null) {
if (!JobScheduler.getInstance().cancelScheduledJob(jc))
Logger.error("failed to cancel existing upgrade job.");
}
// Attempt write to database, or delete the building
// if we are destroying it.
if (newRank == -1)
success = DbManager.BuildingQueries.DELETE_FROM_DATABASE(this);
else
success = DbManager.BuildingQueries.updateBuildingRank(this, newRank);
if (success == false) {
Logger.error("Error writing to database UUID: " + this.getObjectUUID());
return;
}
this.isDeranking.compareAndSet(false, true);
// Change the building's rank
this.rank = newRank;
// New rank means new mesh
newMeshUUID = this.getBlueprint().getMeshForRank(this.rank);
this.meshUUID = newMeshUUID;
// New rank mean new max hitpoints.
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.setCurrentHitPoints(this.healthMax);
if (this.getUpgradeDateTime() != null)
BuildingManager.setUpgradeDateTime(this, null, 0);
// If we destroyed this building make sure to turn off
// protection
if (this.rank == -1)
this.protectionState = ProtectionState.NONE;
if ((this.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
&& (this.rank == 8))
this.meshUUID = Realm.getRealmMesh(this.getCity());
;
// update object to clients
this.refresh(true);
if (this.getBounds() != null)
this.getBounds().setBounds(this);
// Cleanup hirelings resulting from rank change
BuildingManager.cleanupHirelings(this);
this.isDeranking.compareAndSet(true, false);
}
public final int getOwnerUUID() { public final int getOwnerUUID() {
return ownerUUID; return ownerUUID;
} }
@ -446,24 +293,24 @@ public class Building extends AbstractWorldObject {
if (this.getBlueprint() != null && this.getBlueprint().isSiegeEquip() && this.protectionState.equals(ProtectionState.PROTECTED)) { if (this.getBlueprint() != null && this.getBlueprint().isSiegeEquip() && this.protectionState.equals(ProtectionState.PROTECTED)) {
if (this.getGuild() != null) { if (this.getGuild() != null) {
if (this.getGuild().getOwnedCity() != null) { if (this.getGuild().getOwnedCity() != null) {
if (this.getLoc().isInsideCircle(this.getGuild().getOwnedCity().getLoc(), CityBoundsType.ZONE.extents)) if (this.getLoc().isInsideCircle(this.getGuild().getOwnedCity().getLoc(), CityBoundsType.ZONE.halfExtents))
return this.getGuild().getOwnedCity(); return this.getGuild().getOwnedCity();
} else { } else {
Bane bane = Bane.getBaneByAttackerGuild(this.getGuild()); Bane bane = Bane.getBaneByAttackerGuild(this.getGuild());
if (bane != null) { if (bane != null) {
if (bane.getCity() != null) { if (bane.getCity() != null) {
if (this.getLoc().isInsideCircle(bane.getCity().getLoc(), CityBoundsType.ZONE.extents)) if (this.getLoc().isInsideCircle(bane.getCity().getLoc(), CityBoundsType.ZONE.halfExtents))
return bane.getCity(); return bane.getCity();
} }
} }
} }
} }
} }
if (this.parentZone.isPlayerCity() == false) if (this.parentZone.guild_zone == false)
return null; return null;
return City.getCity(this.parentZone.getPlayerCityUUID()); return City.getCity(this.parentZone.playerCityUUID);
} }
@ -538,13 +385,13 @@ public class Building extends AbstractWorldObject {
Mine.SendMineAttackMessage(this); Mine.SendMineAttackMessage(this);
City playerCity = ZoneManager.getCityAtLocation(this.loc); City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){ if (playerCity != null) {
if(this.getGuild().getNation().equals(playerCity.getTOL().getGuild().getNation())){ if (this.getGuild().getNation().equals(playerCity.getTOL().getGuild().getNation())) {
//friendly building has been attacked, add attacker to city outlaw list //friendly building has been attacked, add attacker to city outlaw list
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) if (!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
playerCity.cityOutlaws.add(attacker.getObjectUUID()); playerCity.cityOutlaws.add(attacker.getObjectUUID());
for(Mob guard : playerCity.getParent().zoneMobSet) for (Mob guard : playerCity.getParent().zoneMobSet)
if(guard.combatTarget == null) if (guard.combatTarget == null)
guard.setCombatTarget(attacker); guard.setCombatTarget(attacker);
} }
} }
@ -601,7 +448,7 @@ public class Building extends AbstractWorldObject {
MineRecord mineRecord = MineRecord.borrow(mine, attacker, RecordEventType.DESTROY); MineRecord mineRecord = MineRecord.borrow(mine, attacker, RecordEventType.DESTROY);
DataWarehouse.pushToWarehouse(mineRecord); DataWarehouse.pushToWarehouse(mineRecord);
this.setRank(-1); BuildingManager.setRank(this, -1);
this.setCurrentHitPoints((float) 1); this.setCurrentHitPoints((float) 1);
this.healthMax = (float) 1; this.healthMax = (float) 1;
this.meshUUID = this.getBlueprint().getMeshForRank(this.rank); this.meshUUID = this.getBlueprint().getMeshForRank(this.rank);
@ -624,9 +471,9 @@ public class Building extends AbstractWorldObject {
// Time to either derank or destroy the building. // Time to either derank or destroy the building.
if ((this.rank - 1) < 1) if ((this.rank - 1) < 1)
this.setRank(-1); BuildingManager.setRank(this, -1);
else else
this.setRank(this.rank - 1); BuildingManager.setRank(this, this.rank - 1);
} }
@ -684,7 +531,7 @@ public class Building extends AbstractWorldObject {
if (spireBuilding != null) { if (spireBuilding != null) {
spireBuilding.disableSpire(true); spireBuilding.disableSpire(true);
spireBuilding.setRank(-1); BuildingManager.setRank(spireBuilding, -1);
} }
} }
@ -695,7 +542,7 @@ public class Building extends AbstractWorldObject {
// Delete a random shrine // Delete a random shrine
if (shrineBuilding != null) if (shrineBuilding != null)
shrineBuilding.setRank(-1); BuildingManager.setRank(shrineBuilding, -1);
} }
if (barracksBuildings.size() > this.rank - 1) { if (barracksBuildings.size() > this.rank - 1) {
@ -705,7 +552,7 @@ public class Building extends AbstractWorldObject {
// Delete a random barrack // Delete a random barrack
if (barracksBuilding != null) if (barracksBuilding != null)
barracksBuilding.setRank(-1); BuildingManager.setRank(barracksBuilding, -1);
} }
// If the tree is R8 and deranking, we need to update it's // If the tree is R8 and deranking, we need to update it's
@ -734,7 +581,7 @@ public class Building extends AbstractWorldObject {
// Let's do so and early exit // Let's do so and early exit
if (this.rank > 1) { if (this.rank > 1) {
this.setRank(rank - 1); BuildingManager.setRank(this, rank - 1);
City.lastCityUpdate = System.currentTimeMillis(); City.lastCityUpdate = System.currentTimeMillis();
return; return;
} }
@ -852,10 +699,6 @@ public class Building extends AbstractWorldObject {
return this.meshUUID; return this.meshUUID;
} }
public final void setMeshUUID(int value) {
this.meshUUID = value;
}
public final Resists getResists() { public final Resists getResists() {
return this.resists; return this.resists;
} }
@ -942,13 +785,8 @@ public class Building extends AbstractWorldObject {
DispatchMessage.sendToAllInRange(this, applyBuildingEffectMsg); DispatchMessage.sendToAllInRange(this, applyBuildingEffectMsg);
} }
/*
* Utils
*/
public void removeEffectBit(int bit) { public void removeEffectBit(int bit) {
this.effectFlags &= (~bit); this.effectFlags &= (~bit);
} }
@Override @Override
@ -965,26 +803,18 @@ public class Building extends AbstractWorldObject {
this.updateName(); this.updateName();
} }
/*
* Serializing
*/
public final AbstractCharacter getOwner() { public final AbstractCharacter getOwner() {
if (this.ownerUUID == 0) if (this.ownerUUID == 0)
return null; return null;
if (this.ownerIsNPC) if (this.ownerIsNPC)
return NPC.getFromCache(this.ownerUUID); return NPC.getNPC(this.ownerUUID);
return PlayerCharacter.getFromCache(this.ownerUUID); return PlayerCharacter.getPlayerCharacter(this.ownerUUID);
} }
/*
* Database
*/
public final String getOwnerName() { public final String getOwnerName() {
AbstractCharacter owner = this.getOwner(); AbstractCharacter owner = this.getOwner();
if (owner != null) if (owner != null)
@ -1045,19 +875,6 @@ public class Building extends AbstractWorldObject {
} }
// *** Refactor: Can't we just use setRank() for this?
public final void rebuildMine() {
this.setRank(1);
this.meshUUID = this.getBlueprint().getMeshForRank(this.rank);
// New rank mean new max hitpoints.
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.setCurrentHitPoints(this.healthMax);
this.getBounds().setBounds(this);
}
public final void refreshGuild() { public final void refreshGuild() {
UpdateObjectMsg uom = new UpdateObjectMsg(this, 5); UpdateObjectMsg uom = new UpdateObjectMsg(this, 5);
@ -1069,72 +886,93 @@ public class Building extends AbstractWorldObject {
return maxGold; return maxGold;
} }
//This returns if a player is allowed access to control the building
@Override @Override
public void runAfterLoad() { public void runAfterLoad() {
try { // Set Parent Zone
this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID);
this.parentZone.zoneBuildingSet.add(this); this.parentZone.zoneBuildingSet.add(this);
// Submit upgrade job if building is currently set to rank. // Lookup building blueprint
try { Blueprint blueprint;
DbObjectType objectType = DbManager.BuildingQueries.GET_UID_ENUM(this.ownerUUID);
this.ownerIsNPC = (objectType == DbObjectType.NPC);
} catch (Exception e) {
this.ownerIsNPC = false;
Logger.error("Failed to find Object Type for owner " + this.ownerUUID + " Location " + this.getLoc().toString());
}
try { if (this.blueprintUUID == 0)
DbManager.BuildingQueries.LOAD_ALL_FRIENDS_FOR_BUILDING(this); blueprint = Blueprint._meshLookup.get(meshUUID);
DbManager.BuildingQueries.LOAD_ALL_CONDEMNED_FOR_BUILDING(this); else
} catch (Exception e) { blueprint = this.getBlueprint();
Logger.error(this.getObjectUUID() + " failed to load friends/condemned." + e.getMessage());
}
//LOad Owners in Cache so we do not have to continuely look in the db for owner. // Log error if something went horrible wrong
if (this.ownerIsNPC) { if ((this.blueprintUUID != 0) && (blueprint == null))
if (NPC.getNPC(this.ownerUUID) == null) Logger.error("Invalid blueprint for object: " + this.getObjectUUID());
Logger.info("Building UID " + this.getObjectUUID() + " Failed to Load NPC Owner with ID " + this.ownerUUID + " Location " + this.getLoc().toString());
} else if (this.ownerUUID != 0) { // Note: We handle R8 tree edge case for mesh and health
if (PlayerCharacter.getPlayerCharacter(this.ownerUUID) == null) { // after city is loaded to avoid recursive result set call
Logger.info("Building UID " + this.getObjectUUID() + " Failed to Load Player Owner with ID " + this.ownerUUID + " Location " + this.getLoc().toString()); // in City resulting in a stack ovreflow.
}
}
// Apply health bonus and special mesh for realm if applicable if (blueprint != null) {
if ((this.getCity() != null) && this.getCity().getTOL() != null && (this.getCity().getTOL().rank == 8)) {
// Update mesh accordingly // Only switch mesh for player dropped structures
if (this.getBlueprint() != null && this.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
this.meshUUID = Realm.getRealmMesh(this.getCity()); if (this.blueprintUUID != 0)
this.meshUUID = blueprint.getMeshForRank(rank);
// Apply realm capital health bonus. this.healthMax = blueprint.getMaxHealth(this.rank);
// Do not apply bonus to banestones or TOL's. *** Refactor:
// Possibly only protected buildings? Needs some thought.
float missingHealth = 0; // If this object has no blueprint but is a blueprint
// mesh then set it's current health to max health
if (this.health.get() != 0) if (this.blueprintUUID == 0)
missingHealth = this.healthMax - this.health.get(); this.setHealth(healthMax);
if ((this.getBlueprint() != null && this.getBlueprint().getBuildingGroup() != BuildingGroup.TOL) this.patrolPoints = BuildingManager._buildingPatrolPoints.computeIfAbsent(this.getObjectUUID(), k -> new ArrayList<>());
&& (this.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE)) {
this.healthMax += (this.healthMax * Realm.getRealmHealthMod(this.getCity()));
if (this.health.get() != 0) if (this.patrolPoints == null)
this.health.set(this.healthMax - missingHealth); Logger.error("Null patrol points");
} else {
this.healthMax = 100000; // Structures with no blueprint mesh
this.setHealth(healthMax);
}
resists = new Resists("Building");
if (this.parentZone != null) {
if (this.parentBuildingID != 0) {
Building parentBuilding = BuildingManager.getBuilding(this.parentBuildingID);
if (parentBuilding != null) {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX + parentBuilding.statLat, this.statAlt + this.parentZone.absY + parentBuilding.statAlt, this.statLon + this.parentZone.absZ + parentBuilding.statLon));
} else {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX, this.statAlt + this.parentZone.absY, this.statLon + this.parentZone.absZ));
if (this.health.get() > this.healthMax) }
this.health.set(this.healthMax); } else {
// Altitude of this building is derived from the heightmap engine.
Vector3fImmutable tempLoc = new Vector3fImmutable(this.statLat + this.parentZone.absX, 0, this.statLon + this.parentZone.absZ);
tempLoc = new Vector3fImmutable(tempLoc.x, Terrain.getWorldHeight(tempLoc), tempLoc.z);
this.setLoc(tempLoc);
} }
} }
// Submit upgrade job if building is currently set to rank.
try {
DbObjectType objectType = DbManager.BuildingQueries.GET_UID_ENUM(this.ownerUUID);
this.ownerIsNPC = (objectType == DbObjectType.NPC);
} catch (Exception e) {
this.ownerIsNPC = false;
Logger.error("Failed to find Object Type for owner " + this.ownerUUID + " Location " + this.getLoc().toString());
}
// Reference friend and condemn lists from BuildingManager
this.friends = BuildingManager._buildingFriends.computeIfAbsent(this.getObjectUUID(), k -> new ConcurrentHashMap<>());
this.condemned = BuildingManager._buildingCondemned.computeIfAbsent(this.getObjectUUID(), k -> new ConcurrentHashMap<>());
// Set bounds for this building // Set bounds for this building
Bounds buildingBounds = Bounds.borrow(); Bounds buildingBounds = Bounds.borrow();
@ -1148,7 +986,7 @@ public class Building extends AbstractWorldObject {
this.children = new ArrayList<>(); this.children = new ArrayList<>();
if (this.parentBuildingID != 0) { if (this.parentBuildingID != 0) {
Building parent = BuildingManager.getBuildingFromCache(this.parentBuildingID); Building parent = BuildingManager.getBuilding(this.parentBuildingID);
if (parent != null) { if (parent != null) {
parent.children.add(this); parent.children.add(this);
@ -1156,6 +994,7 @@ public class Building extends AbstractWorldObject {
//add furniture to region cache. floor and level are reversed in database, //TODO Fix //add furniture to region cache. floor and level are reversed in database, //TODO Fix
Regions region = BuildingManager.GetRegion(parent, this.level, this.floor, this.getLoc().x, this.getLoc().z); Regions region = BuildingManager.GetRegion(parent, this.level, this.floor, this.getLoc().x, this.getLoc().z);
if (region != null) if (region != null)
Regions.FurnitureRegionMap.put(this.getObjectUUID(), region); Regions.FurnitureRegionMap.put(this.getObjectUUID(), region);
} }
@ -1164,10 +1003,6 @@ public class Building extends AbstractWorldObject {
if (this.upgradeDateTime != null) if (this.upgradeDateTime != null)
BuildingManager.submitUpgradeJob(this); BuildingManager.submitUpgradeJob(this);
} catch (Exception e) {
e.printStackTrace();
}
} }
public synchronized boolean setOwner(AbstractCharacter newOwner) { public synchronized boolean setOwner(AbstractCharacter newOwner) {
@ -1193,7 +1028,6 @@ public class Building extends AbstractWorldObject {
this.ownerIsNPC = (newOwner.getObjectType() == GameObjectType.NPC); this.ownerIsNPC = (newOwner.getObjectType() == GameObjectType.NPC);
} }
// Set new guild for hirelings and refresh all clients // Set new guild for hirelings and refresh all clients
this.refreshGuild(); this.refreshGuild();
@ -1313,7 +1147,7 @@ public class Building extends AbstractWorldObject {
} }
// Save to database ? // Save to database ?
if (updateRecord == true) if (updateRecord)
return DbManager.BuildingQueries.UPDATE_DOOR_LOCK(this.getObjectUUID(), this.doorState); return DbManager.BuildingQueries.UPDATE_DOOR_LOCK(this.getObjectUUID(), this.doorState);
else else
return true; return true;
@ -1349,7 +1183,6 @@ public class Building extends AbstractWorldObject {
this.spireIsActive = true; this.spireIsActive = true;
this.updateEffects(); this.updateEffects();
} }
public final void disableSpire(boolean refreshEffect) { public final void disableSpire(boolean refreshEffect) {
@ -1402,7 +1235,7 @@ public class Building extends AbstractWorldObject {
// Buildings on an npc citygrid are never vulnerable // Buildings on an npc citygrid are never vulnerable
if (this.getCity() != null) { if (this.getCity() != null) {
if (this.getCity().getParent().isNPCCity() == true) if (this.getCity().getParent().isNPCCity == true)
return false; return false;
} }
@ -1558,10 +1391,7 @@ public class Building extends AbstractWorldObject {
public boolean assetIsProtected() { public boolean assetIsProtected() {
boolean outValue = false; boolean outValue = protectionState.equals(ProtectionState.PROTECTED);
if (protectionState.equals(ProtectionState.PROTECTED))
outValue = true;
if (protectionState.equals(ProtectionState.CONTRACT)) if (protectionState.equals(ProtectionState.CONTRACT))
outValue = true; outValue = true;
@ -1638,18 +1468,10 @@ public class Building extends AbstractWorldObject {
return patrolPoints; return patrolPoints;
} }
public void setPatrolPoints(ArrayList<Vector3fImmutable> patrolPoints) {
this.patrolPoints = patrolPoints;
}
public ArrayList<Vector3fImmutable> getSentryPoints() { public ArrayList<Vector3fImmutable> getSentryPoints() {
return sentryPoints; return sentryPoints;
} }
public void setSentryPoints(ArrayList<Vector3fImmutable> sentryPoints) {
this.sentryPoints = sentryPoints;
}
public synchronized boolean addProtectionTax(Building building, PlayerCharacter pc, final TaxType taxType, int amount, boolean enforceKOS) { public synchronized boolean addProtectionTax(Building building, PlayerCharacter pc, final TaxType taxType, int amount, boolean enforceKOS) {
if (building == null) if (building == null)
return false; return false;
@ -1674,14 +1496,6 @@ public class Building extends AbstractWorldObject {
} }
public synchronized boolean declineTaxOffer() {
return true;
}
public synchronized boolean acceptTaxOffer() {
return true;
}
public synchronized boolean acceptTaxes() { public synchronized boolean acceptTaxes() {
if (!DbManager.BuildingQueries.acceptTaxes(this)) if (!DbManager.BuildingQueries.acceptTaxes(this))
@ -1706,14 +1520,6 @@ public class Building extends AbstractWorldObject {
return true; return true;
} }
public boolean isTaxed() {
if (this.taxType == TaxType.NONE)
return false;
if (this.taxAmount == 0)
return false;
return this.taxDateTime != null;
}
public void AddToBarracksList() { public void AddToBarracksList() {
City playerCity = ZoneManager.getCityAtLocation(this.loc); City playerCity = ZoneManager.getCityAtLocation(this.loc);
if (playerCity != null) { if (playerCity != null) {

20
src/engine/objects/BuildingFriends.java

@ -14,10 +14,10 @@ import java.sql.SQLException;
public class BuildingFriends { public class BuildingFriends {
private int playerUID; public int playerUID;
private int buildingUID; public int buildingUID;
private int guildUID; public int guildUID;
private int friendType; public int friendType;
/** /**
* ResultSet Constructor * ResultSet Constructor
@ -38,16 +38,4 @@ public class BuildingFriends {
this.friendType = friendType; this.friendType = friendType;
} }
public int getPlayerUID() {
return playerUID;
}
public int getGuildUID() {
return guildUID;
}
public int getFriendType() {
return friendType;
}
} }

180
src/engine/objects/City.java

@ -11,7 +11,6 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
@ -49,6 +48,8 @@ public class City extends AbstractWorldObject {
public static long lastCityUpdate = 0; public static long lastCityUpdate = 0;
public final HashSet<Integer> _playerMemory = new HashSet<>(); public final HashSet<Integer> _playerMemory = new HashSet<>();
private final boolean isOpen = false;
private final boolean reverseKOS = false;
public java.time.LocalDateTime established; public java.time.LocalDateTime established;
public boolean hasBeenTransfered = false; public boolean hasBeenTransfered = false;
public LocalDateTime realmTaxDate; public LocalDateTime realmTaxDate;
@ -56,7 +57,8 @@ public class City extends AbstractWorldObject {
public volatile boolean protectionEnforced = true; public volatile boolean protectionEnforced = true;
public ArrayList<Building> cityBarracks; public ArrayList<Building> cityBarracks;
public ArrayList<Integer> cityOutlaws = new ArrayList<>(); public ArrayList<Integer> cityOutlaws = new ArrayList<>();
protected Zone parentZone; public Zone parentZone;
public int parentZoneUUID;
private String cityName; private String cityName;
private String motto; private String motto;
private String description; private String description;
@ -74,15 +76,12 @@ public class City extends AbstractWorldObject {
private boolean forceRename = false; private boolean forceRename = false;
private boolean noTeleport = false; //used by npc cities private boolean noTeleport = false; //used by npc cities
private boolean noRepledge = false; //used by npc cities private boolean noRepledge = false; //used by npc cities
private final boolean isOpen = false;
private int treeOfLifeID; private int treeOfLifeID;
private Vector3fImmutable location = Vector3fImmutable.ZERO; private Vector3fImmutable location = Vector3fImmutable.ZERO;
// Players who have entered the city (used for adding and removing affects) // Players who have entered the city (used for adding and removing affects)
private Vector3fImmutable bindLoc; private Vector3fImmutable bindLoc;
private int warehouseBuildingID = 0; private int warehouseBuildingID = 0;
private boolean open = false; private boolean open = false;
private boolean reverseKOS = false;
private String hash; private String hash;
/** /**
@ -92,6 +91,7 @@ public class City extends AbstractWorldObject {
public City(ResultSet rs) throws SQLException { public City(ResultSet rs) throws SQLException {
super(rs); super(rs);
try { try {
this.parentZoneUUID = rs.getInt("parent");
this.cityName = rs.getString("name"); this.cityName = rs.getString("name");
this.motto = rs.getString("motto"); this.motto = rs.getString("motto");
this.isNpc = rs.getByte("isNpc"); this.isNpc = rs.getByte("isNpc");
@ -127,7 +127,9 @@ public class City extends AbstractWorldObject {
this.location.getY(), this.location.getY(),
this.location.getZ() + this.bindZ); this.location.getZ() + this.bindZ);
this.radiusType = rs.getInt("radiusType"); this.radiusType = rs.getInt("radiusType");
float bindradiustemp = rs.getFloat("bindRadius"); float bindradiustemp = rs.getFloat("bindRadius");
if (bindradiustemp > 2) if (bindradiustemp > 2)
bindradiustemp -= 2; bindradiustemp -= 2;
@ -136,30 +138,8 @@ public class City extends AbstractWorldObject {
this.forceRename = rs.getInt("forceRename") == 1; this.forceRename = rs.getInt("forceRename") == 1;
this.open = rs.getInt("open") == 1; this.open = rs.getInt("open") == 1;
if (this.cityName.equals("Perdition") || this.cityName.equals("Bastion")) {
this.noTeleport = true;
this.noRepledge = true;
} else {
this.noTeleport = false;
this.noRepledge = false;
}
this.hash = rs.getString("hash"); this.hash = rs.getString("hash");
if (this.motto.isEmpty()) {
Guild guild = this.getGuild();
if (guild != null && guild.isEmptyGuild() == false)
this.motto = guild.getMotto();
}
Zone zone = ZoneManager.getZoneByUUID(rs.getInt("parent"));
if (zone != null)
setParent(zone);
//npc cities without heightmaps except swampstone are specials.
this.realmID = rs.getInt("realmID"); this.realmID = rs.getInt("realmID");
} catch (Exception e) { } catch (Exception e) {
@ -334,7 +314,7 @@ public class City extends AbstractWorldObject {
if (city.noTeleport) if (city.noTeleport)
continue; continue;
if (city.parentZone != null && city.parentZone.isPlayerCity()) { if (city.parentZone != null && city.parentZone.guild_zone) {
if (pc.getAccount().status.equals(AccountStatus.ADMIN)) { if (pc.getAccount().status.equals(AccountStatus.ADMIN)) {
cities.add(city); cities.add(city);
@ -395,7 +375,7 @@ public class City extends AbstractWorldObject {
if (city.noRepledge) if (city.noRepledge)
continue; continue;
if (city.parentZone != null && city.parentZone.isPlayerCity()) { if (city.parentZone != null && city.parentZone.guild_zone) {
//list Player cities //list Player cities
//open city, just list //open city, just list
@ -568,34 +548,6 @@ public class City extends AbstractWorldObject {
return this.parentZone; return this.parentZone;
} }
public void setParent(Zone zone) {
try {
this.parentZone = zone;
this.location = new Vector3fImmutable(zone.absX, zone.absY, zone.absZ);
this.bindLoc = new Vector3fImmutable(this.location.x + this.bindX,
this.location.y,
this.location.z + this.bindZ);
// set city bounds
Bounds cityBounds = Bounds.borrow();
cityBounds.setBounds(new Vector2f(this.location.x + 64, this.location.z + 64), // location x and z are offset by 64 from the center of the city.
new Vector2f(Enum.CityBoundsType.GRID.extents, Enum.CityBoundsType.GRID.extents),
0.0f);
this.setBounds(cityBounds);
if (zone.getHeightMap() == null && this.isNpc == 1 && this.getObjectUUID() != 1213) {
HeightMap.GenerateCustomHeightMap(zone);
Logger.info(zone.getName() + " created custom heightmap");
}
} catch (Exception e) {
Logger.error(e);
}
}
public AbstractCharacter getOwner() { public AbstractCharacter getOwner() {
if (this.getTOL() == null) if (this.getTOL() == null)
@ -725,11 +677,33 @@ public class City extends AbstractWorldObject {
@Override @Override
public void runAfterLoad() { public void runAfterLoad() {
// Set city bounds this.setObjectTypeMask(MBServerStatics.MASK_CITY);
// *** Note: Moved to SetParent()
// for some undocumented reason
// Set city motto to current guild motto // Set parent
this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID);
// If it's not a player city then must be an NPC city
if (!parentZone.guild_zone)
parentZone.isNPCCity = true;
// Set location for this city
this.location = new Vector3fImmutable(this.parentZone.absX, this.parentZone.absY, this.parentZone.absZ);
this.bindLoc = new Vector3fImmutable(this.location.x + this.bindX,
this.location.y,
this.location.z + this.bindZ);
// set city bounds
Bounds cityBounds = Bounds.borrow();
cityBounds.setBounds(new Vector2f(this.location.x + 64, this.location.z + 64), // location x and z are offset by 64 from the center of the city.
new Vector2f(Enum.CityBoundsType.GRID.halfExtents, Enum.CityBoundsType.GRID.halfExtents),
0.0f);
this.setBounds(cityBounds);
// Sanity check; no tol
if (BuildingManager.getBuilding(this.treeOfLifeID) == null) if (BuildingManager.getBuilding(this.treeOfLifeID) == null)
Logger.info("City UID " + this.getObjectUUID() + " Failed to Load Tree of Life with ID " + this.treeOfLifeID); Logger.info("City UID " + this.getObjectUUID() + " Failed to Load Tree of Life with ID " + this.treeOfLifeID);
@ -745,6 +719,8 @@ public class City extends AbstractWorldObject {
Logger.error("Unable to find realm of ID " + realmID + " for city " + this.getObjectUUID()); Logger.error("Unable to find realm of ID " + realmID + " for city " + this.getObjectUUID());
} }
// Set city motto to current guild motto
if (this.getGuild() != null) { if (this.getGuild() != null) {
this.motto = this.getGuild().getMotto(); this.motto = this.getGuild().getMotto();
@ -754,8 +730,10 @@ public class City extends AbstractWorldObject {
for (Guild sub : this.getGuild().getSubGuildList()) { for (Guild sub : this.getGuild().getSubGuildList()) {
if ((sub.getGuildState() == GuildState.Protectorate) || if ((sub.getGuildState() == GuildState.Protectorate) ||
(sub.getGuildState() == GuildState.Province)) (sub.getGuildState() == GuildState.Province)) {
this.isCapital = 1; this.isCapital = 1;
break;
}
} }
ArrayList<PlayerCharacter> guildList = Guild.GuildRoster(this.getGuild()); ArrayList<PlayerCharacter> guildList = Guild.GuildRoster(this.getGuild());
@ -763,6 +741,61 @@ public class City extends AbstractWorldObject {
this.population = guildList.size(); this.population = guildList.size();
} }
if (this.cityName.equals("Perdition") || this.cityName.equals("Bastion")) {
this.noTeleport = true;
this.noRepledge = true;
} else {
this.noTeleport = false;
this.noRepledge = false;
}
// Add city entry to data warehouse if newly created
if ((ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER)) && (this.getHash() == null)) {
this.setHash();
if (DataWarehouse.recordExists(Enum.DataRecordType.CITY, this.getObjectUUID()) == false) {
CityRecord cityRecord = CityRecord.borrow(this, Enum.RecordEventType.CREATE);
DataWarehouse.pushToWarehouse(cityRecord);
}
}
// Apply health bonus and special mesh for realm if applicable
if (this.getTOL().rank == 8) {
// Update mesh accordingly
this.getTOL().meshUUID = Realm.getRealmMesh(this);
// Apply realm capital health bonus.
// Do not apply bonus to banestones or TOL's. *** Refactor:
// Possibly only protected buildings? Needs some thought.
float missingHealth = 0;
if (this.health.get() != 0)
missingHealth = this.healthMax - this.health.get();
for (Building building : this.parentZone.zoneBuildingSet) {
if (building.getBlueprint() != null &&
building.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE &&
building.getBlueprint().getBuildingGroup() != BuildingGroup.TOL) {
building.healthMax += (building.healthMax * Realm.getRealmHealthMod(this));
if (this.health.get() != 0)
this.health.set(this.healthMax - missingHealth);
if (this.health.get() > this.healthMax)
this.health.set(this.healthMax);
}
}
}
// Banes are loaded for this city from the database at this point // Banes are loaded for this city from the database at this point
if (this.getBane() == null) if (this.getBane() == null)
@ -770,12 +803,12 @@ public class City extends AbstractWorldObject {
// if this city is baned, add the siege effect // if this city is baned, add the siege effect
try {
this.getTOL().addEffectBit((1 << 16)); this.getTOL().addEffectBit((1 << 16));
this.getBane().getStone().addEffectBit((1 << 19)); this.getBane().getStone().addEffectBit((1 << 19));
} catch (Exception e) {
Logger.info("Failed ao add bane effects on city." + e.getMessage()); // Spawn city
}
this.setLoc(this.getLoc());
} }
public void addCityEffect(EffectsBase effectBase, int rank) { public void addCityEffect(EffectsBase effectBase, int rank) {
@ -791,7 +824,7 @@ public class City extends AbstractWorldObject {
// Any players currently in the zone will not be processed by the heartbeat // Any players currently in the zone will not be processed by the heartbeat
// if it's not the first effect toggled so we do it here manually // if it's not the first effect toggled so we do it here manually
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, this.parentZone.getBounds().getHalfExtents().x * 1.2f, MBServerStatics.MASK_PLAYER); currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, this.parentZone.bounds.getHalfExtents().x * 1.2f, MBServerStatics.MASK_PLAYER);
for (AbstractWorldObject playerObject : currentPlayers) { for (AbstractWorldObject playerObject : currentPlayers) {
@ -835,7 +868,6 @@ public class City extends AbstractWorldObject {
player.addCityEffect(Integer.toString(effectBase.getUUID()), effectBase, rank, MBServerStatics.FOURTYFIVE_SECONDS, false, this); player.addCityEffect(Integer.toString(effectBase.getUUID()), effectBase, rank, MBServerStatics.FOURTYFIVE_SECONDS, false, this);
} }
} }
public Warehouse getWarehouse() { public Warehouse getWarehouse() {
@ -861,20 +893,14 @@ public class City extends AbstractWorldObject {
return collided; return collided;
} }
public boolean isLocationOnCityGrid(Bounds newBounds) {
boolean collided = Bounds.collide(this.getBounds(), newBounds, 0);
return collided;
}
public boolean isLocationWithinSiegeBounds(Vector3fImmutable insideLoc) { public boolean isLocationWithinSiegeBounds(Vector3fImmutable insideLoc) {
return insideLoc.isInsideCircle(this.getLoc(), CityBoundsType.ZONE.extents); return insideLoc.isInsideCircle(this.getLoc(), CityBoundsType.ZONE.halfExtents);
} }
public boolean isLocationOnCityZone(Vector3fImmutable insideLoc) { public boolean isLocationOnCityZone(Vector3fImmutable insideLoc) {
return Bounds.collide(insideLoc, this.parentZone.getBounds()); return Bounds.collide(insideLoc, this.parentZone.bounds);
} }
private void applyAllCityEffects(PlayerCharacter player) { private void applyAllCityEffects(PlayerCharacter player) {
@ -934,7 +960,7 @@ public class City extends AbstractWorldObject {
// Gather current list of players within the zone bounds // Gather current list of players within the zone bounds
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.ZONE.extents, MBServerStatics.MASK_PLAYER); currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.ZONE.halfExtents, MBServerStatics.MASK_PLAYER);
currentMemory = new HashSet<>(); currentMemory = new HashSet<>();
for (AbstractWorldObject playerObject : currentPlayers) { for (AbstractWorldObject playerObject : currentPlayers) {

47
src/engine/objects/Condemned.java

@ -14,72 +14,45 @@ import engine.gameManager.DbManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
public class Condemned { public class Condemned {
public static final int INDIVIDUAL = 2; public static final int INDIVIDUAL = 2;
public static final int GUILD = 4; public static final int GUILD = 4;
public static final int NATION = 5; public static final int NATION = 5;
private int ID;
private int playerUID;
private int parent;
private int guildUID;
private int friendType;
private boolean active;
public int playerUID;
public int buildingUUID;
public int guildUID;
public int friendType;
public boolean active;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
public Condemned(ResultSet rs) throws SQLException { public Condemned(ResultSet rs) throws SQLException {
this.playerUID = rs.getInt("playerUID"); this.playerUID = rs.getInt("playerUID");
this.parent = rs.getInt("buildingUID"); this.buildingUUID = rs.getInt("buildingUID");
this.guildUID = rs.getInt("guildUID"); this.guildUID = rs.getInt("guildUID");
this.friendType = rs.getInt("friendType"); this.friendType = rs.getInt("friendType");
this.active = rs.getBoolean("active"); this.active = rs.getBoolean("active");
} }
public Condemned(int playerUID, int buildingUUID, int guildUID, int friendType) {
public Condemned(int playerUID, int parent, int guildUID, int friendType) {
super(); super();
this.playerUID = playerUID; this.playerUID = playerUID;
this.parent = parent; this.buildingUUID = buildingUUID;
this.guildUID = guildUID; this.guildUID = guildUID;
this.friendType = friendType; this.friendType = friendType;
this.active = false; this.active = false;
} }
public int getPlayerUID() {
return playerUID;
}
public int getParent() {
return parent;
}
public int getGuildUID() {
return guildUID;
}
public int getFriendType() {
return friendType;
}
public boolean isActive() {
return active;
}
public boolean setActive(boolean active) { public boolean setActive(boolean active) {
if (!DbManager.BuildingQueries.updateActiveCondemn(this, active)) if (!DbManager.BuildingQueries.updateActiveCondemn(this, active))
return false; return false;
this.active = active; this.active = active;
return true; return true;
} }
} }

62
src/engine/objects/Guild.java

@ -59,8 +59,6 @@ public class Guild extends AbstractWorldObject {
private int cityUUID = 0; private int cityUUID = 0;
private int mineTime; private int mineTime;
private ArrayList<PlayerCharacter> banishList; private ArrayList<PlayerCharacter> banishList;
private ArrayList<PlayerCharacter> characterKOSList;
private ArrayList<Guild> guildKOSList;
private ArrayList<Guild> allyList = new ArrayList<>(); private ArrayList<Guild> allyList = new ArrayList<>();
private ArrayList<Guild> enemyList = new ArrayList<>(); private ArrayList<Guild> enemyList = new ArrayList<>();
private ArrayList<Guild> recommendList = new ArrayList<>(); private ArrayList<Guild> recommendList = new ArrayList<>();
@ -83,8 +81,6 @@ public class Guild extends AbstractWorldObject {
this.leadershipType = leadershipType; this.leadershipType = leadershipType;
this.banishList = new ArrayList<>(); this.banishList = new ArrayList<>();
this.characterKOSList = new ArrayList<>();
this.guildKOSList = new ArrayList<>();
this.allyList = new ArrayList<>(); this.allyList = new ArrayList<>();
this.enemyList = new ArrayList<>(); this.enemyList = new ArrayList<>();
this.subGuildList = new ArrayList<>(); this.subGuildList = new ArrayList<>();
@ -115,8 +111,6 @@ public class Guild extends AbstractWorldObject {
this.leadershipType = leadershipType; this.leadershipType = leadershipType;
this.banishList = new ArrayList<>(); this.banishList = new ArrayList<>();
this.characterKOSList = new ArrayList<>();
this.guildKOSList = new ArrayList<>();
this.allyList = new ArrayList<>(); this.allyList = new ArrayList<>();
this.enemyList = new ArrayList<>(); this.enemyList = new ArrayList<>();
this.subGuildList = new ArrayList<>(); this.subGuildList = new ArrayList<>();
@ -189,22 +183,6 @@ public class Guild extends AbstractWorldObject {
return a.getObjectUUID() == b.getObjectUUID(); return a.getObjectUUID() == b.getObjectUUID();
} }
public static boolean sameGuildExcludeErrant(Guild a, Guild b) {
if (a == null || b == null)
return false;
if (a.isEmptyGuild() || b.isEmptyGuild())
return false;
return a.getObjectUUID() == b.getObjectUUID();
}
public static boolean sameGuildIncludeErrant(Guild a, Guild b) {
if (a == null || b == null)
return false;
if (a.isEmptyGuild() || b.isEmptyGuild())
return true;
return a.getObjectUUID() == b.getObjectUUID();
}
public static boolean sameNation(Guild a, Guild b) { public static boolean sameNation(Guild a, Guild b) {
if (a == null || b == null) if (a == null || b == null)
return false; return false;
@ -225,11 +203,6 @@ public class Guild extends AbstractWorldObject {
return a.nation.getObjectUUID() == b.nation.getObjectUUID() && !a.nation.isEmptyGuild(); return a.nation.getObjectUUID() == b.nation.getObjectUUID() && !a.nation.isEmptyGuild();
} }
public static boolean isTaxCollector(int uuid) {
//TODO add the handling for this later
return false;
}
public static boolean canSwearIn(Guild toSub) { public static boolean canSwearIn(Guild toSub) {
boolean canSwear = false; boolean canSwear = false;
@ -393,7 +366,9 @@ public class Guild extends AbstractWorldObject {
} }
public static ArrayList<PlayerCharacter> GuildRoster(Guild guild) { public static ArrayList<PlayerCharacter> GuildRoster(Guild guild) {
ArrayList<PlayerCharacter> roster = new ArrayList<>(); ArrayList<PlayerCharacter> roster = new ArrayList<>();
if (guild == null) if (guild == null)
return roster; return roster;
@ -402,6 +377,7 @@ public class Guild extends AbstractWorldObject {
if (DbManager.getList(GameObjectType.PlayerCharacter) == null) if (DbManager.getList(GameObjectType.PlayerCharacter) == null)
return roster; return roster;
for (AbstractGameObject ago : DbManager.getList(GameObjectType.PlayerCharacter)) { for (AbstractGameObject ago : DbManager.getList(GameObjectType.PlayerCharacter)) {
PlayerCharacter toAdd = (PlayerCharacter) ago; PlayerCharacter toAdd = (PlayerCharacter) ago;
@ -462,14 +438,6 @@ public class Guild extends AbstractWorldObject {
return banishList; return banishList;
} }
public ArrayList<PlayerCharacter> getCharacterKOSList() {
return characterKOSList;
}
public ArrayList<Guild> getGuildKOSList() {
return guildKOSList;
}
public ArrayList<Guild> getAllyList() { public ArrayList<Guild> getAllyList() {
return allyList; return allyList;
} }
@ -560,9 +528,12 @@ public class Guild extends AbstractWorldObject {
} }
public boolean setGuildLeader(AbstractCharacter ac) { public boolean setGuildLeader(AbstractCharacter ac) {
if (ac == null) if (ac == null)
return false; return false;
// errant guilds cant be guild leader. // errant guilds cant be guild leader.
if (this.isEmptyGuild()) if (this.isEmptyGuild())
return false; return false;
@ -575,6 +546,7 @@ public class Guild extends AbstractWorldObject {
PlayerCharacter oldGuildLeader = PlayerCharacter.getFromCache(this.guildLeaderUUID); PlayerCharacter oldGuildLeader = PlayerCharacter.getFromCache(this.guildLeaderUUID);
//old guildLeader no longer has guildLeadership stauts. //old guildLeader no longer has guildLeadership stauts.
if (oldGuildLeader != null) if (oldGuildLeader != null)
oldGuildLeader.setGuildLeader(false); oldGuildLeader.setGuildLeader(false);
@ -586,9 +558,12 @@ public class Guild extends AbstractWorldObject {
} }
public boolean setGuildLeaderForCreate(AbstractCharacter ac) { public boolean setGuildLeaderForCreate(AbstractCharacter ac) {
if (ac == null) if (ac == null)
return false; return false;
// errant guilds cant be guild leader. // errant guilds cant be guild leader.
if (this.isEmptyGuild()) if (this.isEmptyGuild())
return false; return false;
@ -824,17 +799,6 @@ public class Guild extends AbstractWorldObject {
Logger.error("Failed to find Object Type for owner " + this.guildLeaderUUID); Logger.error("Failed to find Object Type for owner " + this.guildLeaderUUID);
} }
//LOad Owners in Cache so we do not have to continuely look in the db for owner.
if (this.ownerIsNPC) {
if (NPC.getNPC(this.guildLeaderUUID) == null)
Logger.info("Guild UID " + this.getObjectUUID() + " Failed to Load NPC Owner with ID " + this.guildLeaderUUID);
} else if (this.guildLeaderUUID != 0) {
if (PlayerCharacter.getPlayerCharacter(this.guildLeaderUUID) == null)
Logger.info("Guild UID " + this.getObjectUUID() + " Failed to Load Player Owner with ID " + this.guildLeaderUUID);
}
// If loading this guild for the first time write it's character record to disk // If loading this guild for the first time write it's character record to disk
if (ConfigManager.serverType.equals(ServerType.WORLDSERVER) if (ConfigManager.serverType.equals(ServerType.WORLDSERVER)
@ -859,7 +823,9 @@ public class Guild extends AbstractWorldObject {
if (this.nation == null) if (this.nation == null)
this.nation = Guild.getErrantGuild(); this.nation = Guild.getErrantGuild();
//Get guild states. //Get guild states.
try { try {
this.subGuildList = DbManager.GuildQueries.GET_SUB_GUILDS(this.getObjectUUID()); this.subGuildList = DbManager.GuildQueries.GET_SUB_GUILDS(this.getObjectUUID());
} catch (Exception e) { } catch (Exception e) {
@ -882,7 +848,6 @@ public class Guild extends AbstractWorldObject {
if (this.cityUUID == 0) if (this.cityUUID == 0)
return; return;
// Calculate number of realms this guild controls // Calculate number of realms this guild controls
// Only do this on the game server to avoid loading a TOL/City/Zone needlessly // Only do this on the game server to avoid loading a TOL/City/Zone needlessly
@ -898,9 +863,8 @@ public class Guild extends AbstractWorldObject {
//add alliance list, clear all lists as there seems to be a bug where alliances are doubled, need to find where. //add alliance list, clear all lists as there seems to be a bug where alliances are doubled, need to find where.
//possible runAfterLoad being called twice?!?! //possible runAfterLoad being called twice?!?!
this.banishList = dbGuildHandler.GET_GUILD_BANISHED(this.getObjectUUID()); this.banishList = dbGuildHandler.GET_GUILD_BANISHED(this.getObjectUUID());
this.characterKOSList = DbManager.GuildQueries.GET_GUILD_KOS_CHARACTER(this.getObjectUUID());
this.guildKOSList = DbManager.GuildQueries.GET_GUILD_KOS_GUILD(this.getObjectUUID());
this.allyList.clear(); this.allyList.clear();
this.enemyList.clear(); this.enemyList.clear();

4
src/engine/objects/ItemFactory.java

@ -104,7 +104,7 @@ public class ItemFactory {
if (zone == null) if (zone == null)
return null; return null;
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) if (city == null)
return null; return null;
@ -796,7 +796,7 @@ public class ItemFactory {
if (zone == null) if (zone == null)
return null; return null;
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) if (city == null)
return null; return null;

4
src/engine/objects/Mine.java

@ -64,7 +64,7 @@ public class Mine extends AbstractGameObject {
this.flags = rs.getInt("flags"); this.flags = rs.getInt("flags");
int parent = rs.getInt("parent"); int parent = rs.getInt("parent");
this.parentZone = ZoneManager.getZoneByUUID(parent); this.parentZone = ZoneManager.getZoneByUUID(parent);
this.zoneName = this.parentZone.getParent().getName(); this.zoneName = this.parentZone.parent.zoneName;
this.owningGuild = Guild.getGuild(ownerUID); this.owningGuild = Guild.getGuild(ownerUID);
Guild nation = null; Guild nation = null;
@ -129,7 +129,7 @@ public class Mine extends AbstractGameObject {
mine.getTimestamps().put("MineAttack", System.currentTimeMillis() + MBServerStatics.ONE_MINUTE); mine.getTimestamps().put("MineAttack", System.currentTimeMillis() + MBServerStatics.ONE_MINUTE);
ChatManager.chatNationInfo(mine.getGuild().getNation(), mine.getName() + " in " + mine.getParentZone().getParent().getName() + " is Under attack!"); ChatManager.chatNationInfo(mine.getGuild().getNation(), mine.getName() + " in " + mine.getParentZone().parent.zoneName + " is Under attack!");
} }
public static void loadAllMines() { public static void loadAllMines() {

22
src/engine/objects/Mob.java

@ -841,13 +841,11 @@ public class Mob extends AbstractIntelligenceAgent {
if (newLoc.equals(this.getEndLoc())) { if (newLoc.equals(this.getEndLoc())) {
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
return; return;
//Next upda //Next upda
} }
setLoc(newLoc); setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
//Next update will be end Loc, lets stop him here. //Next update will be end Loc, lets stop him here.
} }
@ -899,7 +897,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.setCombatTarget(null); this.setCombatTarget(null);
this.hasLoot = false; this.hasLoot = false;
ZoneManager.getSeaFloor().zoneMobSet.remove(this); ZoneManager.seaFloor.zoneMobSet.remove(this);
try { try {
this.clearEffects(); this.clearEffects();
@ -971,8 +969,6 @@ public class Mob extends AbstractIntelligenceAgent {
if (this.building == null && this.guardCaptain != null && ((Mob) this.guardCaptain).behaviourType.equals(MobBehaviourType.GuardCaptain)) if (this.building == null && this.guardCaptain != null && ((Mob) this.guardCaptain).behaviourType.equals(MobBehaviourType.GuardCaptain))
this.building = this.guardCaptain.building; this.building = this.guardCaptain.building;
else if (this.building != null)
this.region = BuildingManager.GetRegion(this.building, bindLoc.x, bindLoc.y, bindLoc.z);
this.loadInventory(); this.loadInventory();
@ -1653,7 +1649,7 @@ public class Mob extends AbstractIntelligenceAgent {
// Setup location for this Mobile // Setup location for this Mobile
this.loc = new Vector3fImmutable(bindLoc); this.setLoc(bindLoc);
this.endLoc = new Vector3fImmutable(bindLoc); this.endLoc = new Vector3fImmutable(bindLoc);
// Initialize inventory // Initialize inventory
@ -1681,10 +1677,13 @@ public class Mob extends AbstractIntelligenceAgent {
if (this.getMobBase().enemy.size() > 0) if (this.getMobBase().enemy.size() > 0)
this.enemy.addAll(this.getMobBase().enemy); this.enemy.addAll(this.getMobBase().enemy);
} }
// Load skills, powers and effects
NPCManager.applyMobbaseEffects(this); NPCManager.applyMobbaseEffects(this);
NPCManager.applyEquipmentResists(this); NPCManager.applyEquipmentResists(this);
NPCManager.applyMobbaseSkill(this); NPCManager.applyMobbaseSkill(this);
NPCManager.applyRuneSkills(this,this.getMobBaseID()); NPCManager.applyRuneSkills(this, this.getMobBaseID());
this.recalculateStats(); this.recalculateStats();
this.setHealth(this.healthMax); this.setHealth(this.healthMax);
@ -1699,6 +1698,11 @@ public class Mob extends AbstractIntelligenceAgent {
if (this.agentType.equals(AIAgentType.MOBILE)) if (this.agentType.equals(AIAgentType.MOBILE))
NPCManager.AssignPatrolPoints(this); NPCManager.AssignPatrolPoints(this);
// Load minions for guard captain.
if (this.agentType.equals(AIAgentType.GUARDCAPTAIN))
DbManager.MobQueries.LOAD_GUARD_MINIONS(this);
this.deathTime = 0; this.deathTime = 0;
} }
@ -1736,9 +1740,9 @@ public class Mob extends AbstractIntelligenceAgent {
if (!ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (!ac.getObjectType().equals(GameObjectType.PlayerCharacter))
return; return;
if (this.getCombatTarget() == null) { if (this.getCombatTarget() == null)
this.setCombatTarget(ac); this.setCombatTarget(ac);
}
} }
public void setRank(int newRank) { public void setRank(int newRank) {

10
src/engine/objects/NPC.java

@ -865,7 +865,7 @@ public class NPC extends AbstractCharacter {
this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon); this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon);
this.bindLoc = this.parentZone.getLoc().add(this.bindLoc); this.bindLoc = this.parentZone.getLoc().add(this.bindLoc);
this.loc = new Vector3fImmutable(bindLoc); this.setLoc(bindLoc);
// Handle NPCs within buildings // Handle NPCs within buildings
@ -894,7 +894,7 @@ public class NPC extends AbstractCharacter {
this.stamina.set(this.staminaMax); this.stamina.set(this.staminaMax);
} }
if (this.parentZone.isPlayerCity()) if (this.parentZone.guild_zone)
if (NPC.GetNPCProfits(this) == null) if (NPC.GetNPCProfits(this) == null)
NPCProfits.CreateProfits(this); NPCProfits.CreateProfits(this);
@ -972,6 +972,10 @@ public class NPC extends AbstractCharacter {
Bounds npcBounds = Bounds.borrow(); Bounds npcBounds = Bounds.borrow();
npcBounds.setBounds(this.getLoc()); npcBounds.setBounds(this.getLoc());
//apply NPC rune effects
NPCManager.applyRunesForNPC(this);
this.resists.setImmuneToAll(true);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.getMessage()); Logger.error(e.getMessage());
} }
@ -1188,7 +1192,7 @@ public class NPC extends AbstractCharacter {
if (serverZone == null) if (serverZone == null)
return null; return null;
city = City.GetCityFromCache(serverZone.getPlayerCityUUID()); city = City.GetCityFromCache(serverZone.playerCityUUID);
if (city == null) { if (city == null) {

81
src/engine/objects/PlayerCharacter.java

@ -11,9 +11,9 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.CharacterRecord; import engine.db.archive.CharacterRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
@ -117,10 +117,8 @@ public class PlayerCharacter extends AbstractCharacter {
public float landingAltitude = 0; public float landingAltitude = 0;
public int bindBuilding = 0; public int bindBuilding = 0;
public FriendStatus friendStatus = FriendStatus.Available; public FriendStatus friendStatus = FriendStatus.Available;
protected ArrayList<CharacterRune> runes;
private BaseClass baseClass; private BaseClass baseClass;
private PromotionClass promotionClass; private PromotionClass promotionClass;
private long channelMute = 0; // none muted.
private ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); private ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
private boolean lfGroup = false; private boolean lfGroup = false;
private boolean lfGuild = false; private boolean lfGuild = false;
@ -1509,16 +1507,16 @@ public class PlayerCharacter extends AbstractCharacter {
return true; return true;
Zone zone = ZoneManager.findSmallestZone(breather.getLoc()); Zone zone = ZoneManager.findSmallestZone(breather.getLoc());
if (zone.getSeaLevel() != 0) { if (zone.sea_level != 0) {
float localAltitude = breather.getLoc().y; float localAltitude = breather.getLoc().y;
if (localAltitude + breather.characterHeight < zone.getSeaLevel() - 2) if (localAltitude + breather.characterHeight < zone.sea_level - 2)
return false; return false;
if (breather.isMoving()) { if (breather.isMoving()) {
if (localAltitude + breather.characterHeight < zone.getSeaLevel()) if (localAltitude + breather.characterHeight < zone.sea_level)
return false; return false;
} }
} else { } else {
@ -1549,12 +1547,12 @@ public class PlayerCharacter extends AbstractCharacter {
Zone zone = ZoneManager.findSmallestZone(enterer.getLoc()); Zone zone = ZoneManager.findSmallestZone(enterer.getLoc());
if (zone.getSeaLevel() != 0) { if (zone.sea_level != 0) {
float localAltitude = enterer.getLoc().y + enterer.characterHeight; float localAltitude = enterer.getLoc().y + enterer.characterHeight;
if (localAltitude < zone.getSeaLevel()) if (localAltitude < zone.sea_level)
return true; return true;
} else { } else {
if (enterer.getLoc().y + enterer.characterHeight < 0) if (enterer.getLoc().y + enterer.characterHeight < 0)
@ -1581,12 +1579,12 @@ public class PlayerCharacter extends AbstractCharacter {
leaveWater = 1f; leaveWater = 1f;
if (zone.getSeaLevel() != 0) { if (zone.sea_level != 0) {
float localAltitude = leaver.getLoc().y; float localAltitude = leaver.getLoc().y;
if (localAltitude + leaveWater < zone.getSeaLevel()) if (localAltitude + leaveWater < zone.sea_level)
return false; return false;
} else { } else {
if (leaver.getLoc().y + leaveWater < 0) if (leaver.getLoc().y + leaveWater < 0)
@ -1705,7 +1703,7 @@ public class PlayerCharacter extends AbstractCharacter {
Zone zone = ZoneManager.findSmallestZone(this.getLoc()); Zone zone = ZoneManager.findSmallestZone(this.getLoc());
if (zone != null) { if (zone != null) {
return zone.getSafeZone() == (byte) 1; return zone.peace_zone == (byte) 1;
} }
return false; return false;
@ -1799,7 +1797,7 @@ public class PlayerCharacter extends AbstractCharacter {
//DeathShroud //DeathShroud
if (zone.getSafeZone() == 0) if (zone.peace_zone == 0)
PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false);
//enable this to give players deathshroud if mobs kill player. //enable this to give players deathshroud if mobs kill player.
@ -1845,7 +1843,7 @@ public class PlayerCharacter extends AbstractCharacter {
//DeathShroud //DeathShroud
if (zone.getSafeZone() == 0) if (zone.peace_zone == 0)
PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false);
if (doPVPEXP) { if (doPVPEXP) {
@ -1900,7 +1898,7 @@ public class PlayerCharacter extends AbstractCharacter {
killCleanup(); killCleanup();
Zone zone = ZoneManager.findSmallestZone(this.getLoc()); Zone zone = ZoneManager.findSmallestZone(this.getLoc());
if (zone.getSafeZone() == 0) if (zone.peace_zone == 0)
PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false); PowersManager.applyPower(this, this, Vector3fImmutable.ZERO, 1672601862, 40, false);
// Send death message if needed // Send death message if needed
@ -4741,10 +4739,10 @@ public class PlayerCharacter extends AbstractCharacter {
Zone zone = ZoneManager.findSmallestZone(this.getLoc()); Zone zone = ZoneManager.findSmallestZone(this.getLoc());
if (zone.getSeaLevel() != 0) { if (zone.sea_level != 0) {
float localAltitude = this.getLoc().y + this.centerHeight; float localAltitude = this.getLoc().y + this.centerHeight;
if (localAltitude < zone.getSeaLevel()) if (localAltitude < zone.sea_level)
return true; return true;
} else { } else {
if (this.getLoc().y + this.centerHeight < 0) if (this.getLoc().y + this.centerHeight < 0)
@ -4762,13 +4760,13 @@ public class PlayerCharacter extends AbstractCharacter {
// If char is flying they aren't quite swimming // If char is flying they aren't quite swimming
try { try {
float localAltitude = HeightMap.getWorldHeight(currentLoc); float localAltitude = Terrain.getWorldHeight(currentLoc);
Zone zone = ZoneManager.findSmallestZone(currentLoc); Zone zone = ZoneManager.findSmallestZone(currentLoc);
if (zone.getSeaLevel() != 0) { if (zone.sea_level != 0) {
if (localAltitude < zone.getSeaLevel()) if (localAltitude < zone.sea_level)
return true; return true;
} else { } else {
if (localAltitude < 0) if (localAltitude < 0)
@ -4834,7 +4832,7 @@ public class PlayerCharacter extends AbstractCharacter {
} else } else
this.altitude = this.getDesiredAltitude(); this.altitude = this.getDesiredAltitude();
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude()); this.loc = this.loc.setY(Terrain.getWorldHeight(this.getLoc()) + this.getAltitude());
this.setTakeOffTime(0); this.setTakeOffTime(0);
MovementManager.finishChangeAltitude(this, this.getDesiredAltitude()); MovementManager.finishChangeAltitude(this, this.getDesiredAltitude());
@ -4842,7 +4840,7 @@ public class PlayerCharacter extends AbstractCharacter {
return; return;
} }
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude()); this.loc = this.loc.setY(Terrain.getWorldHeight(this.getLoc()) + this.getAltitude());
} }
public boolean hasBoon() { public boolean hasBoon() {
@ -4888,12 +4886,10 @@ public class PlayerCharacter extends AbstractCharacter {
if (this.isAlive() == false || this.getBonuses().getBool(ModType.Stunned, SourceType.None) || this.getBonuses().getBool(ModType.CannotMove, SourceType.None)) { if (this.isAlive() == false || this.getBonuses().getBool(ModType.Stunned, SourceType.None) || this.getBonuses().getBool(ModType.CannotMove, SourceType.None)) {
//Target is stunned or rooted. Don't move //Target is stunned or rooted. Don't move
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
return; return;
} }
if (newLoc.equals(this.getEndLoc())) { if (newLoc.equals(this.getEndLoc())) {
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1)) if (this.getDebug(1))
ChatManager.chatSystemInfo(this, ChatManager.chatSystemInfo(this,
"Arrived at End location. " + this.getEndLoc()); "Arrived at End location. " + this.getEndLoc());
@ -4902,7 +4898,6 @@ public class PlayerCharacter extends AbstractCharacter {
} }
setLoc(newLoc); setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1)) if (this.getDebug(1))
ChatManager.chatSystemInfo(this, ChatManager.chatSystemInfo(this,
@ -5436,14 +5431,6 @@ public class PlayerCharacter extends AbstractCharacter {
return characterHeight; return characterHeight;
} }
public void setCharacterHeight(float characterHeight) {
this.characterHeight = characterHeight;
}
public void setCenterHeight(float centerHeight) {
this.centerHeight = centerHeight;
}
public boolean isEnteredWorld() { public boolean isEnteredWorld() {
return enteredWorld; return enteredWorld;
} }
@ -5452,40 +5439,10 @@ public class PlayerCharacter extends AbstractCharacter {
this.enteredWorld = enteredWorld; this.enteredWorld = enteredWorld;
} }
public long getChannelMute() {
return channelMute;
}
public void setChannelMute(long channelMute) {
this.channelMute = channelMute;
}
public boolean isLastSwimming() { public boolean isLastSwimming() {
return lastSwimming; return lastSwimming;
} }
public boolean isTeleporting() {
return isTeleporting;
}
public void setTeleporting(boolean isTeleporting) {
this.isTeleporting = isTeleporting;
}
@Override
public final void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock();
try {
MovementManager.translocate(this, targetLoc, targetRegion);
} catch (Exception e) {
Logger.error(e);
} finally {
locationLock.writeLock().unlock();
}
}
public ReadWriteLock getTeleportLock() { public ReadWriteLock getTeleportLock() {
return teleportLock; return teleportLock;

3
src/engine/objects/Portal.java

@ -3,6 +3,7 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.PortalType; import engine.Enum.PortalType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.gameManager.BuildingManager;
import engine.gameManager.ConfigManager; import engine.gameManager.ConfigManager;
import engine.job.JobScheduler; import engine.job.JobScheduler;
import engine.jobs.CloseGateJob; import engine.jobs.CloseGateJob;
@ -104,7 +105,7 @@ public class Portal {
if (player.getTimeStamp("lastMoveGate") < this.lastActive) if (player.getTimeStamp("lastMoveGate") < this.lastActive)
return; return;
player.teleport(targetGate.getLoc()); player.teleport(targetGate.getLoc().add(0,6,0));//offset height of runegate
player.setSafeMode(); player.setSafeMode();
} }

82
src/engine/objects/Realm.java

@ -175,22 +175,6 @@ public class Realm {
return (this.rulingCityUUID != 0); return (this.rulingCityUUID != 0);
} }
public float getMapR() {
return this.mapR;
}
public float getMapG() {
return this.mapG;
}
public float getMapB() {
return this.mapB;
}
public float getMapA() {
return this.mapA;
}
public boolean getCanBeClaimed() { public boolean getCanBeClaimed() {
return this.canBeClaimed; return this.canBeClaimed;
} }
@ -211,37 +195,6 @@ public class Realm {
return City.getCity(this.rulingCityUUID); return City.getCity(this.rulingCityUUID);
} }
public float getMapY1() {
return this.mapY1;
}
public float getMapX1() {
return this.mapX1;
}
public float getMapY2() {
return this.mapY2;
}
public float getMapX2() {
return this.mapX2;
}
public int getStretchX() {
return this.stretchX;
}
public int getStretchY() {
return this.stretchY;
}
public int getlocX() {
return this.locX;
}
public int getlocY() {
return this.locY;
}
// Call this after changing ownership before you serialize a realm // Call this after changing ownership before you serialize a realm
@ -370,13 +323,6 @@ public class Realm {
return charterType; return charterType;
} }
/**
* @param charterType the charterType to set
*/
public void setCharterType(int charterType) {
this.charterType = charterType;
}
public void abandonRealm() { public void abandonRealm() {
// Push event to warehouse // Push event to warehouse
@ -417,32 +363,4 @@ public class Realm {
return hash; return hash;
} }
public void setHash() {
this.hash = DataWarehouse.hasher.encrypt(this.realmID);
// Write hash to player character table
DataWarehouse.writeHash(Enum.DataRecordType.REALM, this.realmID);
}
/* *** Keeping around in case needed for server wipe or some other emergency
public static void backfillRealms() {
// Backfill realm records
for (Realm realm : _realms.values()) {
realm.setHash();
if ( (realm.isRuled() == true) &&
(DataWarehouse.recordExists(Enum.DataRecordType.REALM, realm.getRealmID()) == false)) {
RealmRecord realmRecord = RealmRecord.borrow(realm, Enum.RecordEventType.CAPTURE);
DataWarehouse.pushToWarehouse(realmRecord);
}
}
}
*/
} }

9
src/engine/objects/Regions.java

@ -170,10 +170,10 @@ public class Regions {
return true; return true;
//next region is stairs, if they are on the same level as stairs or 1 up, world object can enter. //next region is stairs, if they are on the same level as stairs or 1 up, world object can enter.
if (toEnter.stairs) if (toEnter.isStairs())
if (worldObject.region.level == toEnter.level || toEnter.level - 1 == worldObject.region.level) if (worldObject.region.level == toEnter.level || toEnter.level - 1 == worldObject.region.level)
return true; return true;
if (worldObject.region.stairs) { if (worldObject.region.isStairs()) {
boolean movingUp = false; boolean movingUp = false;
@ -239,7 +239,7 @@ public class Regions {
return true; return true;
//cant move up a level without stairs. //cant move up a level without stairs.
if (!fromRegion.stairs) if (!fromRegion.isStairs())
return false; return false;
boolean movingUp = false; boolean movingUp = false;
@ -367,7 +367,8 @@ public class Regions {
} }
public boolean isStairs() { public boolean isStairs() {
return stairs;
return this.highLerp.y - this.lowLerp.y > 0.25f;
} }
public boolean isExit() { public boolean isExit() {

2
src/engine/objects/Runegate.java

@ -108,7 +108,7 @@ public class Runegate {
writer.putInt(gateBuilding.getObjectType().ordinal()); writer.putInt(gateBuilding.getObjectType().ordinal());
writer.putInt(gateBuilding.getObjectUUID()); writer.putInt(gateBuilding.getObjectUUID());
writer.putString(gateBuilding.getParentZone().getName()); writer.putString(gateBuilding.getParentZone().zoneName);
writer.putFloat(gateBuilding.getLoc().getLat()); writer.putFloat(gateBuilding.getLoc().getLat());
writer.putFloat(gateBuilding.getLoc().getAlt()); writer.putFloat(gateBuilding.getLoc().getAlt());
writer.putFloat(gateBuilding.getLoc().getLong()); writer.putFloat(gateBuilding.getLoc().getLong());

2
src/engine/objects/Warehouse.java

@ -1272,7 +1272,7 @@ public class Warehouse extends AbstractWorldObject {
return; return;
} }
City city = City.getCity(cityZone.getPlayerCityUUID()); City city = City.getCity(cityZone.playerCityUUID);
if (city == null) { if (city == null) {
Logger.error("Failed to load City for Warehouse with UUID " + this.getObjectUUID()); Logger.error("Failed to load City for Warehouse with UUID " + this.getObjectUUID());

336
src/engine/objects/Zone.java

@ -10,9 +10,8 @@
package engine.objects; package engine.objects;
import engine.Enum; import engine.Enum;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector2f; import engine.math.Vector2f;
@ -28,106 +27,105 @@ import java.util.Collections;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class Zone extends AbstractGameObject { public class Zone extends AbstractWorldObject {
public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>());
public static long lastRespawn = 0;
public final Set<Building> zoneBuildingSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Set<Building> zoneBuildingSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
public final Set<NPC> zoneNPCSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Set<NPC> zoneNPCSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
public final Set<Mob> zoneMobSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Set<Mob> zoneMobSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final int playerCityID;
private final String zoneName; public ZoneTemplate template;
private final float xCoord;
private final float zCoord; public final int playerCityUUID;
private final float yCoord; public final String zoneName;
private final int loadNum; public final float major_radius;
private final byte safeZone; public final float minor_radius;
private final String Icon1; public final float xOffset;
private final String Icon2; public final float zOffset;
private final String Icon3; public final float yOffset;
public final int templateID;
public final byte peace_zone;
public final String icon1;
public final String icon2;
public final String icon3;
public float absX = 0.0f; public float absX = 0.0f;
public float absY = 0.0f; public float absY = 0.0f;
public float absZ = 0.0f; public float absZ = 0.0f;
public int minLvl; public int min_level;
public int maxLvl; public int max_level;
public boolean hasBeenHotzone = false; public boolean hasBeenHotzone = false;
private ArrayList<Zone> nodes = null; public ArrayList<Zone> nodes = new ArrayList<>();
private int parentZoneID; public int parentZoneID;
private Zone parent = null; public Zone parent = null;
private Bounds bounds; public Bounds bounds;
private boolean isNPCCity = false; public boolean isNPCCity = false;
private boolean isPlayerCity = false; public boolean guild_zone;
private String hash; public String hash;
public float worldAltitude = 0; public float global_height = 0;
private float seaLevel = 0; public float sea_level;
//public static ArrayList<Mob> respawnQue = new ArrayList<>();
public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>()); public Terrain terrain = null;
public static long lastRespawn = 0;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
public Zone(ResultSet rs) throws SQLException { public Zone(ResultSet rs) throws SQLException {
super(rs); super(rs);
this.parentZoneID = rs.getInt("parent"); this.parentZoneID = rs.getInt("parent");
this.playerCityID = rs.getInt("isPlayerCity"); this.templateID = rs.getInt("template");
this.isPlayerCity = this.playerCityID != 0; this.zoneName = rs.getString("zone_name");
this.zoneName = rs.getString("Name"); this.peace_zone = rs.getByte("peace_zone");
this.xCoord = rs.getFloat("XCoord");
this.zCoord = rs.getFloat("ZCoord"); this.major_radius = rs.getFloat("major_radius");
this.yCoord = rs.getFloat("YOffset"); this.minor_radius = rs.getFloat("minor_radius");
this.loadNum = rs.getInt("LoadNum"); this.xOffset = rs.getFloat("xOffset");
this.safeZone = rs.getByte("SafeZone"); this.zOffset = rs.getFloat("zOffset");
this.Icon1 = rs.getString("Icon1"); this.yOffset = rs.getFloat("yOffset");
this.Icon2 = rs.getString("Icon2");
this.Icon3 = rs.getString("Icon3");
this.hash = rs.getString("hash");
this.minLvl = rs.getInt("minLvl");
this.maxLvl = rs.getInt("maxLvl");
//this needs to be here specifically for new zones created after server boot (e.g. player city zones)
Zone parentZone = ZoneManager.getZoneByUUID(parentZoneID);
this.setParent(parentZone);
if (this.minLvl == 0 && parentZone != null) {
this.minLvl = parentZone.minLvl;
this.maxLvl = parentZone.maxLvl;
}
if (parentZone != null) this.playerCityUUID = rs.getInt("playerCityUUID");
parentZone.addNode(this); this.guild_zone = this.playerCityUUID != 0;
this.icon1 = rs.getString("icon1");
this.icon2 = rs.getString("icon2");
this.icon3 = rs.getString("icon3");
this.min_level = rs.getInt("min_level");
this.max_level = rs.getInt("max_level");
// If zone doesn't yet hava a hash then write it back to the zone table // If zone doesn't yet hava a hash then write it back to the zone table
if (hash == null) if (hash == null)
setHash(); setHash();
} }
public static void serializeForClientMsg(Zone zone, ByteBufferWriter writer) { public static void serializeForClientMsg(Zone zone, ByteBufferWriter writer) {
if (zone.loadNum == 0 && zone.playerCityID == 0) if (zone.templateID == 0 && zone.playerCityUUID == 0)
Logger.warn("Warning! WorldServerMap with ID " + zone.getObjectUUID() + " has a loadnum of 0 (player city) and no city linked. This will probably crash the client!"); Logger.warn("Warning! WorldServerMap with ID " + zone.getObjectUUID() + " has a loadnum of 0 (player city) and no city linked. This will probably crash the client!");
// Player City Terraform values serialized here. // Player City Terraform values serialized here.
if (zone.playerCityID > 0) { if (zone.playerCityUUID > 0) {
writer.put((byte) 1); // Player City - True writer.put((byte) 1); // Player City - True
writer.putFloat(Enum.CityBoundsType.ZONE.extents); writer.putFloat(Enum.CityBoundsType.ZONE.halfExtents);
writer.putFloat(Enum.CityBoundsType.ZONE.extents); writer.putFloat(Enum.CityBoundsType.ZONE.halfExtents);
} else } else
writer.put((byte) 0); // Player City - False writer.put((byte) 0); // Player City - False
writer.putFloat(zone.xCoord); writer.putFloat(zone.xOffset);
writer.putFloat(zone.zCoord); writer.putFloat(zone.zOffset);
writer.putFloat(zone.yCoord); writer.putFloat(zone.yOffset);
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
writer.putInt(zone.loadNum); writer.putInt(zone.templateID);
if (zone.playerCityID > 0) { if (zone.playerCityUUID > 0) {
City k = City.getCity(zone.playerCityID); City k = City.getCity(zone.playerCityUUID);
if (k != null) { if (k != null) {
writer.putInt(k.getObjectType().ordinal()); writer.putInt(k.getObjectType().ordinal());
@ -140,16 +138,16 @@ public class Zone extends AbstractGameObject {
} }
writer.putInt(zone.nodes.size()); writer.putInt(zone.nodes.size());
City city = City.getCity(zone.playerCityID); City city = City.getCity(zone.playerCityUUID);
if (city != null) if (city != null)
writer.putString(city.getCityName()); writer.putString(city.getCityName());
else else
writer.putString(zone.zoneName); writer.putString(zone.zoneName);
writer.put(zone.safeZone); writer.put(zone.peace_zone);
writer.putString(zone.Icon1); writer.putString(zone.icon1);
writer.putString(zone.Icon2); writer.putString(zone.icon2);
writer.putString(zone.Icon3); writer.putString(zone.icon3);
writer.put((byte) 0); // Pad writer.put((byte) 0); // Pad
for (Zone child : zone.nodes) { for (Zone child : zone.nodes) {
@ -157,148 +155,111 @@ public class Zone extends AbstractGameObject {
} }
} }
/* Method sets a default value for player cities @Override
* otherwise using values derived from the loadnum public void runAfterLoad() {
* field in the obj_zone database table.
*/
public void setBounds() {
float halfExtentX;
float halfExtentY;
// Set initial bounds object
this.bounds = Bounds.borrow();
// Player cities are assigned default value
if (this.loadNum == 0) { this.template = ZoneManager._zone_templates.get(this.templateID);
bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents), 0.0f);
return;
}
Vector2f zoneSize = ZoneManager._zone_size_data.get(this.loadNum); // First zone is always the seafloor
// Default to player zone size on error? Maybe log this if (ZoneManager.seaFloor == null)
ZoneManager.seaFloor = this;
if (zoneSize != null) if (this.template.terrain_type.equals("NONE"))
this.bounds.setBounds(new Vector2f(this.absX, this.absZ), zoneSize, 0.0f); this.terrain = null;
else else
bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents), 0.0f); this.terrain = new Terrain(this);
} this.setParent();
public int getPlayerCityUUID() { if (this.min_level == 0 && this.parent != null) {
return this.playerCityID; this.min_level = this.parent.min_level;
this.max_level = this.parent.max_level;
} }
public String getName() { ZoneManager.populateZoneCollections(this);
return zoneName;
}
public float getXCoord() {
return xCoord;
} }
public float getYCoord() { /* Method sets a default value for player cities
return yCoord; * otherwise using values derived from the loadnum
} * field in the obj_zone database table.
*/
public float getZCoord() { public void setBounds() {
return zCoord;
}
public int getLoadNum() {
return loadNum;
}
public byte getSafeZone() { // Set initial bounds object
return safeZone;
}
public String getIcon1() { this.bounds = Bounds.borrow();
return Icon1; this.bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(this.template.major_radius, this.template.minor_radius), 0.0f);
}
public Zone getParent() {
return this.parent;
} }
public void setParent(final Zone value) { public void setParent() {
this.parent = value; this.parent = ZoneManager.getZoneByUUID(parentZoneID);
this.parentZoneID = (this.parent != null) ? this.parent.getObjectUUID() : 0;
// Zone AABB is set here as it's coordinate space is world requiring a parent. if (parent != null)
parent.addNode(this);
// Seafloor // Seafloor
if (this.parent == null) { if (ZoneManager.seaFloor.equals(this)) {
this.absX = this.xCoord; this.absX = this.xOffset;
this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE; this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE;
this.absZ = this.zCoord; this.global_height = MBServerStatics.SEA_FLOOR_ALTITUDE;
this.seaLevel = 0; this.absZ = this.zOffset;
this.sea_level = 0;
this.setBounds(); this.setBounds();
return; return;
} }
this.absX = this.xCoord + parent.absX; this.absX = this.xOffset + parent.absX;
this.absY = this.yCoord + parent.absY; this.absY = this.yOffset + parent.absY;
this.absZ = this.zCoord + parent.absZ; this.absZ = this.zOffset + parent.absZ;
if (this.minLvl == 0 || this.maxLvl == 0) { if (this.min_level == 0 || this.max_level == 0) {
this.minLvl = this.parent.minLvl; this.min_level = this.parent.min_level;
this.maxLvl = this.parent.maxLvl; this.max_level = this.parent.max_level;
} }
this.setBounds(); this.setBounds();
this.global_height = ZoneManager.calculateGlobalZoneHeight(this);
setSeaLevel();
}
if (this.getHeightMap() != null && this.getHeightMap().getSeaLevel() != 0) private void setSeaLevel() {
this.seaLevel = this.worldAltitude + this.getHeightMap().getSeaLevel();
else
this.seaLevel = this.parent.seaLevel;
} int world_sea_level = 0;
public float getAbsX() { if (this.parent == null) {
return this.absX; this.sea_level = world_sea_level;
return;
} }
public float getAbsY() { switch (this.template.sea_level_type) {
return this.absY; case "WORLD":
this.sea_level = world_sea_level + this.template.sea_level;
break;
case "PARENT":
this.sea_level = this.parent.sea_level + this.template.sea_level;
break;
case "SELF":
this.sea_level = this.global_height + this.template.sea_level;
break;
} }
public float getAbsZ() {
return this.absZ;
} }
public boolean isMacroZone() { public boolean isMacroZone() {
// Macro zones have icons. // Macro zones have icons.
if (this.isPlayerCity == true) if (this.guild_zone)
return false; return false;
if (this.parent == null) if (this.parent == null)
return false; return false;
return !this.getIcon1().equals(""); return !icon1.equals("");
}
public boolean isNPCCity() {
return this.isNPCCity;
}
public void setNPCCity(boolean value) {
this.isNPCCity = value;
}
public boolean isPlayerCity() {
return this.isPlayerCity;
}
public void setPlayerCity(boolean value) {
this.isPlayerCity = value;
} }
public Vector3fImmutable getLoc() { public Vector3fImmutable getLoc() {
@ -309,20 +270,6 @@ public class Zone extends AbstractGameObject {
return this.parentZoneID; return this.parentZoneID;
} }
public ArrayList<Zone> getNodes() {
if (this.nodes == null) {
this.nodes = DbManager.ZoneQueries.GET_MAP_NODES(super.getObjectUUID());
//Add reverse lookup for child->parent
if (this.nodes != null)
for (Zone zone : this.nodes) {
zone.setParent(this);
}
}
return nodes;
}
/* /*
* Serializing * Serializing
*/ */
@ -338,28 +285,17 @@ public class Zone extends AbstractGameObject {
public boolean isContinent() { public boolean isContinent() {
if (this.equals(ZoneManager.getSeaFloor())) if (this.equals(ZoneManager.seaFloor))
return false; return false;
if (this.getNodes().isEmpty()) if (this.nodes.isEmpty())
return false; return false;
if (this.getNodes().get(0).isMacroZone()) if (this.nodes.get(0).isMacroZone())
return true; return true;
return this.getParent().equals(ZoneManager.getSeaFloor()); return this.parent.equals(ZoneManager.seaFloor);
}
/**
* @return the bounds
*/
public Bounds getBounds() {
return bounds;
}
public String getHash() {
return hash;
} }
public void setHash() { public void setHash() {
@ -371,18 +307,4 @@ public class Zone extends AbstractGameObject {
DataWarehouse.writeHash(Enum.DataRecordType.ZONE, this.getObjectUUID()); DataWarehouse.writeHash(Enum.DataRecordType.ZONE, this.getObjectUUID());
} }
// Return heightmap for this Zone.
public HeightMap getHeightMap() {
if (this.isPlayerCity)
return HeightMap.PlayerCityHeightMap;
return HeightMap.heightmapByLoadNum.get(this.loadNum);
}
public float getSeaLevel() {
return seaLevel;
}
} }

59
src/engine/objects/ZoneTemplate.java

@ -0,0 +1,59 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.objects;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ZoneTemplate {
public int templateID;
public String zone_type;
public String zone_name;
public String peace_zone;
public float major_radius;
public float minor_radius;
public float min_blend;
public float max_blend;
public String has_water;
public String sea_level_type;
public float sea_level;
public String has_terrain;
public String terrain_type;
public float terrain_max_y;
public int terrain_image;
/**
* ResultSet Constructor
*/
public ZoneTemplate() {
}
public ZoneTemplate(ResultSet rs) throws SQLException {
this.templateID = rs.getInt("template");
this.zone_type = rs.getString("zone_type");
this.zone_name = rs.getString("zone_name");
this.major_radius = rs.getFloat("zone_major_radius");
this.minor_radius = rs.getFloat("zone_minor_radius");
this.min_blend = rs.getFloat("zone_min_blend");
this.max_blend = rs.getFloat("zone_max_blend");
this.has_water = rs.getString("zone_has_water");
this.sea_level_type = rs.getString("zone_sea_level_type");
this.sea_level = rs.getFloat("zone_sea_level");
this.has_terrain = rs.getString("zone_has_terrain_gen");
this.terrain_type = rs.getString("terrain_type");
this.terrain_max_y = rs.getFloat("terrain_max_y");
this.terrain_image = rs.getInt("terrain_image");
}
}

2
src/engine/powers/poweractions/CreateMobPowerAction.java

@ -56,7 +56,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
PlayerCharacter owner = (PlayerCharacter) source; PlayerCharacter owner = (PlayerCharacter) source;
Mob currentPet = owner.getPet(); Mob currentPet = owner.getPet();
Zone seaFloor = ZoneManager.getSeaFloor(); Zone seaFloor = ZoneManager.seaFloor;
Guild guild = Guild.getErrantGuild(); Guild guild = Guild.getErrantGuild();
ClientConnection origin = owner.getClientConnection(); ClientConnection origin = owner.getClientConnection();

2
src/engine/powers/poweractions/MobRecallPowerAction.java

@ -38,7 +38,7 @@ public class MobRecallPowerAction extends AbstractPowerAction {
return; return;
MovementManager.translocate(awoac, awoac.getBindLoc(), null); MovementManager.translocate(awoac, awoac.getBindLoc());
if (awoac.getObjectType() == GameObjectType.Mob) { if (awoac.getObjectType() == GameObjectType.Mob) {
//MobAI.setAwake((Mob)awoac,true); //MobAI.setAwake((Mob)awoac,true);
((Mob) awoac).setCombatTarget(null); ((Mob) awoac).setCombatTarget(null);

2
src/engine/powers/poweractions/RecallPowerAction.java

@ -58,7 +58,7 @@ public class RecallPowerAction extends AbstractPowerAction {
DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY);
} else { } else {
MovementManager.translocate(awoac, awoac.getBindLoc(), null); MovementManager.translocate(awoac, awoac.getBindLoc());
} }
} else { } else {
Vector3fImmutable bindloc = awoac.getBindLoc(); Vector3fImmutable bindloc = awoac.getBindLoc();

2
src/engine/powers/poweractions/SummonPowerAction.java

@ -55,7 +55,7 @@ public class SummonPowerAction extends AbstractPowerAction {
String location = "Somewhere"; String location = "Somewhere";
if (zone != null) if (zone != null)
location = zone.getName(); location = zone.zoneName;
RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(source.getObjectType().ordinal(), source.getObjectUUID(), source.getFirstName(), RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(source.getObjectType().ordinal(), source.getObjectUUID(), source.getFirstName(),
location, false); location, false);

2
src/engine/powers/poweractions/TeleportPowerAction.java

@ -101,7 +101,7 @@ public class TeleportPowerAction extends AbstractPowerAction {
if (region != null && !region.isOutside()) if (region != null && !region.isOutside())
return; return;
MovementManager.translocate(awoac, targetLoc, region); MovementManager.translocate(awoac, targetLoc);
} }
@Override @Override

24
src/engine/server/login/LoginServerMsgHandler.java

@ -136,25 +136,25 @@ public class LoginServerMsgHandler implements NetMsgHandler {
cMajorVer = vim.getMajorVersion(); cMajorVer = vim.getMajorVersion();
cMinorVer = vim.getMinorVersion(); cMinorVer = vim.getMinorVersion();
if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) { // if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc);
return; // return;
} // }
/* if (!cMinorVer.equals(this.server.getDefaultVersionInfo().getMinorVersion())) { /* if (!cMinorVer.equals(this.server.getDefaultVersionInfo().getMinorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: " + cMinorVer, cc); this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: " + cMinorVer, cc);
return; return;
} */ } */
if (cMinorVer == null) { // if (cMinorVer == null) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return; // return;
} // }
if (cMinorVer.length() < 8 || cMinorVer.length() > 16) { // if (cMinorVer.length() < 8 || cMinorVer.length() > 16) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return; // return;
} // }
// set MachineID for this connection // set MachineID for this connection

151
src/engine/server/world/WorldServer.java

@ -13,7 +13,6 @@ import engine.Enum;
import engine.Enum.DispatchChannel; import engine.Enum.DispatchChannel;
import engine.Enum.MinionType; import engine.Enum.MinionType;
import engine.Enum.SupportMsgType; import engine.Enum.SupportMsgType;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
@ -39,6 +38,7 @@ import engine.net.client.msg.UpdateStateMsg;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.util.MapLoader;
import engine.util.ThreadUtils; import engine.util.ThreadUtils;
import engine.workthreads.DisconnectTrashTask; import engine.workthreads.DisconnectTrashTask;
import engine.workthreads.HourlyJobThread; import engine.workthreads.HourlyJobThread;
@ -309,15 +309,27 @@ public class WorldServer {
Logger.info("Initializing Errant Guild"); Logger.info("Initializing Errant Guild");
Guild.getErrantGuild(); Guild.getErrantGuild();
Logger.info("Loading zone template data");
DbManager.ZoneQueries.LOAD_ALL_ZONE_TEMPLATES();
Logger.info("Initializing PowersManager."); Logger.info("Initializing PowersManager.");
PowersManager.initPowersManager(true); PowersManager.initPowersManager(true);
Logger.info("Initializing granted Skills for Runes"); Logger.info("Loading granted Skills for Runes");
DbManager.SkillsBaseQueries.LOAD_ALL_RUNE_SKILLS(); DbManager.SkillsBaseQueries.LOAD_ALL_RUNE_SKILLS();
Logger.info("Initializing Player Friends"); Logger.info("Loading Player Friends");
DbManager.PlayerCharacterQueries.LOAD_PLAYER_FRIENDS(); DbManager.PlayerCharacterQueries.LOAD_PLAYER_FRIENDS();
Logger.info("Loading Building Friends");
DbManager.BuildingQueries.LOAD_BUILDING_FRIENDS();
Logger.info("Loading Building Condemned");
DbManager.BuildingQueries.LOAD_BUILDING_CONDEMNED();
Logger.info("Loading Barracks Patrol Points");
DbManager.BuildingQueries.LOAD_BARRACKS_PATROL_POINTS();
Logger.info("Initializing NPC Profits"); Logger.info("Initializing NPC Profits");
DbManager.NPCQueries.LOAD_NPC_PROFITS(); DbManager.NPCQueries.LOAD_NPC_PROFITS();
@ -360,9 +372,6 @@ public class WorldServer {
Logger.info("Loading item enchants"); Logger.info("Loading item enchants");
DbManager.LootQueries.LOAD_ENCHANT_VALUES(); DbManager.LootQueries.LOAD_ENCHANT_VALUES();
Logger.info("Loading zone extent cache");
DbManager.ZoneQueries.LOAD_ZONE_EXTENTS();
Logger.info("Loading Realms"); Logger.info("Loading Realms");
Realm.loadAllRealms(); Realm.loadAllRealms();
@ -384,8 +393,8 @@ public class WorldServer {
Blueprint.loadAllDoorNumbers(); Blueprint.loadAllDoorNumbers();
Blueprint.loadAllBlueprints(); Blueprint.loadAllBlueprints();
Logger.info("Initializing Heightmap data"); Logger.info("Loading Heightmap Pixel data");
HeightMap.loadAlHeightMaps(); MapLoader.loadAlHeightMaps();
Logger.info("Loading Race data"); Logger.info("Loading Race data");
Enum.RaceType.initRaceTypeTables(); Enum.RaceType.initRaceTypeTables();
@ -412,7 +421,17 @@ public class WorldServer {
//Load Buildings, Mobs and NPCs for server //Load Buildings, Mobs and NPCs for server
getWorldBuildingsMobsNPCs(); Logger.info("Populating world with objects");
long start = System.currentTimeMillis();
DbManager.ZoneQueries.GET_ALL_ZONES();
DbManager.BuildingQueries.GET_ALL_BUILDINGS();
DbManager.CityQueries.GET_ALL_CITIES();
DbManager.NPCQueries.GET_ALL_NPCS();
DbManager.MobQueries.GET_ALL_MOBS();
Logger.info("time to load World Objects: " + (System.currentTimeMillis() - start) + " ms");
// Configure realms for serialization // Configure realms for serialization
// Doing this after the world is loaded // Doing this after the world is loaded
@ -441,19 +460,6 @@ public class WorldServer {
//pick a startup Hotzone //pick a startup Hotzone
ZoneManager.generateAndSetRandomHotzone(); ZoneManager.generateAndSetRandomHotzone();
Logger.info("Loading All Players from database to Server Cache");
long start = System.currentTimeMillis();
try {
DbManager.PlayerCharacterQueries.GET_ALL_CHARACTERS();
} catch (Exception e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
Logger.info("Loading All Players took " + (end - start) + " ms.");
ItemProductionManager.ITEMPRODUCTIONMANAGER.initialize(); ItemProductionManager.ITEMPRODUCTIONMANAGER.initialize();
Logger.info("Loading Player Heraldries"); Logger.info("Loading Player Heraldries");
@ -466,14 +472,6 @@ public class WorldServer {
Logger.info("Starting Mob AI Thread"); Logger.info("Starting Mob AI Thread");
MobAIThread.startAIThread(); MobAIThread.startAIThread();
for (Zone zone : ZoneManager.getAllZones()) {
if (zone.getHeightMap() != null) {
if (zone.getHeightMap().getBucketWidthX() == 0) {
System.out.println("Zone load num: " + zone.getLoadNum() + " has no bucket width");
}
}
}
Logger.info("World data loaded."); Logger.info("World data loaded.");
//set default accesslevel for server *** Refactor who two separate variables? //set default accesslevel for server *** Refactor who two separate variables?
@ -542,99 +540,6 @@ public class WorldServer {
return true; return true;
} }
private void getWorldBuildingsMobsNPCs() {
ArrayList<Zone> rootParent;
rootParent = DbManager.ZoneQueries.GET_MAP_NODES(worldUUID);
if (rootParent.isEmpty()) {
Logger.error("populateWorldBuildings: No entries found in worldMap for parent " + worldUUID);
return;
}
//Set sea floor object for server
Zone seaFloor = rootParent.get(0);
seaFloor.setParent(null);
ZoneManager.setSeaFloor(seaFloor);
rootParent.addAll(DbManager.ZoneQueries.GET_ALL_NODES(seaFloor));
long start = System.currentTimeMillis();
for (Zone zone : rootParent) {
ZoneManager.addZone(zone.getLoadNum(), zone);
zone.worldAltitude = ZoneManager.caclulateWorldAltitude(zone);
//Handle Buildings
try {
ArrayList<Building> bList;
bList = DbManager.BuildingQueries.GET_ALL_BUILDINGS_FOR_ZONE(zone);
for (Building b : bList) {
b.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
b.setLoc(b.getLoc());
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle Mobs
try {
ArrayList<Mob> mobs;
mobs = DbManager.MobQueries.GET_ALL_MOBS_FOR_ZONE(zone);
for (Mob m : mobs) {
m.setObjectTypeMask(MBServerStatics.MASK_MOB | m.getTypeMasks());
m.setLoc(m.getLoc());
// Load Minions for Guard Captains here.
if (m.building != null && m.building.getBlueprint() != null && m.building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.BARRACK)
DbManager.MobQueries.LOAD_GUARD_MINIONS(m);
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle NPCs
try {
ArrayList<NPC> npcs;
// Ignore NPCs on the seafloor (npc guild leaders, etc)
if (zone.equals(seaFloor))
continue;
npcs = DbManager.NPCQueries.GET_ALL_NPCS_FOR_ZONE(zone);
for (NPC n : npcs) {
n.setObjectTypeMask(MBServerStatics.MASK_NPC);
n.setLoc(n.getLoc());
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle cities
ZoneManager.loadCities(zone);
ZoneManager.populateWorldZones(zone);
}
Logger.info("time to load World Objects: " + (System.currentTimeMillis() - start) + " ms");
}
/** /**
* Called to remove a client on "leave world", "quit game", killed client * Called to remove a client on "leave world", "quit game", killed client
* process, etc. * process, etc.

55
src/engine/util/MapLoader.java

@ -5,6 +5,7 @@
package engine.util; package engine.util;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain;
import engine.gameManager.ConfigManager; import engine.gameManager.ConfigManager;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -14,6 +15,10 @@ import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public enum MapLoader { public enum MapLoader {
@ -87,4 +92,54 @@ public enum MapLoader {
g.dispose(); g.dispose();
return dimg; return dimg;
} }
public static void loadAlHeightMaps() {
// Load pixel data for heightmaps
try (Stream<Path> filePathStream = Files.walk(Paths.get(ConfigManager.DEFAULT_DATA_DIR + "heightmaps/TARGA/"))) {
filePathStream.forEach(filePath -> {
if (Files.isRegularFile(filePath)) {
File imageFile = filePath.toFile();
BufferedImage heightmapImage;
try {
heightmapImage = ImageIO.read(imageFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
int fileName = Integer.parseInt(imageFile.getName().substring(0, imageFile.getName().lastIndexOf(".")));
boolean singleBandRaster = heightmapImage.getRaster().getNumBands() == 1;
int color;
// Generate pixel data for this heightmap.
short[][] colorData = new short[heightmapImage.getWidth()][heightmapImage.getHeight()];
for (int y = 0; y < heightmapImage.getHeight(); y++)
for (int x = 0; x < heightmapImage.getWidth(); x++) {
if (singleBandRaster)
color = heightmapImage.getRaster().getSample(x, y, 0);
else
color = new Color(heightmapImage.getRGB(x, y)).getRed();
colorData[x][y] = (short) color;
}
// Add pixel for this TGA image into the collection
Terrain._heightmap_pixel_cache.put(fileName, colorData);
}
}); // Try with resources block
} catch (IOException e) {
Logger.error(e);
}
}
} }

7
src/engine/workthreads/DestroyCityThread.java

@ -19,6 +19,7 @@ package engine.workthreads;
*/ */
import engine.Enum; import engine.Enum;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.GuildManager; import engine.gameManager.GuildManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
@ -53,7 +54,7 @@ public class DestroyCityThread implements Runnable {
// Member variable assignment // Member variable assignment
cityZone = city.getParent(); cityZone = city.getParent();
newParent = cityZone.getParent(); newParent = cityZone.parent;
formerGuild = city.getTOL().getGuild(); formerGuild = city.getTOL().getGuild();
// Former guild loses it's tree! // Former guild loses it's tree!
@ -127,7 +128,7 @@ public class DestroyCityThread implements Runnable {
|| (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) { || (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) {
if (cityBuilding.getRank() != -1) if (cityBuilding.getRank() != -1)
cityBuilding.setRank(-1); BuildingManager.setRank(cityBuilding, -1);
} }
} }
@ -150,6 +151,6 @@ public class DestroyCityThread implements Runnable {
// Zone and city should vanish upon next reboot // Zone and city should vanish upon next reboot
// if the codebase reaches here. // if the codebase reaches here.
Logger.info(city.getParent().getName() + " uuid:" + city.getObjectUUID() + "has been destroyed!"); Logger.info(city.getParent().zoneName + " uuid:" + city.getObjectUUID() + "has been destroyed!");
} }
} }

8
src/engine/workthreads/HourlyJobThread.java

@ -163,10 +163,10 @@ public class HourlyJobThread implements Runnable {
mine.nationName = nation.getName(); mine.nationName = nation.getName();
mine.nationTag = nation.getGuildTag(); mine.nationTag = nation.getGuildTag();
mineBuilding.rebuildMine(); BuildingManager.rebuildMine(mineBuilding);
WorldGrid.updateObject(mineBuilding); WorldGrid.updateObject(mineBuilding);
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mine.lastClaimer.getName() + " has claimed the mine in " + mine.getParentZone().getParent().getName() + " for " + mine.getOwningGuild().getName() + ". The mine is no longer active."); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mine.lastClaimer.getName() + " has claimed the mine in " + mine.getParentZone().parent.zoneName + " for " + mine.getOwningGuild().getName() + ". The mine is no longer active.");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg); DispatchMessage.dispatchMsgToAll(chatMsg);
@ -176,7 +176,7 @@ public class HourlyJobThread implements Runnable {
MineRecord mineRecord = MineRecord.borrow(mine, mine.lastClaimer, Enum.RecordEventType.CAPTURE); MineRecord mineRecord = MineRecord.borrow(mine, mine.lastClaimer, Enum.RecordEventType.CAPTURE);
DataWarehouse.pushToWarehouse(mineRecord); DataWarehouse.pushToWarehouse(mineRecord);
mineBuilding.setRank(mineBuilding.getRank()); BuildingManager.setRank(mineBuilding, mineBuilding.getRank());
mine.lastClaimer = null; mine.lastClaimer = null;
mine.setActive(false); mine.setActive(false);
mine.wasClaimed = true; mine.wasClaimed = true;
@ -205,7 +205,7 @@ public class HourlyJobThread implements Runnable {
if (ZoneManager.hotZone == null) { if (ZoneManager.hotZone == null) {
Logger.error("Null HotZone returned from ZoneManager"); Logger.error("Null HotZone returned from ZoneManager");
} else { } else {
Logger.info("HotZone switched to: " + ZoneManager.hotZone.getName()); Logger.info("HotZone switched to: " + ZoneManager.hotZone.zoneName);
} }
} catch (Exception e) { } catch (Exception e) {

2
src/engine/workthreads/TransferCityThread.java

@ -74,7 +74,7 @@ public class TransferCityThread implements Runnable {
//Reset TOL to rank 1 //Reset TOL to rank 1
city.getTOL().setRank(1); BuildingManager.setRank(city.getTOL(), 1);
// Transfer all assets to new owner // Transfer all assets to new owner

Loading…
Cancel
Save