diff --git a/src/engine/ai/MobileFSM.java b/src/engine/ai/MobileFSM.java index 2091c201..de96c5e9 100644 --- a/src/engine/ai/MobileFSM.java +++ b/src/engine/ai/MobileFSM.java @@ -29,300 +29,150 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ThreadLocalRandom; import static engine.math.FastMath.sqr; public class MobileFSM { - private static void mobAttack(Mob aiAgent) { - - AbstractGameObject target = aiAgent.getCombatTarget(); - if (target == null) { + private static void AttackTarget(Mob mob, AbstractWorldObject target) { + if(target == null || mob == null){ return; } switch (target.getObjectType()) { case PlayerCharacter: - PlayerCharacter player = (PlayerCharacter) target; - if (!player.isActive()) { - aiAgent.setCombatTarget(null); - CheckMobMovement(aiAgent); - return; - } - if (aiAgent.isNecroPet() && player.inSafeZone()) { - aiAgent.setCombatTarget(null); - return; - } - if (canCast(aiAgent) == true) { - if (MobCast(aiAgent) == false) { - handlePlayerAttackForMob(aiAgent, player); + PlayerCharacter targetPlayer = (PlayerCharacter) target; + if (canCast(mob) == true) { + if (MobCast(mob) == false) { + AttackPlayer(mob, targetPlayer); } } else { - handlePlayerAttackForMob(aiAgent, player); + AttackPlayer(mob, targetPlayer); } break; case Building: - Building building = (Building) target; - petHandleBuildingAttack(aiAgent, building); + Building targetBuilding = (Building) target; + AttackBuilding(mob, targetBuilding); break; case Mob: - Mob mob = (Mob) target; - handleMobAttackForMob(aiAgent, mob); - } - } - private static void petHandleBuildingAttack(Mob aiAgent, Building building) { - - int buildingHitBox = (int) CombatManager.calcHitBox(building); - - if (building.getRank() == -1) { - aiAgent.setCombatTarget(null); - return; - } - - if (!building.isVulnerable()) { - aiAgent.setCombatTarget(null); - return; - } - - if (BuildingManager.getBuildingFromCache(building.getObjectUUID()) == null) { - aiAgent.setCombatTarget(null); - return; - } - - if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) { - - for (Mob mob : building.getParentZone().zoneMobSet) { - - if (!mob.isPlayerGuard()) - continue; - - if (mob.getCombatTarget() != null) - continue; - - if (mob.getGuild() != null && building.getGuild() != null) - if (!Guild.sameGuild(mob.getGuild().getNation(), building.getGuild().getNation())) - continue; - - mob.setCombatTarget(aiAgent); - } - } - - if (CombatUtilities.inRangeToAttack(aiAgent, building)) { - //not time to attack yet. - - if (!CombatUtilities.RunAIRandom()) - return; - - if (System.currentTimeMillis() < aiAgent.getLastAttackTime()) - return; - - if (aiAgent.getRange() >= 30 && aiAgent.isMoving()) - return; - - //reset attack animation - if (aiAgent.isSiege()) - MovementManager.sendRWSSMsg(aiAgent); - - // Fire siege balls - // TODO: Fix animations not following stone - - //no weapons, defualt mob attack speed 3 seconds. - ItemBase mainHand = aiAgent.getWeaponItemBase(true); - ItemBase offHand = aiAgent.getWeaponItemBase(false); - - if (mainHand == null && offHand == null) { - - CombatUtilities.combatCycle(aiAgent, building, true, null); - int delay = 3000; - - if (aiAgent.isSiege()) - delay = 15000; - - aiAgent.setLastAttackTime(System.currentTimeMillis() + delay); - } else - //TODO set offhand attack time. - if (aiAgent.getWeaponItemBase(true) != null) { - - int attackDelay = 3000; - - if (aiAgent.isSiege()) - attackDelay = 15000; - - CombatUtilities.combatCycle(aiAgent, building, true, aiAgent.getWeaponItemBase(true)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); - - } else if (aiAgent.getWeaponItemBase(false) != null) { - - int attackDelay = 3000; - - if (aiAgent.isSiege()) - attackDelay = 15000; - - CombatUtilities.combatCycle(aiAgent, building, false, aiAgent.getWeaponItemBase(false)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); - } - - if (aiAgent.isSiege()) { - PowerProjectileMsg ppm = new PowerProjectileMsg(aiAgent, building); - ppm.setRange(50); - DispatchMessage.dispatchMsgToInterestArea(aiAgent, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); - } - return; + Mob targetMob = (Mob) target; + AttackMob(mob,targetMob); + break; } - - //Outside of attack Range, Move to players predicted loc. - - if (!aiAgent.isMoving()) - if (MovementUtilities.canMove(aiAgent)) - MovementUtilities.moveToLocation(aiAgent, building.getLoc(), aiAgent.getRange() + buildingHitBox); } - private static void handlePlayerAttackForMob(Mob aiAgent, PlayerCharacter player) { - - if (aiAgent.getMobBase().getSeeInvis() < player.getHidden()) { - aiAgent.setCombatTarget(null); - return; - } - - if (!player.isAlive()) { - aiAgent.setCombatTarget(null); + public static void AttackPlayer(Mob mob, PlayerCharacter target){ + if (mob.getMobBase().getSeeInvis() < target.getHidden() || !target.isAlive()) { + mob.setCombatTarget(null); return; } - - if (aiAgent.BehaviourType.callsForHelp) { - MobCallForHelp(aiAgent); + if (mob.BehaviourType.callsForHelp) { + MobCallForHelp(mob); } - if (!MovementUtilities.inRangeDropAggro(aiAgent, player)) { - aiAgent.setAggroTargetID(0); - aiAgent.setCombatTarget(null); - MovementUtilities.moveToLocation(aiAgent, aiAgent.getTrueBindLoc(), 0); + if (!MovementUtilities.inRangeDropAggro(mob, target)) { + mob.setAggroTargetID(0); + mob.setCombatTarget(null); return; } - if (CombatUtilities.inRange2D(aiAgent, player, aiAgent.getRange())) { - - //no weapons, defualt mob attack speed 3 seconds. - - if (System.currentTimeMillis() < aiAgent.getLastAttackTime()) + if (CombatUtilities.inRange2D(mob, target, mob.getRange())) { + //no weapons, default mob attack speed 3 seconds. + if (System.currentTimeMillis() < mob.getLastAttackTime()) return; - - //if (!CombatUtilities.RunAIRandom()) - // return; - // ranged mobs cant attack while running. skip until they finally stop. - //if (aiAgent.getRange() >= 30 && aiAgent.isMoving()) - if (aiAgent.isMoving()) + if (mob.isMoving()) return; - // add timer for last attack. - // player.setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); - ItemBase mainHand = aiAgent.getWeaponItemBase(true); - ItemBase offHand = aiAgent.getWeaponItemBase(false); - + ItemBase mainHand = mob.getWeaponItemBase(true); + ItemBase offHand = mob.getWeaponItemBase(false); if (mainHand == null && offHand == null) { - - CombatUtilities.combatCycle(aiAgent, player, true, null); + CombatUtilities.combatCycle(mob, target, true, null); int delay = 3000; - - if (aiAgent.isSiege()) + if (mob.isSiege()) delay = 11000; - - aiAgent.setLastAttackTime(System.currentTimeMillis() + delay); - - } else - //TODO set offhand attack time. - if (aiAgent.getWeaponItemBase(true) != null) { - - int delay = 3000; - - if (aiAgent.isSiege()) - delay = 11000; - - CombatUtilities.combatCycle(aiAgent, player, true, aiAgent.getWeaponItemBase(true)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + delay); - } else if (aiAgent.getWeaponItemBase(false) != null) { - - int attackDelay = 3000; - - if (aiAgent.isSiege()) - attackDelay = 11000; - if (aiAgent.BehaviourType.callsForHelp) { - MobCallForHelp(aiAgent); - } - CombatUtilities.combatCycle(aiAgent, player, false, aiAgent.getWeaponItemBase(false)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); - } + mob.setLastAttackTime(System.currentTimeMillis() + delay); + } else if (mob.getWeaponItemBase(true) != null) { + int delay = 3000; + if (mob.isSiege()) + delay = 11000; + CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); + mob.setLastAttackTime(System.currentTimeMillis() + delay); + } else if (mob.getWeaponItemBase(false) != null) { + int attackDelay = 3000; + if (mob.isSiege()) + attackDelay = 11000; + CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); + mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); + } return; } - - if (!MovementUtilities.updateMovementToCharacter(aiAgent, player)) - return; - - if (!MovementUtilities.canMove(aiAgent)) - return; - - //this stops mobs from attempting to move while they are underneath a player. - if (CombatUtilities.inRangeToAttack2D(aiAgent, player)) - return; - } - private static void handleMobAttackForMob(Mob aiAgent, Mob mob) { - - - if (!mob.isAlive()) { - aiAgent.setCombatTarget(null); + public static void AttackBuilding(Mob mob, Building target){ + if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { + mob.setCombatTarget(null); return; } - - if (CombatUtilities.inRangeToAttack(aiAgent, mob)) { - //not time to attack yet. - if (System.currentTimeMillis() < aiAgent.getLastAttackTime()) { - return; - } - - if (!CombatUtilities.RunAIRandom()) - return; - - if (aiAgent.getRange() >= 30 && aiAgent.isMoving()) - return; - //no weapons, defualt mob attack speed 3 seconds. - ItemBase mainHand = aiAgent.getWeaponItemBase(true); - ItemBase offHand = aiAgent.getWeaponItemBase(false); - - if (mainHand == null && offHand == null) { - - CombatUtilities.combatCycle(aiAgent, mob, true, null); - int delay = 3000; - - if (aiAgent.isSiege()) - delay = 11000; - - aiAgent.setLastAttackTime(System.currentTimeMillis() + delay); - } else - //TODO set offhand attack time. - if (aiAgent.getWeaponItemBase(true) != null) { - - int attackDelay = 3000; - - if (aiAgent.isSiege()) - attackDelay = 11000; - - CombatUtilities.combatCycle(aiAgent, mob, true, aiAgent.getWeaponItemBase(true)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); - - } else if (aiAgent.getWeaponItemBase(false) != null) { - - int attackDelay = 3000; - - if (aiAgent.isSiege()) - attackDelay = 11000; - - CombatUtilities.combatCycle(aiAgent, mob, false, aiAgent.getWeaponItemBase(false)); - aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); + City playercity = ZoneManager.getCityAtLocation(mob.getLoc()); + if(playercity != null) { + for (Building barracks : playercity.cityBarracks) { + for(AbstractCharacter guardCaptain : barracks.getHirelings().keySet()){ + if(guardCaptain.getCombatTarget() == null){ + guardCaptain.setCombatTarget(mob); + } } - return; + } } - - //use this so mobs dont continue to try to move if they are underneath a flying target. only use 2D range check. - if (CombatUtilities.inRangeToAttack2D(aiAgent, mob)) - return; - - if (!MovementUtilities.updateMovementToCharacter(aiAgent, mob)) - return; + if (mob.isSiege()) + MovementManager.sendRWSSMsg(mob); + ItemBase mainHand = mob.getWeaponItemBase(true); + ItemBase offHand = mob.getWeaponItemBase(false); + if (mainHand == null && offHand == null) { + CombatUtilities.combatCycle(mob, target, true, null); + int delay = 3000; + if (mob.isSiege()) + delay = 15000; + mob.setLastAttackTime(System.currentTimeMillis() + delay); + } else + if (mob.getWeaponItemBase(true) != null) { + int attackDelay = 3000; + if (mob.isSiege()) + attackDelay = 15000; + CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); + mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); + } else if (mob.getWeaponItemBase(false) != null) { + int attackDelay = 3000; + if (mob.isSiege()) + attackDelay = 15000; + CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); + mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); + } + if (mob.isSiege()) { + PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target); + ppm.setRange(50); + DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); + } + } + public static void AttackMob(Mob mob, Mob target){ + if (mob.getRange() >= 30 && mob.isMoving()) + return; + //no weapons, default mob attack speed 3 seconds. + ItemBase mainHand = mob.getWeaponItemBase(true); + ItemBase offHand = mob.getWeaponItemBase(false); + if (mainHand == null && offHand == null) { + CombatUtilities.combatCycle(mob, target, true, null); + int delay = 3000; + if (mob.isSiege()) + delay = 11000; + mob.setLastAttackTime(System.currentTimeMillis() + delay); + } else + if (mob.getWeaponItemBase(true) != null) { + int attackDelay = 3000; + if (mob.isSiege()) + attackDelay = 11000; + CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); + mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); + } else if (mob.getWeaponItemBase(false) != null) { + int attackDelay = 3000; + if (mob.isSiege()) + attackDelay = 11000; + CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); + mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); + } + return; } - private static void patrol(Mob mob) { + private static void Patrol(Mob mob) { //make sure mob is out of combat stance if (mob.isCombat() && mob.getCombatTarget() == null) { mob.setCombat(false); @@ -495,53 +345,32 @@ public class MobileFSM { if (mob == null) { return; } - if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()){ - //this is a player slotted guard captain - GuardCaptainLogic(mob); - return; - } - if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()){ - //this is a player slotted guard minion - GuardMinionLogic(mob); + if (mob.isAlive() == false) { + //no need to continue if mob is dead, check for respawn and move on + CheckForRespawn(mob); return; } - if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardWallArcher.ordinal()){ - //this is a player slotted guard minion - GuardWallArcherLogic(mob); + if (mob.playerAgroMap.isEmpty()) { + //no players loaded, no need to proceed return; } - if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { - if (mob.isAlive() == false) { - //no need to continue if mob is dead, check for respawn and move on - CheckForRespawn(mob); - return; - } - //check to see if mob has wandered too far from his bind loc - CheckToSendMobHome(mob); - //check to see if players have mob loaded - if (mob.playerAgroMap.isEmpty()) { - //no players loaded, no need to proceed - return; - } - //check for players that can be aggroed if mob is agressive and has no target - if (mob.BehaviourType.isAgressive && mob.getCombatTarget() == null && mob.BehaviourType != Enum.MobBehaviourType.SimpleStandingGuard) { - //normal aggro - CheckForAggro(mob); - } else if (mob.BehaviourType == Enum.MobBehaviourType.SimpleStandingGuard) { - //safehold guard - SafeGuardAggro(mob); - } - //check if mob can move for patrol or moving to target - if (mob.BehaviourType.canRoam) { - CheckMobMovement(mob); - } - //check if mob can attack if it isn't wimpy - if (!mob.BehaviourType.isWimpy && !mob.isMoving() && mob.combatTarget != null) { - CheckForAttack(mob); - } - } else { - CheckMobMovement(mob); - CheckForAttack(mob); + CheckToSendMobHome(mob); + switch(mob.BehaviourType){ + case GuardCaptain: + GuardCaptainLogic(mob); + break; + case GuardMinion: + GuardMinionLogic(mob); + break; + case GuardWallArcher: + GuardWallArcherLogic(mob); + break; + case Pet1: + PetLogic(mob); + break; + default: + DefaultLogic(mob); + break; } } private static void CheckForAggro(Mob aiAgent) { @@ -584,7 +413,7 @@ public class MobileFSM { mob.updateLocation(); if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { if (mob.getCombatTarget() == null) { - patrol(mob); + Patrol(mob); } else { chaseTarget(mob); } @@ -606,54 +435,49 @@ public class MobileFSM { } } private static void CheckForRespawn(Mob aiAgent) { + if (aiAgent.deathTime == 0) { + aiAgent.setDeathTime(System.currentTimeMillis()); + } //handles checking for respawn of dead mobs even when no players have mob loaded //Despawn Timer with Loot currently in inventory. if (aiAgent.getCharItemManager().getInventoryCount() > 0) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { aiAgent.despawn(); - //update time of death after mob despawns so respawn time happens after mob despawns. - if (aiAgent.deathTime != 0) { - aiAgent.setDeathTime(System.currentTimeMillis()); - } - respawn(aiAgent); } - //No items in inventory. } else { //Mob's Loot has been looted. if (aiAgent.isHasLoot()) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { aiAgent.despawn(); - //update time of death after mob despawns so respawn time happens after mob despawns. - if (aiAgent.deathTime != 0) { - aiAgent.setDeathTime(System.currentTimeMillis()); - } - respawn(aiAgent); } //Mob never had Loot. } else { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { aiAgent.despawn(); //update time of death after mob despawns so respawn time happens after mob despawns. - if (aiAgent.deathTime != 0) { - aiAgent.setDeathTime(System.currentTimeMillis()); - } - respawn(aiAgent); } } } - + if (System.currentTimeMillis() > aiAgent.deathTime + (aiAgent.spawnTime * 1000)) { + aiAgent.respawn(); + aiAgent.setCombatTarget(null); + } } public static void CheckForAttack(Mob mob) { //checks if mob can attack based on attack timer and range - if (mob.isAlive()) + if (mob.isAlive() == false){ + return; + } if (!mob.isCombat()) { mob.setCombat(true); UpdateStateMsg rwss = new UpdateStateMsg(); rwss.setPlayer(mob); DispatchMessage.sendToAllInRange(mob, rwss); } - mobAttack(mob); + if(System.currentTimeMillis() > mob.getLastAttackTime()) { + AttackTarget(mob, mob.getCombatTarget()); + } } private static void CheckToSendMobHome(Mob mob) { @@ -705,23 +529,10 @@ public class MobileFSM { } } } - private static void respawn(Mob aiAgent) { - - if (!aiAgent.canRespawn()) - return; - - long spawnTime = aiAgent.getSpawnTime(); - - if (aiAgent.isPlayerGuard() && aiAgent.npcOwner != null && !aiAgent.npcOwner.isAlive()) - return; - - if (System.currentTimeMillis() > aiAgent.deathTime + spawnTime) { - aiAgent.respawn(); - aiAgent.setCombatTarget(null); - } - } private static void chaseTarget(Mob mob) { mob.updateMovementState(); + if (CombatUtilities.inRangeToAttack2D(mob, mob.getCombatTarget())) + return; if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { if (mob.getRange() > 15) { mob.destination = mob.getCombatTarget().getLoc(); @@ -749,17 +560,9 @@ public class MobileFSM { } } public static void GuardCaptainLogic(Mob mob){ - if (mob.playerAgroMap.isEmpty()) { - //no players loaded, no need to proceed - return; - } - if (mob.isAlive() == false) { - //no need to continue if mob is dead, check for respawn and move on - CheckForRespawn(mob); - return; + if(mob.getCombatTarget() == null) { + CheckForPlayerGuardAggro(mob); } - CheckToSendMobHome(mob); - CheckForPlayerGuardAggro(mob); CheckMobMovement(mob); if(mob.getCombatTarget() != null) { CheckForAttack(mob); @@ -777,12 +580,7 @@ public class MobileFSM { } return; } - if(mob.isAlive() == false){ - CheckForRespawn(mob); - return; - } - CheckToSendMobHome(mob); - if(mob.npcOwner.isAlive() == false){ + if(mob.npcOwner.isAlive() == false && mob.getCombatTarget() == null){ CheckForPlayerGuardAggro(mob); return; } @@ -792,11 +590,7 @@ public class MobileFSM { } } public static void GuardWallArcherLogic(Mob mob){ - if(mob.isAlive() == false){ - CheckForRespawn(mob); - return; - } - if(mob.npcOwner.isAlive() == false){ + if(mob.getCombatTarget() == null){ CheckForPlayerGuardAggro(mob); return; } @@ -804,6 +598,34 @@ public class MobileFSM { CheckForAttack(mob); } } + private static void PetLogic(Mob mob){ + if(MovementUtilities.canMove(mob)){ + CheckMobMovement(mob); + } + if(mob.getCombatTarget() != null) { + CheckForAttack(mob); + } + } + private static void DefaultLogic(Mob mob){ + //check for players that can be aggroed if mob is agressive and has no target + if (mob.BehaviourType.isAgressive && mob.getCombatTarget() == null) { + if (mob.BehaviourType == Enum.MobBehaviourType.SimpleStandingGuard) { + //safehold guard + SafeGuardAggro(mob); + } else { + //normal aggro + CheckForAggro(mob); + } + } + //check if mob can move for patrol or moving to target + if (mob.BehaviourType.canRoam) { + CheckMobMovement(mob); + } + //check if mob can attack if it isn't wimpy + if (!mob.BehaviourType.isWimpy && !mob.isMoving() && mob.combatTarget != null) { + CheckForAttack(mob); + } + } public static void CheckForPlayerGuardAggro(Mob mob) { //looks for and sets mobs combatTarget if (!mob.isAlive()) { diff --git a/src/engine/devcmd/cmds/InfoCmd.java b/src/engine/devcmd/cmds/InfoCmd.java index d20aa32a..c36158a9 100644 --- a/src/engine/devcmd/cmds/InfoCmd.java +++ b/src/engine/devcmd/cmds/InfoCmd.java @@ -473,10 +473,13 @@ public class InfoCmd extends AbstractDevCmd { output += "BuildingID : " + targetMob.getRegion().parentBuildingID; output += "building level : " + targetMob.getRegion().level; output += "building room : " + targetMob.getRegion().room; - }else if(targetMob.building != null) { - output += newline; - output += "BuildingID : " + targetMob.building; - output += "In BuildingLoc : " + targetMob.inBuildingLoc; + } + if(targetMob.building != null) { + output += "Building Name: " + targetMob.building.getName() + newline; + output += "BuildingID : " + targetMob.building + newline; + output += "Bind Loc : " + targetMob.getBindLoc() + newline; + output += "Curr Loc : " + targetMob.getLoc() + newline; + output += "InBuildingLoc : " + targetMob.inBuildingLoc + newline; }else{ output += newline; output += "No building found."; diff --git a/src/engine/devcmd/cmds/RemoveObjectCmd.java b/src/engine/devcmd/cmds/RemoveObjectCmd.java index 5b176002..cd0eaf86 100644 --- a/src/engine/devcmd/cmds/RemoveObjectCmd.java +++ b/src/engine/devcmd/cmds/RemoveObjectCmd.java @@ -185,6 +185,9 @@ public class RemoveObjectCmd extends AbstractDevCmd { DbManager.BuildingQueries.DELETE_FROM_DATABASE(building); DbManager.removeFromCache(building); zone.zoneBuildingSet.remove(building); + if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + building.RemoveFromBarracksList(); + } WorldGrid.RemoveWorldObject(building); WorldGrid.removeObject(building, pc); diff --git a/src/engine/loot/LootManager.java b/src/engine/loot/LootManager.java index 7811c131..ef70966c 100644 --- a/src/engine/loot/LootManager.java +++ b/src/engine/loot/LootManager.java @@ -71,11 +71,11 @@ public class LootManager { } } private static void RunBootySet(ArrayList entries, Mob mob, float multiplier, boolean inHotzone, boolean fromDeath) { - for (BootySetEntry bse : entries) { + int roll = ThreadLocalRandom.current().nextInt(101); switch (bse.bootyType) { case "GOLD": - if (ThreadLocalRandom.current().nextInt(100) <= (bse.dropChance * multiplier) || fromDeath) { + if (roll > (bse.dropChance * multiplier) || fromDeath) { //early exit, failed to hit minimum chance roll OR booty was generated from mob's death break; } @@ -87,7 +87,7 @@ public class LootManager { } break; case "LOOT": - if (ThreadLocalRandom.current().nextInt(100) <= (bse.dropChance * multiplier) || fromDeath) { + if (roll > (bse.dropChance * multiplier) || fromDeath) { //early exit, failed to hit minimum chance roll OR booty was generated from mob's death break; } @@ -111,7 +111,7 @@ public class LootManager { break; case "EQUIP": - if (ThreadLocalRandom.current().nextInt(100) <= (bse.dropChance * multiplier) || !fromDeath) { + if (roll > (bse.dropChance * multiplier) && fromDeath) { //early exit, failed to hit minimum chance roll OR booty wasn't generated from mob's death break; } diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index 1789c453..0ece4fd4 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -99,7 +99,9 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { WorldGrid.RemoveWorldObject(building); WorldGrid.removeObject(building); building.getParentZone().zoneBuildingSet.remove(building); - + if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + building.RemoveFromBarracksList(); + } return true; } diff --git a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java index 0b4ee378..750a56bd 100644 --- a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java +++ b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java @@ -879,6 +879,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { WorldGrid.RemoveWorldObject(building); WorldGrid.removeObject(building); building.getParentZone().getParent().zoneBuildingSet.remove(building); + if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + building.RemoveFromBarracksList(); + } continue; } // remove gold from walls already placed before returning. @@ -1338,6 +1341,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { WorldGrid.RemoveWorldObject(building); WorldGrid.removeObject(building); building.getParentZone().zoneBuildingSet.remove(building); + if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + building.RemoveFromBarracksList(); + } continue; } diff --git a/src/engine/objects/Building.java b/src/engine/objects/Building.java index 80a625c4..0075f18c 100644 --- a/src/engine/objects/Building.java +++ b/src/engine/objects/Building.java @@ -707,43 +707,31 @@ public class Building extends AbstractWorldObject { if (this.parentZone != null) { this.parentZone.zoneBuildingSet.remove(this); + if(this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + this.RemoveFromBarracksList(); + } zone.zoneBuildingSet.add(this); } else zone.zoneBuildingSet.add(this); - else if (this.parentZone != null) + else if (this.parentZone != null) { this.parentZone.zoneBuildingSet.remove(this); - + if(this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + this.RemoveFromBarracksList(); + } + } if (this.parentZone == null) { this.parentZone = zone; this.setLoc(new Vector3fImmutable(this.statLat + zone.absX, this.statAlt + zone.absY, this.statLon + zone.absZ)); } else this.parentZone = zone; + if(this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){ + AddToBarracksList(); + } } //Sets the relative position to a parent zone - public final void setRelPos(Zone zone, float locX, float locY, float locZ) { - - //update ZoneManager's zone building list - - if (zone != null) - if (this.parentZone != null) { - if (zone.getObjectUUID() != this.parentZone.getObjectUUID()) { - this.parentZone.zoneBuildingSet.remove(this); - zone.zoneBuildingSet.add(this); - } - } else - zone.zoneBuildingSet.add(this); - else if (this.parentZone != null) - this.parentZone.zoneBuildingSet.remove(this); - - this.statLat = locX; - this.statAlt = locY; - this.statLon = locZ; - this.parentZone = zone; - } - public float getStatLat() { return statLat; } @@ -1757,4 +1745,13 @@ public class Building extends AbstractWorldObject { return false; return this.taxDateTime != null; } + public void AddToBarracksList(){ + City playerCity = ZoneManager.getCityAtLocation(this.loc); + if(playerCity != null){ + playerCity.cityBarracks.add(this); + } + } + public void RemoveFromBarracksList(){ + + } } diff --git a/src/engine/objects/City.java b/src/engine/objects/City.java index 6919b137..dba734b8 100644 --- a/src/engine/objects/City.java +++ b/src/engine/objects/City.java @@ -91,6 +91,7 @@ public class City extends AbstractWorldObject { public volatile boolean protectionEnforced = true; private String hash; + public ArrayListcityBarracks; /** * ResultSet Constructor diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 8be4b000..e6120bea 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1343,7 +1343,7 @@ public class Mob extends AbstractIntelligenceAgent { } public boolean canRespawn() { - return System.currentTimeMillis() > this.deathTime; + return System.currentTimeMillis() > this.deathTime + (spawnTime * 1000); } @Override