forked from MagicBane/Server
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1368 lines
50 KiB
1368 lines
50 KiB
package engine.net.client.handlers; |
|
|
|
import engine.Enum; |
|
import engine.Enum.*; |
|
import engine.InterestManagement.InterestManager; |
|
import engine.InterestManagement.RealmMap; |
|
import engine.InterestManagement.WorldGrid; |
|
import engine.db.archive.CityRecord; |
|
import engine.db.archive.DataWarehouse; |
|
import engine.exception.MsgSendException; |
|
import engine.gameManager.*; |
|
import engine.math.Bounds; |
|
import engine.math.Vector3fImmutable; |
|
import engine.net.Dispatch; |
|
import engine.net.DispatchMessage; |
|
import engine.net.client.ClientConnection; |
|
import engine.net.client.msg.CityZoneMsg; |
|
import engine.net.client.msg.ClientNetMsg; |
|
import engine.net.client.msg.ErrorPopupMsg; |
|
import engine.net.client.msg.PlaceAssetMsg; |
|
import engine.net.client.msg.PlaceAssetMsg.PlacementInfo; |
|
import engine.objects.*; |
|
import engine.server.MBServerStatics; |
|
import org.joda.time.DateTime; |
|
import org.pmw.tinylog.Logger; |
|
|
|
import java.time.LocalDateTime; |
|
import java.util.ArrayList; |
|
import java.util.HashMap; |
|
import java.util.HashSet; |
|
import java.util.concurrent.locks.ReentrantReadWriteLock; |
|
|
|
/* |
|
* @Summary: Processes application protocol message which requests |
|
* creation of new city / buildings from seeds/deeds in inventory. |
|
*/ |
|
public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { |
|
|
|
// Useful constants |
|
// ActionType 1 = client request |
|
// 2 = Server confirms open window |
|
// 3 = Request to place asset |
|
// 4 = Server confirms/close window |
|
private static final int CLIENTREQ_UNKNOWN = 1; |
|
private static final int SERVER_OPENWINDOW = 2; |
|
private static final int CLIENTREQ_NEWBUILDING = 3; // Request to place asset |
|
private static final int SERVER_CLOSEWINDOW = 4; |
|
|
|
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); |
|
|
|
public PlaceAssetMsgHandler() { |
|
|
|
super(PlaceAssetMsg.class); |
|
|
|
} |
|
|
|
private static void closePlaceAssetWindow(ClientConnection origin) { |
|
|
|
// Action type 4 is the server telling the client to |
|
// close the asset placement window. |
|
// This is believed to be a confirmation message to the client |
|
PlaceAssetMsg pam = new PlaceAssetMsg(); |
|
pam.setActionType(4); |
|
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), pam); |
|
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); |
|
} |
|
|
|
// Default method: Validates and places all buildings that do not |
|
// require special treatment in some fashion. |
|
|
|
private static boolean validateTreeOfLifePlacement(PlayerCharacter playerCharacter, Realm serverRealm, Zone serverZone, |
|
ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
PlacementInfo placementInfo = msg.getFirstPlacementInfo(); |
|
|
|
// Your guild already owns a tree |
|
|
|
if (playerCharacter.getGuild().getOwnedCity() != null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Your guild already owns a tree!"); |
|
return false; |
|
} |
|
|
|
// Validate that the player is the leader of a guild |
|
|
|
if (GuildStatusController.isGuildLeader(playerCharacter.getGuildStatus()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 10, ""); // Must be a guild leader |
|
return false; |
|
} |
|
|
|
// Validate that the player is the leader of a guild |
|
// that is not currently Sovereign *** BUG? Doesn't look right. isGuildLeader()? |
|
|
|
if ((playerCharacter.getGuild().getGuildState() != GuildState.Sworn |
|
|| playerCharacter.getGuild().getGuildState() != GuildState.Errant) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 17, ""); // Your is not an errant or soverign guild |
|
return false; |
|
} |
|
|
|
// All trees must be placed within a continent. |
|
|
|
if (!serverZone.isContinent()) { |
|
|
|
PlaceAssetMsg.sendPlaceAssetError(origin, 69, ""); // Tree must be within a territory |
|
return false; |
|
} |
|
|
|
if (serverRealm == null || serverRealm.getCanPlaceCities() == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 57, playerCharacter.getName()); // No building may be placed within this territory |
|
return false; |
|
} |
|
|
|
// Cannot place a tree underwater |
|
|
|
if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater |
|
return false; |
|
} |
|
|
|
//Test city not too close to any other zone |
|
|
|
if (!ZoneManager.validTreePlacementLoc(serverZone, placementInfo.getLoc().x, placementInfo.getLoc().z)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 39, ""); // Too close to another tree |
|
return false; |
|
} |
|
|
|
// Validate that Realm is not at it's city limit |
|
|
|
if (serverRealm.isRealmFull() == true) { |
|
int numCities; |
|
numCities = serverRealm.getNumCities(); |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 58, Integer.toString(numCities)); // This territory is full |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) { |
|
|
|
if (serverZone.guild_zone == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName()); |
|
return false; |
|
} |
|
|
|
City city = ZoneManager.getCityAtLocation(placementInfo.getLoc()); |
|
|
|
if (player.getGuild().equals(city.getGuild()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 40, player.getName()); |
|
return false; |
|
} |
|
|
|
if (city.isLocationOnCityGrid(placementInfo.getLoc()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); |
|
return false; |
|
} |
|
|
|
// Retrieve the building details we're placing |
|
|
|
if (serverZone.isNPCCity == true) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 15, ""); // Cannot place in a peace zone |
|
return false; |
|
} |
|
|
|
// Errant guilds cannot place assets |
|
|
|
if (player.getGuild().getGuildState() == GuildState.Errant) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Only sovereign or sworn guilds may place assets."); |
|
return false; |
|
} |
|
|
|
// Player must be GL or IC of a guild to place buildings. |
|
|
|
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 10, ""); // You must be a guild leader |
|
return false; |
|
} |
|
|
|
// Cannot place a building underwater |
|
|
|
if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater |
|
return false; |
|
} |
|
|
|
// Players cannot place buildings in mob zones. |
|
|
|
if ((serverZone.isMacroZone() == true) |
|
|| (serverZone.parent.isMacroZone() == true)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory |
|
return false; |
|
} |
|
|
|
Realm serverRealm = RealmMap.getRealmAtLocation(city.getLoc()); |
|
|
|
// Cannot place buildings on seafloor or other restricted realms |
|
|
|
if (serverRealm == null || serverRealm.getCanPlaceCities() == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory |
|
return false; |
|
} |
|
|
|
// Cannot place assets on a dead tree |
|
|
|
if ((serverZone.guild_zone) |
|
&& (City.getCity(serverZone.playerCityUUID).getTOL().getRank() == -1)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot place asset on dead tree until world heals"); |
|
return false; |
|
} |
|
|
|
if (placementCollisionCheck(serverZone, origin, placementInfo)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private static boolean placementCollisionCheck(Zone serverZone, ClientConnection origin, PlacementInfo placementInfo) { |
|
// Overlap check |
|
|
|
for (Building building : serverZone.zoneBuildingSet) { |
|
|
|
if ((building.getBlueprintUUID() != 0) && (Bounds.collide(placementInfo, building) == true)) { |
|
|
|
// Ignore and remove from simulation if we are placing over rubble |
|
|
|
if (building.getRank() == -1) { |
|
|
|
if ((building.getBlueprintUUID() != 0) |
|
&& (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE)) { |
|
Shrine.RemoveShrineFromCacheByBuilding(building); |
|
if (building.getCity() != null) { |
|
|
|
} |
|
} |
|
|
|
building.removeFromCache(); |
|
WorldGrid.RemoveWorldObject(building); |
|
WorldGrid.removeObject(building); |
|
building.getParentZone().zoneBuildingSet.remove(building); |
|
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) { |
|
building.RemoveFromBarracksList(); |
|
} |
|
continue; |
|
} |
|
|
|
|
|
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
private static boolean validateCityBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo buildingInfo) { |
|
|
|
// Perform shared common validation first |
|
|
|
if (validateBuildingPlacement(serverZone, msg, origin, player, buildingInfo) == false) |
|
return false; |
|
|
|
// Must be a player city |
|
|
|
if (serverZone.guild_zone == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); // Cannot place outside a guild zone |
|
return false; |
|
} |
|
|
|
//Test zone has a city object |
|
|
|
City city = City.getCity(serverZone.playerCityUUID); |
|
|
|
if (city == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); //"no city to associate asset with" |
|
return false; |
|
} |
|
|
|
// City assets must be placed on the city grid |
|
|
|
if (!city.isLocationOnCityGrid(buildingInfo.getLoc())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); |
|
return false; |
|
} |
|
|
|
// Make sure it's not an errant tree |
|
|
|
if ((city.getGuild() == null || city.getGuild().isEmptyGuild() == true)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 18, ""); //"There are no guild trees to be found" |
|
return false; |
|
} |
|
|
|
//Test player is in correct guild to place buildings |
|
|
|
if (!player.isCSR) |
|
if (player.getGuild().getObjectUUID() != city.getGuild().getObjectUUID()) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 9, ""); //You must be a guild member to place this asset |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
@Override |
|
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { |
|
|
|
// Member variable declaration |
|
|
|
PlaceAssetMsg msg; |
|
Boolean buildingCreated; |
|
|
|
// Character location and session |
|
|
|
PlayerCharacter playerCharacter; |
|
PlacementInfo buildingList; |
|
Blueprint buildingBlueprint; |
|
|
|
// Tell compiler it's ok to trust us and parse |
|
// what we need from the message structure |
|
|
|
msg = (PlaceAssetMsg) baseMsg; |
|
|
|
// Action type 3 is a client requesting to place an object |
|
// For all other action types let's just early exit |
|
|
|
if (msg.getActionType() != CLIENTREQ_NEWBUILDING) |
|
return true; |
|
|
|
// assign our character |
|
|
|
playerCharacter = SessionManager.getPlayerCharacter(origin); |
|
|
|
// We need to figure out what exactly the player is attempting |
|
// to place, as some objects like tol/bane/walls are edge cases. |
|
// So let's get the first item in their list. |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
// Early exit if null building list. |
|
|
|
if (buildingList == null) { |
|
Logger.error("Player " + playerCharacter.getCombinedName() |
|
+ " null building list on deed use"); |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
closePlaceAssetWindow(origin); |
|
return true; |
|
} |
|
|
|
Item contract = null; |
|
|
|
for (Item inventoryItem : playerCharacter.getInventory()) { |
|
if (inventoryItem.getItemBase().getUseID() == buildingList.getBlueprintUUID()) { |
|
contract = inventoryItem; |
|
break; |
|
} |
|
} |
|
|
|
// Grab the blueprint from the uuid in the message |
|
|
|
buildingBlueprint = Blueprint.getBlueprint(buildingList.getBlueprintUUID()); |
|
|
|
// Early exit if blueprint can't be retrieved for the object. |
|
|
|
if (buildingBlueprint == null) { |
|
Logger.error("Player " + playerCharacter.getCombinedName() |
|
+ " null blueprint UUID: " + buildingList.getBlueprintUUID() + " on deed use"); |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
closePlaceAssetWindow(origin); |
|
return true; |
|
} |
|
|
|
// Let's now attempt to place the building |
|
buildingCreated = false; |
|
|
|
// Many buildings have particular validation and |
|
// post-creation cleanup requirements. |
|
|
|
boolean close = true; |
|
lock.writeLock().lock(); |
|
boolean isSiege = false; |
|
try { |
|
switch (buildingBlueprint.getBuildingGroup()) { |
|
|
|
case TOL: |
|
if (contract == null) |
|
break; |
|
buildingCreated = placeTreeOfLife(playerCharacter, origin, msg); |
|
break; |
|
case WAREHOUSE: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeWarehouse(playerCharacter, origin, msg); |
|
break; |
|
case SIEGETENT: |
|
case BULWARK: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeSiegeEquip(playerCharacter, origin, msg); |
|
break; |
|
case SPIRE: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeSpire(playerCharacter, origin, msg); |
|
break; |
|
case SHRINE: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeShrine(playerCharacter, origin, msg); |
|
break; |
|
case BARRACK: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeBarrack(playerCharacter, origin, msg); |
|
break; |
|
case WALLSTRAIGHT: |
|
case WALLCORNER: |
|
case SMALLGATE: |
|
case ARTYTOWER: |
|
case WALLSTAIRS: |
|
case WALLSTRAIGHTTOWER: |
|
buildingCreated = placeCityWalls(playerCharacter, origin, msg); |
|
close = false; |
|
break; |
|
default: |
|
if (contract == null) |
|
break; |
|
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) |
|
break; |
|
buildingCreated = placeSingleBuilding(playerCharacter, origin, msg); |
|
break; |
|
} |
|
} catch (Exception e) { |
|
Logger.error("PlaceAssetHandler", e.getMessage()); |
|
e.printStackTrace(); |
|
} finally { |
|
lock.writeLock().unlock(); |
|
} |
|
|
|
// Remove the appropriate deed. |
|
if (buildingCreated == true) |
|
if (contract != null) { |
|
playerCharacter.getCharItemManager().delete(contract); |
|
playerCharacter.getCharItemManager().updateInventory(); |
|
} |
|
|
|
// Close the window. We're done! |
|
//DONT CLOSE THE WINDOW IF WALL KTHANX |
|
|
|
if (close) |
|
closePlaceAssetWindow(origin); |
|
return true; |
|
} |
|
|
|
private boolean placeSingleBuilding(PlayerCharacter playerCharacter, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
PlacementInfo buildingList; |
|
Zone serverZone; |
|
|
|
// Retrieve the building details we're placing |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
// Early exit if something went horribly wrong |
|
// with locating the current or zone |
|
|
|
if (serverZone == null) { |
|
Logger.error("Null zone in placeSingleBuilding"); |
|
return false; |
|
} |
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateBuildingPlacement(serverZone, msg, origin, playerCharacter, buildingList) == false) |
|
return false; // Close window here? |
|
|
|
// Place the building |
|
if (createStructure(playerCharacter, buildingList, serverZone) == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private boolean placeWarehouse(PlayerCharacter player, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Zone serverZone; |
|
City cityObject; |
|
PlacementInfo buildingList; |
|
|
|
// Retrieve the building details we're placing |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
// Setup working variables we'll need |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
|
|
if (serverZone == null) |
|
return false; |
|
|
|
cityObject = City.getCity(serverZone.playerCityUUID); |
|
|
|
// Early exit if something went horribly wrong |
|
|
|
if (cityObject == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); |
|
return false; |
|
} |
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateCityBuildingPlacement(serverZone, msg, origin, player, buildingList) == false) |
|
return false; |
|
|
|
if (cityObject.getWarehouse() != null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 50, ""); //"You can only have one warehouse" |
|
return false; |
|
} |
|
|
|
// Create the warehouse object and it's entry in the database |
|
|
|
if (createWarehouse(player, msg.getFirstPlacementInfo(), serverZone) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private boolean placeSiegeEquip(PlayerCharacter player, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Zone serverZone; |
|
Building siegeBuilding; |
|
PlacementInfo buildingList; |
|
City serverCity; |
|
Bane bane; |
|
|
|
// Retrieve the building details we're placing |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
// Setup working variables we'll need |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
// with locating the current city and/or zone |
|
|
|
if (serverZone == null) { |
|
Logger.error("Error obtaining reference to zone"); |
|
return false; |
|
} |
|
|
|
serverCity = ZoneManager.getCityAtLocation(buildingList.getLoc()); |
|
|
|
// No valid player city found |
|
|
|
if (serverCity == null || serverCity.getParent().guild_zone == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); // Cannot place outisde a guild zone |
|
return false; |
|
} |
|
|
|
// No bane no bow |
|
|
|
bane = serverCity.getBane(); |
|
|
|
if (bane == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 66, ""); // There is no bane circle to support this building of war |
|
return false; |
|
} |
|
|
|
// Must belong to either attacker or defenders. |
|
|
|
if ((player.getGuild().equals(serverCity.getBane().getOwner().getGuild()) == false) |
|
&& (player.getGuild().equals(serverCity.getGuild()) == false)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 54, ""); // Must belong to attacker or defender |
|
return false; |
|
} |
|
|
|
// Player must be GL or IC of the bane guild to place bow. |
|
|
|
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false |
|
&& GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 10, player.getName()); // You must be a guild leader to place this asset |
|
return false; |
|
} |
|
|
|
// Attackers cannot place on grid until bane is live |
|
|
|
if (bane.getSiegePhase() != SiegePhase.WAR && |
|
player.getGuild().equals(serverCity.getBane().getOwner().getGuild()) && |
|
serverCity.isLocationOnCityGrid(buildingList.getLoc())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 53, player.getName()); // Buildings of war cannot be placed around a city grid unless there is an active bane |
|
return false; |
|
} |
|
|
|
// If there is a bane placed, we limit bow placement to 2x the stone rank's worth of attacker assets |
|
// and 1x the tree rank for defenders |
|
|
|
if (validateSiegeLimits(player, origin, serverCity.getBane()) == false) |
|
return false; |
|
|
|
// Collision check (Removes rubble side effect) |
|
|
|
if (placementCollisionCheck(serverZone, origin, buildingList)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 3, ""); // Conflict between proposed assets |
|
return false; |
|
} |
|
|
|
// Create the siege Building |
|
|
|
siegeBuilding = createStructure(player, msg.getFirstPlacementInfo(), serverZone); |
|
|
|
// Oops something went really wrong |
|
|
|
if (siegeBuilding == null) |
|
return false; |
|
|
|
// passes validation: can assign auto-protection to war asset |
|
|
|
siegeBuilding.setProtectionState(ProtectionState.PROTECTED); |
|
|
|
return true; |
|
} |
|
|
|
private boolean validateSiegeLimits(PlayerCharacter playerCharacter, ClientConnection origin, Bane bane) { |
|
|
|
City serverCity = bane.getCity(); |
|
HashSet<AbstractWorldObject> awoList; |
|
HashSet<AbstractWorldObject> attackerBuildings = new HashSet<>(); |
|
HashSet<AbstractWorldObject> defenderBuildings = new HashSet<>(); |
|
; |
|
int maxAttackerAssets = serverCity.getBane().getStone().getRank() * 2; |
|
int maxDefenderAssets = serverCity.getRank(); |
|
|
|
// Count bow for attackers and defenders |
|
|
|
awoList = WorldGrid.getObjectsInRangePartial(serverCity, 1000, MBServerStatics.MASK_BUILDING); |
|
|
|
for (AbstractWorldObject awo : awoList) { |
|
Building building = (Building) awo; |
|
|
|
if (building.getBlueprint() != null) |
|
if (!building.getBlueprint().isSiegeEquip()) |
|
continue; |
|
|
|
if (!building.getLoc().isInsideCircle(serverCity.getLoc(), CityBoundsType.ZONE.halfExtents)) |
|
continue; |
|
|
|
if (building.getGuild() == null) |
|
continue; |
|
|
|
if (building.getGuild().isEmptyGuild()) |
|
continue; |
|
|
|
if (!building.getGuild().equals(serverCity.getGuild()) && !building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) |
|
continue; |
|
if (building.getRank() < 0) { |
|
continue; |
|
} |
|
if (building.getGuild().equals(serverCity.getGuild())) |
|
defenderBuildings.add(building); |
|
|
|
if (building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) |
|
attackerBuildings.add(building); |
|
|
|
} |
|
// Validate bane limits on siege assets |
|
|
|
if (playerCharacter.getGuild().equals(serverCity.getGuild())) { |
|
//defender attempting to place asset |
|
if (defenderBuildings.size() >= maxDefenderAssets) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 62, ""); |
|
return false; |
|
} |
|
} |
|
|
|
if (playerCharacter.getGuild().equals(serverCity.getBane().getStone().getGuild())) { |
|
//attacker attempting to place asset |
|
if (attackerBuildings.size() >= maxAttackerAssets) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 61, ""); |
|
return false; |
|
} |
|
} |
|
|
|
// Passed validation |
|
|
|
return true; |
|
} |
|
|
|
private boolean placeTreeOfLife(PlayerCharacter playerCharacter, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Realm serverRealm; |
|
Zone serverZone; |
|
ArrayList<AbstractGameObject> cityObjects; // MySql result set |
|
HashMap<GameObjectType, AbstractGameObject> cityObjectMap = new HashMap<>(); |
|
PlacementInfo treeInfo; |
|
Guild playerNation; |
|
PlacementInfo treePlacement = msg.getFirstPlacementInfo(); |
|
Building treeObject; |
|
City cityObject; |
|
Zone zoneObject; |
|
|
|
// Setup working variables we'll need |
|
|
|
serverRealm = RealmMap.getRealmAtLocation(treePlacement.getLoc()); |
|
serverZone = ZoneManager.findSmallestZone(treePlacement.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
// with locating the current realm and/or zone |
|
|
|
if (serverRealm == null || serverZone == null) |
|
return false; |
|
|
|
// Method checks validation conditions arising when placing |
|
// trees |
|
|
|
if (validateTreeOfLifePlacement(playerCharacter, serverRealm, serverZone, origin, msg) == false) |
|
return false; |
|
|
|
// Retrieve tree info for the w value it's passing. |
|
|
|
treeInfo = msg.getFirstPlacementInfo(); |
|
|
|
if (treeInfo == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x, |
|
0, |
|
treeInfo.getLoc().z); |
|
|
|
cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(), |
|
serverRealm.getRealmID(), |
|
plantLoc.x - serverZone.absX, plantLoc.y, |
|
plantLoc.z - serverZone.absZ, treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now()); |
|
|
|
// Uh oh! |
|
|
|
if (cityObjects == null || cityObjects.isEmpty()) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
// Assign our worker variables after figuring out what |
|
// is what in the result set. |
|
|
|
for (AbstractGameObject gameObject : cityObjects) |
|
cityObjectMap.put(gameObject.getObjectType(), gameObject); |
|
|
|
treeObject = (Building) cityObjectMap.get(GameObjectType.Building); |
|
cityObject = (City) cityObjectMap.get(GameObjectType.City); |
|
zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone); |
|
|
|
// not allowed to plant a tree if ur not an errant guild. |
|
// Desub from any previous nation. |
|
// This should be done automatically in a method inside Guild *** Refactor |
|
// Player is now a Sovereign guild, configure them as such. |
|
|
|
playerCharacter.getGuild().setNation(playerCharacter.getGuild()); |
|
playerNation = playerCharacter.getGuild(); |
|
playerNation.setGuildState(GuildState.Sovereign); |
|
|
|
// Update guild binds and tags |
|
|
|
GuildManager.updateAllGuildBinds(playerNation, cityObject); |
|
GuildManager.updateAllGuildTags(playerNation); |
|
|
|
//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.halfExtents, Enum.CityBoundsType.ZONE.halfExtents); |
|
DispatchMessage.dispatchMsgToAll(czm); |
|
|
|
// Set maintenance date |
|
|
|
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7)); |
|
|
|
// Send all the cities to the clients? |
|
// *** Refactor : figure out how to send like, one? |
|
|
|
City.lastCityUpdate = System.currentTimeMillis(); |
|
treeObject.setLoc(treeObject.getLoc()); |
|
|
|
// As this is a new static object set it's dirtyFlag |
|
// so players already near it will have the object loaded. |
|
|
|
InterestManager.setObjectDirty(treeObject); |
|
|
|
serverRealm.addCity(cityObject.getObjectUUID()); |
|
playerNation.setCityUUID(cityObject.getObjectUUID()); |
|
|
|
// Bypass warehouse entry if we're an admin |
|
|
|
if (playerCharacter.getAccount().status.equals(AccountStatus.ADMIN)) |
|
return true; |
|
|
|
// Push this event to the data warehouse |
|
|
|
CityRecord cityRecord = CityRecord.borrow(cityObject, RecordEventType.CREATE); |
|
DataWarehouse.pushToWarehouse(cityRecord); |
|
|
|
return true; |
|
} |
|
|
|
// Method validates the location we have selected for our new city |
|
|
|
private boolean placeSpire(PlayerCharacter playerCharacter, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Zone serverZone; |
|
Building spireBuilding; |
|
Blueprint blueprint; |
|
City cityObject; |
|
PlacementInfo buildingList; |
|
|
|
// Setup working variables we'll need |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
// with locating the current realm and/or city |
|
|
|
if (serverZone == null) |
|
return false; |
|
|
|
cityObject = City.getCity(serverZone.playerCityUUID); |
|
|
|
if (cityObject == null) |
|
return false; |
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateCityBuildingPlacement(serverZone, msg, origin, playerCharacter, buildingList) == false) |
|
return false; |
|
|
|
// Loop through all buildings in this city looking for a spire of the. |
|
// same type we are placing. There can be only one of each type |
|
|
|
int spireCount = 0; |
|
|
|
blueprint = Blueprint.getBlueprint(msg.getFirstPlacementInfo().getBlueprintUUID()); |
|
|
|
for (Building building : serverZone.zoneBuildingSet) { |
|
|
|
if (building.getBlueprint().getBuildingGroup() == BuildingGroup.SPIRE) { |
|
|
|
if (building.getBlueprintUUID() == blueprint.getMeshForRank(0)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 46, ""); // "Spire of that type exists" |
|
return false; |
|
} |
|
spireCount++; |
|
} |
|
} |
|
|
|
// Too many spires for this tree's rank? |
|
|
|
if (spireCount >= Blueprint.getMaxShrines(cityObject.getTOL().getRank())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 45, ""); //Tree cannot support anymore spires |
|
return false; |
|
} |
|
|
|
// Create the spire |
|
|
|
spireBuilding = createStructure(playerCharacter, msg.getFirstPlacementInfo(), serverZone); |
|
return spireBuilding != null; |
|
} |
|
|
|
private boolean placeShrine(PlayerCharacter playerCharacter, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Zone serverZone; |
|
Blueprint blueprint; |
|
City cityObject; |
|
PlacementInfo buildingList; |
|
|
|
// Setup working variables we'll need |
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
// with locating the current realm and/or zone |
|
|
|
if (serverZone == null) |
|
return false; |
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateCityBuildingPlacement(serverZone, msg, origin, playerCharacter, buildingList) == false) |
|
return false; |
|
|
|
// Loop through all buildings in this city looking for a shrine of the. |
|
// same type we are placing. There can be only one of each type |
|
|
|
int shrineCount = 0; |
|
|
|
cityObject = City.getCity(serverZone.playerCityUUID); |
|
|
|
// Cannot place shrine in abandoned city. Shrines must be owned |
|
// by the tol owner not the person placing them. |
|
|
|
if (cityObject.getTOL().getOwnerUUID() == 0) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 42, ""); //Tree cannot support anymore shrines |
|
return false; |
|
} |
|
|
|
blueprint = Blueprint.getBlueprint(msg.getFirstPlacementInfo().getBlueprintUUID()); |
|
|
|
if (blueprint == null) { |
|
return false; |
|
} |
|
|
|
for (Building building : serverZone.zoneBuildingSet) { |
|
if (building.getBlueprint() == null) |
|
continue; |
|
|
|
if (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE) { |
|
if (building.getBlueprintUUID() == blueprint.getMeshForRank(0)) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 43, ""); // "shrine of that type exists" |
|
return false; |
|
} |
|
shrineCount++; |
|
} |
|
} |
|
|
|
// Too many shrines for this tree's rank? |
|
|
|
if (shrineCount >= Blueprint.getMaxShrines(cityObject.getTOL().getRank())) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 42, ""); //Tree cannot support anymore shrines |
|
return false; |
|
} |
|
|
|
// Create the shrine |
|
|
|
return createShrine((PlayerCharacter) cityObject.getTOL().getOwner(), msg.getFirstPlacementInfo(), serverZone); |
|
} |
|
|
|
private boolean placeBarrack(PlayerCharacter playerCharacter, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
Zone serverZone; |
|
City cityObject; |
|
PlacementInfo buildingList; |
|
|
|
// Setup working variables |
|
|
|
buildingList = msg.getFirstPlacementInfo(); |
|
|
|
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
// with locating the current realm and/or zone |
|
|
|
if (serverZone == null) |
|
return false; |
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateCityBuildingPlacement(serverZone, msg, origin, playerCharacter, buildingList) == false) |
|
return false; |
|
|
|
// Loop through all buildings in this city counting barracks . |
|
|
|
int barracksCount = 0; |
|
|
|
cityObject = City.getCity(serverZone.playerCityUUID); |
|
|
|
// Cannot place barracks in abandoned city. |
|
|
|
if (cityObject.getTOL().getOwnerUUID() == 0) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 42, ""); //Tree cannot support anymore shrines |
|
return false; |
|
} |
|
|
|
for (Building building : serverZone.zoneBuildingSet) { |
|
if (building.getBlueprint().getBuildingGroup() == BuildingGroup.BARRACK) |
|
barracksCount++; |
|
} |
|
|
|
// Too many shrines for this tree's rank? |
|
|
|
if (barracksCount >= cityObject.getTOL().getRank()) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 47, ""); //Tree cannot support anymore shrines |
|
return false; |
|
} |
|
|
|
// Create the shrine |
|
|
|
return createBarracks((PlayerCharacter) cityObject.getTOL().getOwner(), msg.getFirstPlacementInfo(), serverZone); |
|
} |
|
|
|
private boolean placeCityWalls(PlayerCharacter player, ClientConnection origin, PlaceAssetMsg msg) { |
|
|
|
// Member variables |
|
|
|
Zone serverZone; |
|
City cityObject; |
|
int placementCost = 0; |
|
CharacterItemManager itemMan; |
|
Item goldItem; |
|
Building wallPiece; |
|
|
|
// Setup working variables we'll need |
|
|
|
serverZone = ZoneManager.findSmallestZone(player.getLoc()); |
|
|
|
// Early exit if something went horribly wrong |
|
|
|
if (serverZone == null) |
|
return false; |
|
|
|
|
|
if (player.getCharItemManager().getGoldTrading() > 0) { |
|
ErrorPopupMsg.sendErrorPopup(player, 195); |
|
return false; |
|
} |
|
|
|
|
|
// Method checks validation conditions arising when placing |
|
// buildings. Player must be on a city grid, must be |
|
// inner council of the city's guild, etc. |
|
|
|
if (validateCityBuildingPlacement(serverZone, msg, origin, player, msg.getFirstPlacementInfo()) == false) |
|
return false; |
|
|
|
cityObject = City.getCity(serverZone.playerCityUUID); |
|
|
|
// We need to be able to access how much gold a character is carrying |
|
|
|
itemMan = player.getCharItemManager(); |
|
|
|
if (itemMan == null) |
|
|
|
return false; |
|
|
|
goldItem = itemMan.getGoldInventory(); |
|
|
|
// Grab list of walls we're placing |
|
|
|
ArrayList<PlacementInfo> walls = msg.getPlacementInfo(); |
|
|
|
// Character must be able to afford walls |
|
|
|
for (PlacementInfo wall : walls) { |
|
placementCost += PlaceAssetMsg.getWallCost(wall.getBlueprintUUID()); |
|
} |
|
|
|
// Early exit if not enough gold in character's inventory to place walls |
|
|
|
if (placementCost > goldItem.getNumOfItems()) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 28, ""); // Not enough gold |
|
return false; |
|
} |
|
|
|
placementCost = 0; // reset placement cost for fix bug with wall pieces somethings not taking gold out if forced an error. |
|
|
|
// Overlap check and wall deed verifications |
|
for (PlacementInfo wall : walls) { |
|
|
|
if (Blueprint.isMeshWallPiece(wall.getBlueprintUUID()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 48, ""); //"Assets (except walls) must be placed one at a time" |
|
continue; |
|
} |
|
|
|
// Ignore wall pieces not on the city grid |
|
if (cityObject.isLocationOnCityGrid(wall.getLoc()) == false) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Asset " + cityObject.getName() + " not on citygrid"); |
|
continue; |
|
} |
|
|
|
// Does this wall collide with any other building? |
|
|
|
for (Building building : serverZone.zoneBuildingSet) { |
|
|
|
//TODO Clean up collision with placementInfo. don't need to create the same placementinfo bounds for collision checks on each building. |
|
if ((building.getBlueprintUUID() != 0) && (Bounds.collide(wall, building) == true)) { |
|
|
|
if (building.getRank() == -1) { |
|
building.removeFromCache(); |
|
WorldGrid.RemoveWorldObject(building); |
|
WorldGrid.removeObject(building); |
|
building.getParentZone().parent.zoneBuildingSet.remove(building); |
|
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) { |
|
building.RemoveFromBarracksList(); |
|
} |
|
continue; |
|
} |
|
// remove gold from walls already placed before returning. |
|
|
|
PlaceAssetMsg.sendPlaceAssetError(origin, 3, building.getName()); //"Conflict between assets" |
|
return false; |
|
} |
|
} |
|
|
|
placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID()); |
|
|
|
if (!itemMan.modifyInventoryGold(-placementCost)) { |
|
ChatManager.chatSystemInfo(player, player.getFirstName() + " can't has free moneys! no for real.. Thor.. seriously... I didnt fix it because you getting laid isnt important enough for me."); |
|
return false; |
|
} |
|
|
|
// Attempt to place wall piece |
|
|
|
wallPiece = createStructure(player, wall, serverZone); |
|
|
|
if (wallPiece == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
continue; |
|
} |
|
|
|
// walls are auto protected |
|
|
|
wallPiece.setProtectionState(ProtectionState.PROTECTED); |
|
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone); |
|
|
|
} |
|
|
|
return true; |
|
} |
|
|
|
private Building createStructure(PlayerCharacter playerCharacter, PlacementInfo buildingInfo, Zone currentZone) { |
|
|
|
Blueprint blueprint; |
|
Building newMesh; |
|
DateTime completionDate; |
|
float vendorRotation; |
|
float buildingRotation; |
|
|
|
blueprint = Blueprint.getBlueprint(buildingInfo.getBlueprintUUID()); |
|
|
|
if (blueprint == null) { |
|
Logger.error("CreateStructure: DB returned null blueprint."); |
|
return null; |
|
} |
|
|
|
// All siege buildings build in 15 minutes |
|
|
|
if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT)) |
|
|| (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK))) |
|
completionDate = DateTime.now().plusMinutes(15); |
|
else |
|
completionDate = DateTime.now().plusHours(blueprint.getRankTime(1)); |
|
|
|
Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone)); |
|
|
|
buildingRotation = buildingInfo.getRot().y; |
|
vendorRotation = buildingInfo.getW(); |
|
|
|
// if W return is negative, this is a -90 rotation not a 90? |
|
|
|
newMesh = DbManager.BuildingQueries.CREATE_BUILDING( |
|
currentZone.getObjectUUID(), playerCharacter.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), |
|
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0, |
|
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation); |
|
|
|
// Make sure we have a valid mesh |
|
|
|
if (newMesh == null) { |
|
Logger.error("CreateStructure: DB returned null object."); |
|
return null; |
|
} |
|
|
|
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); |
|
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); |
|
|
|
newMesh.setLoc(newMesh.getLoc()); |
|
InterestManager.setObjectDirty(newMesh); |
|
return newMesh; |
|
|
|
} |
|
|
|
// Validates that player is able to place buildings |
|
|
|
private boolean createShrine(PlayerCharacter player, PlacementInfo buildingInfo, Zone currentZone) { |
|
|
|
Blueprint blueprint; |
|
Building newMesh; |
|
Shrine newShrine; |
|
City city; |
|
ShrineType shrineType; |
|
|
|
if (player == null) |
|
return false; |
|
|
|
blueprint = Blueprint.getBlueprint(buildingInfo.getBlueprintUUID()); |
|
|
|
if (blueprint == null) { |
|
Logger.error("CreateShrine: DB returned null blueprint."); |
|
return false; |
|
} |
|
|
|
shrineType = Shrine.getShrineTypeByBlueprintUUID(blueprint.getBlueprintUUID()); |
|
|
|
city = City.getCity(currentZone.playerCityUUID); |
|
|
|
if (city == null) |
|
return false; |
|
|
|
if (!city.isLocationOnCityGrid(buildingInfo.getLoc())) |
|
return false; |
|
|
|
Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone)); |
|
|
|
float buildingRotation = buildingInfo.getRot().y; |
|
float vendorRotation = buildingInfo.getW(); |
|
|
|
|
|
ArrayList<AbstractGameObject> shrineObjects = DbManager.ShrineQueries.CREATE_SHRINE( |
|
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), |
|
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0, |
|
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation, shrineType.name()); |
|
|
|
if (shrineObjects == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
for (AbstractGameObject ago : shrineObjects) { |
|
|
|
switch (ago.getObjectType()) { |
|
case Building: |
|
newMesh = (Building) ago; |
|
newMesh.runAfterLoad(); |
|
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); |
|
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); |
|
newMesh.setLoc(newMesh.getLoc()); |
|
InterestManager.setObjectDirty(newMesh); |
|
break; |
|
case Shrine: |
|
newShrine = (Shrine) ago; |
|
newShrine.getShrineType().addShrineToServerList(newShrine); |
|
break; |
|
default: |
|
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
break; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private boolean createBarracks(PlayerCharacter player, PlacementInfo buildingInfo, Zone currentZone) { |
|
|
|
Blueprint blueprint; |
|
Building newMesh; |
|
Shrine newShrine; |
|
City city; |
|
|
|
if (player == null) |
|
return false; |
|
|
|
blueprint = Blueprint.getBlueprint(buildingInfo.getBlueprintUUID()); |
|
|
|
if (blueprint == null) { |
|
Logger.error("CreateShrine: DB returned null blueprint."); |
|
return false; |
|
} |
|
|
|
city = City.getCity(currentZone.playerCityUUID); |
|
|
|
if (city == null) |
|
return false; |
|
|
|
if (!city.isLocationOnCityGrid(buildingInfo.getLoc())) |
|
return false; |
|
|
|
Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone)); |
|
|
|
float buildingRotation = buildingInfo.getRot().y; |
|
float vendorRotation = buildingInfo.getW(); |
|
DateTime completionDate = DateTime.now().plusHours(blueprint.getRankTime(1)); |
|
|
|
|
|
newMesh = DbManager.BuildingQueries.CREATE_BUILDING( |
|
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), |
|
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0, |
|
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation); |
|
|
|
// Make sure we have a valid mesh |
|
if (newMesh == null) { |
|
Logger.error("CreateStructure: DB returned null object."); |
|
return false; |
|
} |
|
|
|
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); |
|
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); |
|
newMesh.setLoc(newMesh.getLoc()); |
|
InterestManager.setObjectDirty(newMesh); |
|
|
|
return true; |
|
} |
|
|
|
private boolean createWarehouse(PlayerCharacter player, PlacementInfo buildingInfo, Zone currentZone) { |
|
|
|
Blueprint blueprint; |
|
Building newMesh = null; |
|
ArrayList<AbstractGameObject> warehouseObjects; |
|
|
|
blueprint = Blueprint.getBlueprint(buildingInfo.getBlueprintUUID()); |
|
|
|
if (blueprint == null) { |
|
Logger.error("CreateWarehouse: DB returned null blueprint."); |
|
return false; |
|
} |
|
|
|
Vector3fImmutable localLoc = new Vector3fImmutable(ZoneManager.worldToLocal(buildingInfo.getLoc(), currentZone)); |
|
|
|
float buildingRotation = buildingInfo.getRot().y; |
|
float vendorRotation = buildingInfo.getW(); |
|
|
|
warehouseObjects = DbManager.WarehouseQueries.CREATE_WAREHOUSE( |
|
currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), |
|
localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.NONE, 0, 0, |
|
DateTime.now().plusHours(blueprint.getRankTime(1)), blueprint.getMeshForRank(0), vendorRotation, buildingRotation); |
|
|
|
if (warehouseObjects == null) { |
|
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); |
|
return false; |
|
} |
|
|
|
// Load the building into the simulation |
|
|
|
for (AbstractGameObject ago : warehouseObjects) { |
|
|
|
if (ago.getObjectType() == GameObjectType.Building) { |
|
newMesh = (Building) ago; |
|
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); |
|
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); |
|
newMesh.setLoc(newMesh.getLoc()); |
|
InterestManager.setObjectDirty(newMesh); |
|
newMesh.runAfterLoad(); |
|
} else if (ago.getObjectType() == GameObjectType.Warehouse) { |
|
Warehouse warehouse = (Warehouse) ago; |
|
City city = City.getCity(currentZone.playerCityUUID); |
|
|
|
if (city == null) |
|
return true; |
|
|
|
city.setWarehouseBuildingID(newMesh.getObjectUUID()); |
|
Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse); |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
} |