2022-04-30 09:41:17 -04:00
package engine.net.client.handlers ;
2023-08-20 20:14:28 -04:00
import engine.InterestManagement.InterestManager ;
2022-04-30 09:41:17 -04:00
import engine.InterestManagement.RealmMap ;
import engine.InterestManagement.WorldGrid ;
import engine.db.archive.CityRecord ;
import engine.db.archive.DataWarehouse ;
import engine.gameManager.* ;
import engine.math.Bounds ;
import engine.math.Vector3fImmutable ;
2024-04-05 07:59:44 -04:00
import engine.mbEnums ;
import engine.mbEnums.* ;
2022-04-30 09:41:17 -04:00
import engine.net.Dispatch ;
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 ;
2023-03-31 10:08:44 -04:00
2022-04-30 09:41:17 -04:00
import java.time.LocalDateTime ;
import java.util.ArrayList ;
2023-01-15 08:57:54 -05:00
import java.util.HashMap ;
2022-04-30 09:41:17 -04:00
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 {
2023-07-15 09:23:48 -04:00
// 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 ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public PlaceAssetMsgHandler ( ) {
2022-04-30 09:41:17 -04:00
2024-05-12 11:55:12 -04:00
super ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static void closePlaceAssetWindow ( ClientConnection origin ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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 ) ;
2024-05-12 13:14:42 -04:00
DispatchManager . dispatchMsgDispatch ( dispatch , DispatchChannel . SECONDARY ) ;
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Default method: Validates and places all buildings that do not
// require special treatment in some fashion.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static boolean validateTreeOfLifePlacement ( PlayerCharacter playerCharacter , Realm serverRealm , Zone serverZone ,
ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PlacementInfo placementInfo = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Your guild already owns a tree
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( playerCharacter . getGuild ( ) . getOwnedCity ( ) ! = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " Your guild already owns a tree! " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Validate that the player is the leader of a guild
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( GuildStatusController . isGuildLeader ( playerCharacter . getGuildStatus ( ) ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 10 , " " ) ; // Must be a guild leader
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Validate that the player is the leader of a guild
// that is not currently Sovereign *** BUG? Doesn't look right. isGuildLeader()?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// All trees must be placed within a continent.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ! serverZone . isContinent ( ) ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 69 , " " ) ; // Tree must be within a territory
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverRealm = = null | | serverRealm . getCanPlaceCities ( ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 57 , playerCharacter . getName ( ) ) ; // No building may be placed within this territory
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot place a tree underwater
2022-04-30 09:41:17 -04:00
2023-09-20 14:31:48 -04:00
if ( ZoneManager . isLocUnderwater ( placementInfo . getLoc ( ) ) ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 6 , " " ) ; // Cannot place underwater
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//Test city not too close to any other zone
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ! ZoneManager . validTreePlacementLoc ( serverZone , placementInfo . getLoc ( ) . x , placementInfo . getLoc ( ) . z ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 39 , " " ) ; // Too close to another tree
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Validate that Realm is not at it's city limit
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverRealm . isRealmFull ( ) = = true ) {
int numCities ;
numCities = serverRealm . getNumCities ( ) ;
PlaceAssetMsg . sendPlaceAssetError ( origin , 58 , Integer . toString ( numCities ) ) ; // This territory is full
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static boolean validateBuildingPlacement ( Zone serverZone , PlaceAssetMsg msg , ClientConnection origin , PlayerCharacter player , PlacementInfo placementInfo ) {
2022-04-30 09:41:17 -04:00
2023-09-20 16:05:57 -04:00
if ( serverZone . guild_zone = = false ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 52 , player . getName ( ) ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
City city = ZoneManager . getCityAtLocation ( placementInfo . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( player . getGuild ( ) . equals ( city . getGuild ( ) ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 40 , player . getName ( ) ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( city . isLocationOnCityGrid ( placementInfo . getLoc ( ) ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 41 , player . getName ( ) ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Retrieve the building details we're placing
2023-01-14 16:31:58 -05:00
2023-09-20 15:43:01 -04:00
if ( serverZone . isNPCCity = = true ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 15 , " " ) ; // Cannot place in a peace zone
return false ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
// Errant guilds cannot place assets
2023-01-14 16:31:58 -05:00
2023-07-15 09:23:48 -04:00
if ( player . getGuild ( ) . getGuildState ( ) = = GuildState . Errant ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " Only sovereign or sworn guilds may place assets. " ) ;
return false ;
}
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
// Player must be GL or IC of a guild to place buildings.
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
if ( GuildStatusController . isGuildLeader ( player . getGuildStatus ( ) ) = = false & & GuildStatusController . isInnerCouncil ( player . getGuildStatus ( ) ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 10 , " " ) ; // You must be a guild leader
return false ;
}
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
// Cannot place a building underwater
2023-01-14 15:34:23 -05:00
2023-09-20 14:31:48 -04:00
if ( ZoneManager . isLocUnderwater ( placementInfo . getLoc ( ) ) ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 6 , " " ) ; // Cannot place underwater
return false ;
}
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
// Players cannot place buildings in mob zones.
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
if ( ( serverZone . isMacroZone ( ) = = true )
2023-09-20 15:43:01 -04:00
| | ( serverZone . parent . isMacroZone ( ) = = true ) ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 57 , player . getName ( ) ) ; // No building may be placed within this territory
return false ;
}
2023-01-15 08:18:23 -05:00
2023-07-31 21:55:20 -05:00
Realm serverRealm = RealmMap . getRealmAtLocation ( city . getLoc ( ) ) ;
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
// Cannot place buildings on seafloor or other restricted realms
2023-01-14 15:34:23 -05:00
2023-07-15 09:23:48 -04:00
if ( serverRealm = = null | | serverRealm . getCanPlaceCities ( ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 57 , player . getName ( ) ) ; // No building may be placed within this territory
return false ;
}
2023-01-15 08:31:56 -05:00
2023-07-15 09:23:48 -04:00
// Cannot place assets on a dead tree
2022-04-30 09:41:17 -04:00
2023-09-20 16:05:57 -04:00
if ( ( serverZone . guild_zone )
2023-09-20 15:53:41 -04:00
& & ( City . getCity ( serverZone . playerCityUUID ) . getTOL ( ) . getRank ( ) = = - 1 ) ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " Cannot place asset on dead tree until world heals " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( placementCollisionCheck ( serverZone , origin , placementInfo ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 3 , " " ) ; // Conflict between proposed assets
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
private static boolean placementCollisionCheck ( Zone serverZone , ClientConnection origin , PlacementInfo placementInfo ) {
// Overlap check
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
for ( Building building : serverZone . zoneBuildingSet ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ( building . getBlueprintUUID ( ) ! = 0 ) & & ( Bounds . collide ( placementInfo , building ) = = true ) ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Ignore and remove from simulation if we are placing over rubble
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getRank ( ) = = - 1 ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ( building . getBlueprintUUID ( ) ! = 0 )
& & ( building . getBlueprint ( ) . getBuildingGroup ( ) = = BuildingGroup . SHRINE ) ) {
Shrine . RemoveShrineFromCacheByBuilding ( building ) ;
if ( building . getCity ( ) ! = null ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 3 , " " ) ; // Conflict between proposed assets
return true ;
}
}
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static boolean validateCityBuildingPlacement ( Zone serverZone , PlaceAssetMsg msg , ClientConnection origin , PlayerCharacter player , PlacementInfo buildingInfo ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Perform shared common validation first
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateBuildingPlacement ( serverZone , msg , origin , player , buildingInfo ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Must be a player city
2022-04-30 09:41:17 -04:00
2023-09-20 16:05:57 -04:00
if ( serverZone . guild_zone = = false ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 41 , player . getName ( ) ) ; // Cannot place outside a guild zone
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//Test zone has a city object
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
City city = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( city = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 52 , " " ) ; //"no city to associate asset with"
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// City assets must be placed on the city grid
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ! city . isLocationOnCityGrid ( buildingInfo . getLoc ( ) ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 52 , " " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Make sure it's not an errant tree
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ( city . getGuild ( ) = = null | | city . getGuild ( ) . isEmptyGuild ( ) = = true ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 18 , " " ) ; //"There are no guild trees to be found"
return false ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
//Test player is in correct guild to place buildings
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
@Override
2024-05-12 13:42:11 -04:00
protected boolean _handleNetMsg ( ClientNetMsg baseMsg , ClientConnection origin ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Member variable declaration
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PlaceAssetMsg msg ;
Boolean buildingCreated ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Character location and session
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ( ) ) {
2024-03-11 12:07:46 -04:00
if ( inventoryItem . template . item_type . equals ( ItemType . DEED ) & &
inventoryItem . template . deed_structure_id = = buildingList . getBlueprintUUID ( ) ) {
2023-07-15 09:23:48 -04:00
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 ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
break ;
buildingCreated = placeWarehouse ( playerCharacter , origin , msg ) ;
break ;
case SIEGETENT :
case BULWARK :
if ( contract = = null )
break ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
break ;
buildingCreated = placeSiegeEquip ( playerCharacter , origin , msg ) ;
break ;
case SPIRE :
if ( contract = = null )
break ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
break ;
buildingCreated = placeSpire ( playerCharacter , origin , msg ) ;
break ;
case SHRINE :
if ( contract = = null )
break ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
break ;
buildingCreated = placeShrine ( playerCharacter , origin , msg ) ;
break ;
case BARRACK :
if ( contract = = null )
break ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
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 ;
2024-03-18 10:01:29 -04:00
if ( ! playerCharacter . charItemManager . doesCharOwnThisItem ( contract . getObjectUUID ( ) ) )
2023-07-15 09:23:48 -04:00
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 ) {
2024-03-18 10:01:29 -04:00
playerCharacter . charItemManager . delete ( contract ) ;
playerCharacter . charItemManager . updateInventory ( ) ;
2023-07-15 09:23:48 -04:00
}
// 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 ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
City cityObject ;
PlacementInfo buildingList ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Retrieve the building details we're placing
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
buildingList = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
cityObject = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( cityObject = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 52 , " " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateCityBuildingPlacement ( serverZone , msg , origin , player , buildingList ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2024-03-17 09:47:00 -04:00
if ( cityObject . warehouse ! = null ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 50 , " " ) ; //"You can only have one warehouse"
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create the warehouse object and it's entry in the database
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeSiegeEquip ( PlayerCharacter player , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
Building siegeBuilding ;
PlacementInfo buildingList ;
City serverCity ;
Bane bane ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Retrieve the building details we're placing
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
buildingList = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
// with locating the current city and/or zone
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null ) {
Logger . error ( " Error obtaining reference to zone " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverCity = ZoneManager . getCityAtLocation ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// No valid player city found
2022-04-30 09:41:17 -04:00
2023-09-20 16:05:57 -04:00
if ( serverCity = = null | | serverCity . getParent ( ) . guild_zone = = false ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 52 , " " ) ; // Cannot place outisde a guild zone
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// No bane no bow
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
bane = serverCity . getBane ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( bane = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 66 , " " ) ; // There is no bane circle to support this building of war
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Must belong to either attacker or defenders.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Player must be GL or IC of the bane guild to place bow.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Attackers cannot place on grid until bane is live
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateSiegeLimits ( player , origin , serverCity . getBane ( ) ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Collision check (Removes rubble side effect)
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( placementCollisionCheck ( serverZone , origin , buildingList ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 3 , " " ) ; // Conflict between proposed assets
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create the siege Building
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
siegeBuilding = createStructure ( player , msg . getFirstPlacementInfo ( ) , serverZone ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Oops something went really wrong
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
if ( siegeBuilding = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// passes validation: can assign auto-protection to war asset
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
siegeBuilding . setProtectionState ( ProtectionState . PROTECTED ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean validateSiegeLimits ( PlayerCharacter playerCharacter , ClientConnection origin , Bane bane ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Count bow for attackers and defenders
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
awoList = WorldGrid . getObjectsInRangePartial ( serverCity , 1000 , MBServerStatics . MASK_BUILDING ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( AbstractWorldObject awo : awoList ) {
Building building = ( Building ) awo ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getBlueprint ( ) ! = null )
if ( ! building . getBlueprint ( ) . isSiegeEquip ( ) )
continue ;
2022-04-30 09:41:17 -04:00
2023-09-17 12:23:06 -04:00
if ( ! building . getLoc ( ) . isInsideCircle ( serverCity . getLoc ( ) , CityBoundsType . ZONE . halfExtents ) )
2023-07-15 09:23:48 -04:00
continue ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getGuild ( ) = = null )
continue ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getGuild ( ) . isEmptyGuild ( ) )
continue ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getGuild ( ) . equals ( serverCity . getBane ( ) . getOwner ( ) . getGuild ( ) ) )
attackerBuildings . add ( building ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
// Validate bane limits on siege assets
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( playerCharacter . getGuild ( ) . equals ( serverCity . getGuild ( ) ) ) {
//defender attempting to place asset
if ( defenderBuildings . size ( ) > = maxDefenderAssets ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 62 , " " ) ;
return false ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( playerCharacter . getGuild ( ) . equals ( serverCity . getBane ( ) . getStone ( ) . getGuild ( ) ) ) {
//attacker attempting to place asset
if ( attackerBuildings . size ( ) > = maxAttackerAssets ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 61 , " " ) ;
return false ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Passed validation
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeTreeOfLife ( PlayerCharacter playerCharacter , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverRealm = RealmMap . getRealmAtLocation ( treePlacement . getLoc ( ) ) ;
serverZone = ZoneManager . findSmallestZone ( treePlacement . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
// with locating the current realm and/or zone
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverRealm = = null | | serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Method checks validation conditions arising when placing
// trees
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateTreeOfLifePlacement ( playerCharacter , serverRealm , serverZone , origin , msg ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Retrieve tree info for the w value it's passing.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
treeInfo = msg . getFirstPlacementInfo ( ) ;
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
if ( treeInfo = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " A Serious error has occurred. Please post details for to ensure transaction integrity " ) ;
return false ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
Vector3fImmutable plantLoc = new Vector3fImmutable ( treeInfo . getLoc ( ) . x ,
2023-09-13 07:29:29 -04:00
0 ,
2023-07-15 09:23:48 -04:00
treeInfo . getLoc ( ) . z ) ;
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
cityObjects = DbManager . CityQueries . CREATE_CITY ( playerCharacter . getObjectUUID ( ) , serverZone . getObjectUUID ( ) ,
2023-09-20 15:43:01 -04:00
plantLoc . x - serverZone . absX , plantLoc . y ,
plantLoc . z - serverZone . absZ , treeInfo . getRot ( ) . y , treeInfo . getW ( ) , playerCharacter . getGuild ( ) . getName ( ) , LocalDateTime . now ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Uh oh!
2023-09-13 07:29:29 -04:00
2023-07-15 09:23:48 -04:00
if ( cityObjects = = null | | cityObjects . isEmpty ( ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " A Serious error has occurred. Please post details for to ensure transaction integrity " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Assign our worker variables after figuring out what
// is what in the result set.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( AbstractGameObject gameObject : cityObjects )
cityObjectMap . put ( gameObject . getObjectType ( ) , gameObject ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
treeObject = ( Building ) cityObjectMap . get ( GameObjectType . Building ) ;
cityObject = ( City ) cityObjectMap . get ( GameObjectType . City ) ;
zoneObject = ( Zone ) cityObjectMap . get ( GameObjectType . Zone ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
playerCharacter . getGuild ( ) . setNation ( playerCharacter . getGuild ( ) ) ;
playerNation = playerCharacter . getGuild ( ) ;
playerNation . setGuildState ( GuildState . Sovereign ) ;
2022-04-30 09:41:17 -04:00
2023-10-18 09:38:19 -04:00
// Update guild binds and tags
2022-04-30 09:41:17 -04:00
2023-10-18 09:38:19 -04:00
GuildManager . updateAllGuildBinds ( playerNation , cityObject ) ;
GuildManager . updateAllGuildTags ( playerNation ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
//load the new city on the clients
2022-04-30 09:41:17 -04:00
2024-04-05 07:59:44 -04:00
CityZoneMsg czm = new CityZoneMsg ( 1 , treeObject . getLoc ( ) . x , treeObject . getLoc ( ) . y , treeObject . getLoc ( ) . z , cityObject . getCityName ( ) , zoneObject , mbEnums . CityBoundsType . ZONE . halfExtents , mbEnums . CityBoundsType . ZONE . halfExtents ) ;
2024-05-12 13:14:42 -04:00
DispatchManager . dispatchMsgToAll ( czm ) ;
2022-04-30 09:41:17 -04:00
2023-10-18 09:38:19 -04:00
// Set maintenance date
MaintenanceManager . setMaintDateTime ( treeObject , LocalDateTime . now ( ) . plusDays ( 7 ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Send all the cities to the clients?
// *** Refactor : figure out how to send like, one?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
City . lastCityUpdate = System . currentTimeMillis ( ) ;
2023-08-20 20:14:28 -04:00
treeObject . setLoc ( treeObject . getLoc ( ) ) ;
2023-12-24 09:44:01 -05:00
// As this is a new static object set it's dirtyFlag
// so players already near it will have the object loaded.
2023-08-20 20:14:28 -04:00
InterestManager . setObjectDirty ( treeObject ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverRealm . addCity ( cityObject . getObjectUUID ( ) ) ;
playerNation . setCityUUID ( cityObject . getObjectUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Bypass warehouse entry if we're an admin
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( playerCharacter . getAccount ( ) . status . equals ( AccountStatus . ADMIN ) )
return true ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Push this event to the data warehouse
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
CityRecord cityRecord = CityRecord . borrow ( cityObject , RecordEventType . CREATE ) ;
DataWarehouse . pushToWarehouse ( cityRecord ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Method validates the location we have selected for our new city
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeSpire ( PlayerCharacter playerCharacter , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
Building spireBuilding ;
Blueprint blueprint ;
City cityObject ;
PlacementInfo buildingList ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
buildingList = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
// with locating the current realm and/or city
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
cityObject = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( cityObject = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateCityBuildingPlacement ( serverZone , msg , origin , playerCharacter , buildingList ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int spireCount = 0 ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
blueprint = Blueprint . getBlueprint ( msg . getFirstPlacementInfo ( ) . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( Building building : serverZone . zoneBuildingSet ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getBlueprint ( ) . getBuildingGroup ( ) = = BuildingGroup . SPIRE ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getBlueprintUUID ( ) = = blueprint . getMeshForRank ( 0 ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 46 , " " ) ; // "Spire of that type exists"
return false ;
}
spireCount + + ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Too many spires for this tree's rank?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( spireCount > = Blueprint . getMaxShrines ( cityObject . getTOL ( ) . getRank ( ) ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 45 , " " ) ; //Tree cannot support anymore spires
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create the spire
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
spireBuilding = createStructure ( playerCharacter , msg . getFirstPlacementInfo ( ) , serverZone ) ;
return spireBuilding ! = null ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeShrine ( PlayerCharacter playerCharacter , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
Blueprint blueprint ;
City cityObject ;
PlacementInfo buildingList ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
buildingList = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
// with locating the current realm and/or zone
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateCityBuildingPlacement ( serverZone , msg , origin , playerCharacter , buildingList ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int shrineCount = 0 ;
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
cityObject = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot place shrine in abandoned city. Shrines must be owned
// by the tol owner not the person placing them.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( cityObject . getTOL ( ) . getOwnerUUID ( ) = = 0 ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 42 , " " ) ; //Tree cannot support anymore shrines
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
blueprint = Blueprint . getBlueprint ( msg . getFirstPlacementInfo ( ) . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( blueprint = = null ) {
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( Building building : serverZone . zoneBuildingSet ) {
if ( building . getBlueprint ( ) = = null )
continue ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( building . getBlueprint ( ) . getBuildingGroup ( ) = = BuildingGroup . SHRINE ) {
if ( building . getBlueprintUUID ( ) = = blueprint . getMeshForRank ( 0 ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 43 , " " ) ; // "shrine of that type exists"
return false ;
}
shrineCount + + ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Too many shrines for this tree's rank?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( shrineCount > = Blueprint . getMaxShrines ( cityObject . getTOL ( ) . getRank ( ) ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 42 , " " ) ; //Tree cannot support anymore shrines
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create the shrine
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return createShrine ( ( PlayerCharacter ) cityObject . getTOL ( ) . getOwner ( ) , msg . getFirstPlacementInfo ( ) , serverZone ) ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeBarrack ( PlayerCharacter playerCharacter , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
City cityObject ;
PlacementInfo buildingList ;
2022-04-30 09:41:17 -04:00
2023-09-13 09:24:40 -04:00
// Setup working variables
2023-07-15 09:23:48 -04:00
buildingList = msg . getFirstPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( buildingList . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
// with locating the current realm and/or zone
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateCityBuildingPlacement ( serverZone , msg , origin , playerCharacter , buildingList ) = = false )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Loop through all buildings in this city counting barracks .
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
int barracksCount = 0 ;
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
cityObject = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Cannot place barracks in abandoned city.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( cityObject . getTOL ( ) . getOwnerUUID ( ) = = 0 ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 42 , " " ) ; //Tree cannot support anymore shrines
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( Building building : serverZone . zoneBuildingSet ) {
if ( building . getBlueprint ( ) . getBuildingGroup ( ) = = BuildingGroup . BARRACK )
barracksCount + + ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
// Too many shrines for this tree's rank?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( barracksCount > = cityObject . getTOL ( ) . getRank ( ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 47 , " " ) ; //Tree cannot support anymore shrines
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Create the shrine
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return createBarracks ( ( PlayerCharacter ) cityObject . getTOL ( ) . getOwner ( ) , msg . getFirstPlacementInfo ( ) , serverZone ) ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean placeCityWalls ( PlayerCharacter player , ClientConnection origin , PlaceAssetMsg msg ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Member variables
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Zone serverZone ;
City cityObject ;
int placementCost = 0 ;
CharacterItemManager itemMan ;
Item goldItem ;
Building wallPiece ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Setup working variables we'll need
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
serverZone = ZoneManager . findSmallestZone ( player . getLoc ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if something went horribly wrong
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( serverZone = = null )
return false ;
2022-04-30 09:41:17 -04:00
2024-03-18 10:01:29 -04:00
if ( player . charItemManager . getGoldTrading ( ) > 0 ) {
2023-07-15 09:23:48 -04:00
ErrorPopupMsg . sendErrorPopup ( player , 195 ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( validateCityBuildingPlacement ( serverZone , msg , origin , player , msg . getFirstPlacementInfo ( ) ) = = false )
return false ;
2022-06-05 16:56:01 -04:00
2023-09-20 15:53:41 -04:00
cityObject = City . getCity ( serverZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// We need to be able to access how much gold a character is carrying
2022-04-30 09:41:17 -04:00
2024-03-18 10:01:29 -04:00
itemMan = player . charItemManager ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( itemMan = = null )
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
goldItem = itemMan . getGoldInventory ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Grab list of walls we're placing
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
ArrayList < PlacementInfo > walls = msg . getPlacementInfo ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Character must be able to afford walls
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( PlacementInfo wall : walls ) {
placementCost + = PlaceAssetMsg . getWallCost ( wall . getBlueprintUUID ( ) ) ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Early exit if not enough gold in character's inventory to place walls
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( placementCost > goldItem . getNumOfItems ( ) ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 28 , " " ) ; // Not enough gold
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
placementCost = 0 ; // reset placement cost for fix bug with wall pieces somethings not taking gold out if forced an error.
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Overlap check and wall deed verifications
for ( PlacementInfo wall : walls ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( Blueprint . isMeshWallPiece ( wall . getBlueprintUUID ( ) ) = = false ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 48 , " " ) ; //"Assets (except walls) must be placed one at a time"
continue ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// 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 ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Does this wall collide with any other building?
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( Building building : serverZone . zoneBuildingSet ) {
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
//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 ) ) {
2023-01-15 08:18:23 -05:00
2023-07-15 09:23:48 -04:00
if ( building . getRank ( ) = = - 1 ) {
building . removeFromCache ( ) ;
WorldGrid . RemoveWorldObject ( building ) ;
WorldGrid . removeObject ( building ) ;
2023-09-20 15:43:01 -04:00
building . getParentZone ( ) . parent . zoneBuildingSet . remove ( building ) ;
2023-07-15 09:23:48 -04:00
if ( building . getBlueprint ( ) ! = null & & building . getBlueprint ( ) . getBuildingGroup ( ) . equals ( BuildingGroup . BARRACK ) ) {
building . RemoveFromBarracksList ( ) ;
}
continue ;
}
// remove gold from walls already placed before returning.
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( origin , 3 , building . getName ( ) ) ; //"Conflict between assets"
return false ;
}
}
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
placementCost = PlaceAssetMsg . getWallCost ( wall . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
// Attempt to place wall piece
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
wallPiece = createStructure ( player , wall , serverZone ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( wallPiece = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( origin , 1 , " A Serious error has occurred. Please post details for to ensure transaction integrity " ) ;
continue ;
}
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
// walls are auto protected
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
wallPiece . setProtectionState ( ProtectionState . PROTECTED ) ;
PlaceAssetMsg . sendPlaceAssetConfirmWall ( origin , serverZone ) ;
2022-06-05 16:56:01 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private Building createStructure ( PlayerCharacter playerCharacter , PlacementInfo buildingInfo , Zone currentZone ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Blueprint blueprint ;
Building newMesh ;
DateTime completionDate ;
float vendorRotation ;
float buildingRotation ;
2023-02-08 09:09:54 -05:00
2023-07-15 09:23:48 -04:00
blueprint = Blueprint . getBlueprint ( buildingInfo . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( blueprint = = null ) {
Logger . error ( " CreateStructure: DB returned null blueprint. " ) ;
return null ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// All siege buildings build in 15 minutes
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
if ( ( blueprint . getBuildingGroup ( ) . equals ( BuildingGroup . SIEGETENT ) )
| | ( blueprint . getBuildingGroup ( ) . equals ( BuildingGroup . BULWARK ) ) )
completionDate = DateTime . now ( ) . plusMinutes ( 15 ) ;
else
completionDate = DateTime . now ( ) . plusHours ( blueprint . getRankTime ( 1 ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Vector3fImmutable localLoc = new Vector3fImmutable ( ZoneManager . worldToLocal ( buildingInfo . getLoc ( ) , currentZone ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
buildingRotation = buildingInfo . getRot ( ) . y ;
vendorRotation = buildingInfo . getW ( ) ;
2023-01-15 08:31:56 -05:00
2023-07-15 09:23:48 -04:00
// if W return is negative, this is a -90 rotation not a 90?
2023-01-15 08:31:56 -05:00
2023-07-15 09:23:48 -04:00
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 ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Make sure we have a valid mesh
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
if ( newMesh = = null ) {
Logger . error ( " CreateStructure: DB returned null object. " ) ;
return null ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
newMesh . setObjectTypeMask ( MBServerStatics . MASK_BUILDING ) ;
MaintenanceManager . setMaintDateTime ( newMesh , LocalDateTime . now ( ) . plusDays ( 7 ) ) ;
2022-04-30 09:41:17 -04:00
2023-08-20 20:14:28 -04:00
newMesh . setLoc ( newMesh . getLoc ( ) ) ;
InterestManager . setObjectDirty ( newMesh ) ;
2023-07-15 09:23:48 -04:00
return newMesh ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Validates that player is able to place buildings
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private boolean createShrine ( PlayerCharacter player , PlacementInfo buildingInfo , Zone currentZone ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Blueprint blueprint ;
Building newMesh ;
Shrine newShrine ;
City city ;
ShrineType shrineType ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( player = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
blueprint = Blueprint . getBlueprint ( buildingInfo . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( blueprint = = null ) {
Logger . error ( " CreateShrine: DB returned null blueprint. " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
shrineType = Shrine . getShrineTypeByBlueprintUUID ( blueprint . getBlueprintUUID ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-09-20 15:53:41 -04:00
city = City . getCity ( currentZone . playerCityUUID ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( city = = null )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( ! city . isLocationOnCityGrid ( buildingInfo . getLoc ( ) ) )
return false ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
Vector3fImmutable localLoc = new Vector3fImmutable ( ZoneManager . worldToLocal ( buildingInfo . getLoc ( ) , currentZone ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
float buildingRotation = buildingInfo . getRot ( ) . y ;
float vendorRotation = buildingInfo . getW ( ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ( ) ) ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( shrineObjects = = null ) {
PlaceAssetMsg . sendPlaceAssetError ( player . getClientConnection ( ) , 1 , " A Serious error has occurred. Please post details for to ensure transaction integrity " ) ;
return false ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
for ( AbstractGameObject ago : shrineObjects ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
switch ( ago . getObjectType ( ) ) {
case Building :
newMesh = ( Building ) ago ;
newMesh . runAfterLoad ( ) ;
newMesh . setObjectTypeMask ( MBServerStatics . MASK_BUILDING ) ;
MaintenanceManager . setMaintDateTime ( newMesh , LocalDateTime . now ( ) . plusDays ( 7 ) ) ;
2023-08-20 20:14:28 -04:00
newMesh . setLoc ( newMesh . getLoc ( ) ) ;
InterestManager . setObjectDirty ( newMesh ) ;
2023-07-15 09:23:48 -04:00
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 ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
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 ;
}
2023-09-20 15:53:41 -04:00
city = City . getCity ( currentZone . playerCityUUID ) ;
2023-07-15 09:23:48 -04:00
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 ) ) ;
2023-08-20 20:14:28 -04:00
newMesh . setLoc ( newMesh . getLoc ( ) ) ;
InterestManager . setObjectDirty ( newMesh ) ;
2023-07-15 09:23:48 -04:00
return true ;
}
private boolean createWarehouse ( PlayerCharacter player , PlacementInfo buildingInfo , Zone currentZone ) {
Blueprint blueprint ;
Building newMesh = null ;
2024-03-17 09:01:35 -04:00
Building warehouseBuilding ;
2023-07-15 09:23:48 -04:00
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 ( ) ;
2024-03-17 09:01:35 -04:00
City city = City . getCity ( currentZone . playerCityUUID ) ;
warehouseBuilding = DbManager . BuildingQueries . CREATE_BUILDING (
2023-07-15 09:23:48 -04:00
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 ) ;
2024-03-17 09:01:35 -04:00
if ( warehouseBuilding = = null ) {
2023-07-15 09:23:48 -04:00
PlaceAssetMsg . sendPlaceAssetError ( player . getClientConnection ( ) , 1 , " A Serious error has occurred. Please post details for to ensure transaction integrity " ) ;
return false ;
}
2024-03-17 10:52:33 -04:00
Warehouse warehouse = new Warehouse ( warehouseBuilding ) ;
city . warehouse = warehouse ;
DbManager . WarehouseQueries . UPDATE_WAREHOUSE ( warehouse ) ;
2023-07-15 09:23:48 -04:00
// Load the building into the simulation
2024-03-17 09:01:35 -04:00
warehouseBuilding . setObjectTypeMask ( MBServerStatics . MASK_BUILDING ) ;
MaintenanceManager . setMaintDateTime ( warehouseBuilding , LocalDateTime . now ( ) . plusDays ( 7 ) ) ;
warehouseBuilding . setLoc ( warehouseBuilding . getLoc ( ) ) ;
InterestManager . setObjectDirty ( warehouseBuilding ) ;
warehouseBuilding . runAfterLoad ( ) ;
2023-09-13 09:24:40 -04:00
2024-03-17 09:01:35 -04:00
if ( city = = null )
return true ;
2023-09-13 09:24:40 -04:00
2023-07-15 09:23:48 -04:00
return true ;
}
2022-06-05 16:56:01 -04:00
}