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