Browse Source

added barracks list to city object

master
FatBoy-DOTC 2 years ago
parent
commit
cfe8d20d2b
  1. 492
      src/engine/ai/MobileFSM.java
  2. 11
      src/engine/devcmd/cmds/InfoCmd.java
  3. 3
      src/engine/devcmd/cmds/RemoveObjectCmd.java
  4. 8
      src/engine/loot/LootManager.java
  5. 4
      src/engine/net/client/handlers/DestroyBuildingHandler.java
  6. 6
      src/engine/net/client/handlers/PlaceAssetMsgHandler.java
  7. 43
      src/engine/objects/Building.java
  8. 1
      src/engine/objects/City.java
  9. 2
      src/engine/objects/Mob.java

492
src/engine/ai/MobileFSM.java

@ -29,300 +29,150 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr; import static engine.math.FastMath.sqr;
public class MobileFSM { public class MobileFSM {
private static void mobAttack(Mob aiAgent) { private static void AttackTarget(Mob mob, AbstractWorldObject target) {
if(target == null || mob == null){
AbstractGameObject target = aiAgent.getCombatTarget();
if (target == null) {
return; return;
} }
switch (target.getObjectType()) { switch (target.getObjectType()) {
case PlayerCharacter: case PlayerCharacter:
PlayerCharacter player = (PlayerCharacter) target; PlayerCharacter targetPlayer = (PlayerCharacter) target;
if (!player.isActive()) { if (canCast(mob) == true) {
aiAgent.setCombatTarget(null); if (MobCast(mob) == false) {
CheckMobMovement(aiAgent); AttackPlayer(mob, targetPlayer);
return;
}
if (aiAgent.isNecroPet() && player.inSafeZone()) {
aiAgent.setCombatTarget(null);
return;
}
if (canCast(aiAgent) == true) {
if (MobCast(aiAgent) == false) {
handlePlayerAttackForMob(aiAgent, player);
} }
} else { } else {
handlePlayerAttackForMob(aiAgent, player); AttackPlayer(mob, targetPlayer);
} }
break; break;
case Building: case Building:
Building building = (Building) target; Building targetBuilding = (Building) target;
petHandleBuildingAttack(aiAgent, building); AttackBuilding(mob, targetBuilding);
break; break;
case Mob: case Mob:
Mob mob = (Mob) target; Mob targetMob = (Mob) target;
handleMobAttackForMob(aiAgent, mob); AttackMob(mob,targetMob);
break;
} }
} }
private static void petHandleBuildingAttack(Mob aiAgent, Building building) { public static void AttackPlayer(Mob mob, PlayerCharacter target){
if (mob.getMobBase().getSeeInvis() < target.getHidden() || !target.isAlive()) {
int buildingHitBox = (int) CombatManager.calcHitBox(building); mob.setCombatTarget(null);
if (building.getRank() == -1) {
aiAgent.setCombatTarget(null);
return; return;
} }
if (mob.BehaviourType.callsForHelp) {
if (!building.isVulnerable()) { MobCallForHelp(mob);
aiAgent.setCombatTarget(null);
return;
} }
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
if (BuildingManager.getBuildingFromCache(building.getObjectUUID()) == null) { mob.setAggroTargetID(0);
aiAgent.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (CombatUtilities.inRange2D(mob, target, mob.getRange())) {
if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) { //no weapons, default mob attack speed 3 seconds.
if (System.currentTimeMillis() < mob.getLastAttackTime())
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; return;
// ranged mobs cant attack while running. skip until they finally stop.
if (aiAgent.getRange() >= 30 && aiAgent.isMoving()) if (mob.isMoving())
return; return;
// add timer for last attack.
//reset attack animation ItemBase mainHand = mob.getWeaponItemBase(true);
if (aiAgent.isSiege()) ItemBase offHand = mob.getWeaponItemBase(false);
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) { if (mainHand == null && offHand == null) {
CombatUtilities.combatCycle(mob, target, true, null);
CombatUtilities.combatCycle(aiAgent, building, true, null);
int delay = 3000; int delay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege()) delay = 11000;
delay = 15000; mob.setLastAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(true) != null) {
aiAgent.setLastAttackTime(System.currentTimeMillis() + delay); int delay = 3000;
} else if (mob.isSiege())
//TODO set offhand attack time. delay = 11000;
if (aiAgent.getWeaponItemBase(true) != null) { CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
mob.setLastAttackTime(System.currentTimeMillis() + delay);
int attackDelay = 3000; } else if (mob.getWeaponItemBase(false) != null) {
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; int attackDelay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege()) attackDelay = 11000;
attackDelay = 15000; CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
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; return;
} }
//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) { public static void AttackBuilding(Mob mob, Building target){
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
if (aiAgent.getMobBase().getSeeInvis() < player.getHidden()) { mob.setCombatTarget(null);
aiAgent.setCombatTarget(null);
return; return;
} }
City playercity = ZoneManager.getCityAtLocation(mob.getLoc());
if (!player.isAlive()) { if(playercity != null) {
aiAgent.setCombatTarget(null); for (Building barracks : playercity.cityBarracks) {
return; for(AbstractCharacter guardCaptain : barracks.getHirelings().keySet()){
if(guardCaptain.getCombatTarget() == null){
guardCaptain.setCombatTarget(mob);
} }
if (aiAgent.BehaviourType.callsForHelp) {
MobCallForHelp(aiAgent);
} }
if (!MovementUtilities.inRangeDropAggro(aiAgent, player)) {
aiAgent.setAggroTargetID(0);
aiAgent.setCombatTarget(null);
MovementUtilities.moveToLocation(aiAgent, aiAgent.getTrueBindLoc(), 0);
return;
} }
if (CombatUtilities.inRange2D(aiAgent, player, aiAgent.getRange())) { }
if (mob.isSiege())
//no weapons, defualt mob attack speed 3 seconds. MovementManager.sendRWSSMsg(mob);
ItemBase mainHand = mob.getWeaponItemBase(true);
if (System.currentTimeMillis() < aiAgent.getLastAttackTime()) ItemBase offHand = mob.getWeaponItemBase(false);
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())
return;
// add timer for last attack.
// player.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
ItemBase mainHand = aiAgent.getWeaponItemBase(true);
ItemBase offHand = aiAgent.getWeaponItemBase(false);
if (mainHand == null && offHand == null) { if (mainHand == null && offHand == null) {
CombatUtilities.combatCycle(mob, target, true, null);
CombatUtilities.combatCycle(aiAgent, player, true, null);
int delay = 3000; int delay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege()) delay = 15000;
delay = 11000; mob.setLastAttackTime(System.currentTimeMillis() + delay);
aiAgent.setLastAttackTime(System.currentTimeMillis() + delay);
} else } else
//TODO set offhand attack time. if (mob.getWeaponItemBase(true) != null) {
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; int attackDelay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege()) attackDelay = 15000;
attackDelay = 11000; CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
if (aiAgent.BehaviourType.callsForHelp) { mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
MobCallForHelp(aiAgent); } else if (mob.getWeaponItemBase(false) != null) {
} int attackDelay = 3000;
CombatUtilities.combatCycle(aiAgent, player, false, aiAgent.getWeaponItemBase(false)); if (mob.isSiege())
aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); attackDelay = 15000;
} CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
return; mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
}
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.isSiege()) {
PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
ppm.setRange(50);
if (!mob.isAlive()) { DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
aiAgent.setCombatTarget(null);
return;
} }
if (CombatUtilities.inRangeToAttack(aiAgent, mob)) {
//not time to attack yet.
if (System.currentTimeMillis() < aiAgent.getLastAttackTime()) {
return;
} }
public static void AttackMob(Mob mob, Mob target){
if (!CombatUtilities.RunAIRandom()) if (mob.getRange() >= 30 && mob.isMoving())
return; return;
//no weapons, default mob attack speed 3 seconds.
if (aiAgent.getRange() >= 30 && aiAgent.isMoving()) ItemBase mainHand = mob.getWeaponItemBase(true);
return; ItemBase offHand = mob.getWeaponItemBase(false);
//no weapons, defualt mob attack speed 3 seconds.
ItemBase mainHand = aiAgent.getWeaponItemBase(true);
ItemBase offHand = aiAgent.getWeaponItemBase(false);
if (mainHand == null && offHand == null) { if (mainHand == null && offHand == null) {
CombatUtilities.combatCycle(mob, target, true, null);
CombatUtilities.combatCycle(aiAgent, mob, true, null);
int delay = 3000; int delay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege())
delay = 11000; delay = 11000;
mob.setLastAttackTime(System.currentTimeMillis() + delay);
aiAgent.setLastAttackTime(System.currentTimeMillis() + delay);
} else } else
//TODO set offhand attack time. if (mob.getWeaponItemBase(true) != null) {
if (aiAgent.getWeaponItemBase(true) != null) {
int attackDelay = 3000; int attackDelay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege())
attackDelay = 11000; attackDelay = 11000;
CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true));
CombatUtilities.combatCycle(aiAgent, mob, true, aiAgent.getWeaponItemBase(true)); mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay); } else if (mob.getWeaponItemBase(false) != null) {
} else if (aiAgent.getWeaponItemBase(false) != null) {
int attackDelay = 3000; int attackDelay = 3000;
if (mob.isSiege())
if (aiAgent.isSiege())
attackDelay = 11000; attackDelay = 11000;
CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false));
CombatUtilities.combatCycle(aiAgent, mob, false, aiAgent.getWeaponItemBase(false)); mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
aiAgent.setLastAttackTime(System.currentTimeMillis() + attackDelay);
}
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; return;
} }
private static void patrol(Mob mob) { private static void Patrol(Mob mob) {
//make sure mob is out of combat stance //make sure mob is out of combat stance
if (mob.isCombat() && mob.getCombatTarget() == null) { if (mob.isCombat() && mob.getCombatTarget() == null) {
mob.setCombat(false); mob.setCombat(false);
@ -495,53 +345,32 @@ public class MobileFSM {
if (mob == null) { if (mob == null) {
return; 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);
return;
}
if(mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardWallArcher.ordinal()){
//this is a player slotted guard minion
GuardWallArcherLogic(mob);
return;
}
if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) {
if (mob.isAlive() == false) { if (mob.isAlive() == false) {
//no need to continue if mob is dead, check for respawn and move on //no need to continue if mob is dead, check for respawn and move on
CheckForRespawn(mob); CheckForRespawn(mob);
return; 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()) { if (mob.playerAgroMap.isEmpty()) {
//no players loaded, no need to proceed //no players loaded, no need to proceed
return; return;
} }
//check for players that can be aggroed if mob is agressive and has no target CheckToSendMobHome(mob);
if (mob.BehaviourType.isAgressive && mob.getCombatTarget() == null && mob.BehaviourType != Enum.MobBehaviourType.SimpleStandingGuard) { switch(mob.BehaviourType){
//normal aggro case GuardCaptain:
CheckForAggro(mob); GuardCaptainLogic(mob);
} else if (mob.BehaviourType == Enum.MobBehaviourType.SimpleStandingGuard) { break;
//safehold guard case GuardMinion:
SafeGuardAggro(mob); GuardMinionLogic(mob);
} break;
//check if mob can move for patrol or moving to target case GuardWallArcher:
if (mob.BehaviourType.canRoam) { GuardWallArcherLogic(mob);
CheckMobMovement(mob); break;
} case Pet1:
//check if mob can attack if it isn't wimpy PetLogic(mob);
if (!mob.BehaviourType.isWimpy && !mob.isMoving() && mob.combatTarget != null) { break;
CheckForAttack(mob); default:
} DefaultLogic(mob);
} else { break;
CheckMobMovement(mob);
CheckForAttack(mob);
} }
} }
private static void CheckForAggro(Mob aiAgent) { private static void CheckForAggro(Mob aiAgent) {
@ -584,7 +413,7 @@ public class MobileFSM {
mob.updateLocation(); mob.updateLocation();
if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) { if (mob.isPet() == false && mob.isSummonedPet() == false && mob.isNecroPet() == false) {
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
patrol(mob); Patrol(mob);
} else { } else {
chaseTarget(mob); chaseTarget(mob);
} }
@ -606,54 +435,49 @@ public class MobileFSM {
} }
} }
private static void CheckForRespawn(Mob aiAgent) { 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 //handles checking for respawn of dead mobs even when no players have mob loaded
//Despawn Timer with Loot currently in inventory. //Despawn Timer with Loot currently in inventory.
if (aiAgent.getCharItemManager().getInventoryCount() > 0) { if (aiAgent.getCharItemManager().getInventoryCount() > 0) {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) {
aiAgent.despawn(); 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. //No items in inventory.
} else { } else {
//Mob's Loot has been looted. //Mob's Loot has been looted.
if (aiAgent.isHasLoot()) { if (aiAgent.isHasLoot()) {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
aiAgent.despawn(); 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. //Mob never had Loot.
} else { } else {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) {
aiAgent.despawn(); aiAgent.despawn();
//update time of death after mob despawns so respawn time happens after mob despawns. //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) { public static void CheckForAttack(Mob mob) {
//checks if mob can attack based on attack timer and range //checks if mob can attack based on attack timer and range
if (mob.isAlive()) if (mob.isAlive() == false){
return;
}
if (!mob.isCombat()) { if (!mob.isCombat()) {
mob.setCombat(true); mob.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg(); UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(mob); rwss.setPlayer(mob);
DispatchMessage.sendToAllInRange(mob, rwss); DispatchMessage.sendToAllInRange(mob, rwss);
} }
mobAttack(mob); if(System.currentTimeMillis() > mob.getLastAttackTime()) {
AttackTarget(mob, mob.getCombatTarget());
}
} }
private static void CheckToSendMobHome(Mob mob) { 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) { private static void chaseTarget(Mob mob) {
mob.updateMovementState(); mob.updateMovementState();
if (CombatUtilities.inRangeToAttack2D(mob, mob.getCombatTarget()))
return;
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) { if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (mob.getRange() > 15) { if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
@ -749,17 +560,9 @@ public class MobileFSM {
} }
} }
public static void GuardCaptainLogic(Mob mob){ public static void GuardCaptainLogic(Mob mob){
if (mob.playerAgroMap.isEmpty()) { if(mob.getCombatTarget() == null) {
//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;
}
CheckToSendMobHome(mob);
CheckForPlayerGuardAggro(mob); CheckForPlayerGuardAggro(mob);
}
CheckMobMovement(mob); CheckMobMovement(mob);
if(mob.getCombatTarget() != null) { if(mob.getCombatTarget() != null) {
CheckForAttack(mob); CheckForAttack(mob);
@ -777,12 +580,7 @@ public class MobileFSM {
} }
return; return;
} }
if(mob.isAlive() == false){ if(mob.npcOwner.isAlive() == false && mob.getCombatTarget() == null){
CheckForRespawn(mob);
return;
}
CheckToSendMobHome(mob);
if(mob.npcOwner.isAlive() == false){
CheckForPlayerGuardAggro(mob); CheckForPlayerGuardAggro(mob);
return; return;
} }
@ -792,11 +590,7 @@ public class MobileFSM {
} }
} }
public static void GuardWallArcherLogic(Mob mob){ public static void GuardWallArcherLogic(Mob mob){
if(mob.isAlive() == false){ if(mob.getCombatTarget() == null){
CheckForRespawn(mob);
return;
}
if(mob.npcOwner.isAlive() == false){
CheckForPlayerGuardAggro(mob); CheckForPlayerGuardAggro(mob);
return; return;
} }
@ -804,6 +598,34 @@ public class MobileFSM {
CheckForAttack(mob); 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) { public static void CheckForPlayerGuardAggro(Mob mob) {
//looks for and sets mobs combatTarget //looks for and sets mobs combatTarget
if (!mob.isAlive()) { if (!mob.isAlive()) {

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

@ -473,10 +473,13 @@ public class InfoCmd extends AbstractDevCmd {
output += "BuildingID : " + targetMob.getRegion().parentBuildingID; output += "BuildingID : " + targetMob.getRegion().parentBuildingID;
output += "building level : " + targetMob.getRegion().level; output += "building level : " + targetMob.getRegion().level;
output += "building room : " + targetMob.getRegion().room; output += "building room : " + targetMob.getRegion().room;
}else if(targetMob.building != null) { }
output += newline; if(targetMob.building != null) {
output += "BuildingID : " + targetMob.building; output += "Building Name: " + targetMob.building.getName() + newline;
output += "In BuildingLoc : " + targetMob.inBuildingLoc; output += "BuildingID : " + targetMob.building + newline;
output += "Bind Loc : " + targetMob.getBindLoc() + newline;
output += "Curr Loc : " + targetMob.getLoc() + newline;
output += "InBuildingLoc : " + targetMob.inBuildingLoc + newline;
}else{ }else{
output += newline; output += newline;
output += "No building found."; output += "No building found.";

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

@ -185,6 +185,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
DbManager.BuildingQueries.DELETE_FROM_DATABASE(building); DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
DbManager.removeFromCache(building); DbManager.removeFromCache(building);
zone.zoneBuildingSet.remove(building); zone.zoneBuildingSet.remove(building);
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
building.RemoveFromBarracksList();
}
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building, pc); WorldGrid.removeObject(building, pc);

8
src/engine/loot/LootManager.java

@ -71,11 +71,11 @@ public class LootManager {
} }
} }
private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob, float multiplier, boolean inHotzone, boolean fromDeath) { private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob, float multiplier, boolean inHotzone, boolean fromDeath) {
for (BootySetEntry bse : entries) { for (BootySetEntry bse : entries) {
int roll = ThreadLocalRandom.current().nextInt(101);
switch (bse.bootyType) { switch (bse.bootyType) {
case "GOLD": 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 //early exit, failed to hit minimum chance roll OR booty was generated from mob's death
break; break;
} }
@ -87,7 +87,7 @@ public class LootManager {
} }
break; break;
case "LOOT": 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 //early exit, failed to hit minimum chance roll OR booty was generated from mob's death
break; break;
} }
@ -111,7 +111,7 @@ public class LootManager {
break; break;
case "EQUIP": 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 //early exit, failed to hit minimum chance roll OR booty wasn't generated from mob's death
break; break;
} }

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

@ -99,7 +99,9 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().zoneBuildingSet.remove(building); building.getParentZone().zoneBuildingSet.remove(building);
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
building.RemoveFromBarracksList();
}
return true; return true;
} }

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

@ -879,6 +879,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().getParent().zoneBuildingSet.remove(building); building.getParentZone().getParent().zoneBuildingSet.remove(building);
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
building.RemoveFromBarracksList();
}
continue; continue;
} }
// remove gold from walls already placed before returning. // remove gold from walls already placed before returning.
@ -1338,6 +1341,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().zoneBuildingSet.remove(building); building.getParentZone().zoneBuildingSet.remove(building);
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
building.RemoveFromBarracksList();
}
continue; continue;
} }

43
src/engine/objects/Building.java

@ -707,42 +707,30 @@ public class Building extends AbstractWorldObject {
if (this.parentZone != null) { if (this.parentZone != null) {
this.parentZone.zoneBuildingSet.remove(this); this.parentZone.zoneBuildingSet.remove(this);
if(this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
this.RemoveFromBarracksList();
}
zone.zoneBuildingSet.add(this); zone.zoneBuildingSet.add(this);
} else } else
zone.zoneBuildingSet.add(this); zone.zoneBuildingSet.add(this);
else if (this.parentZone != null) else if (this.parentZone != null) {
this.parentZone.zoneBuildingSet.remove(this); this.parentZone.zoneBuildingSet.remove(this);
if(this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)){
this.RemoveFromBarracksList();
}
}
if (this.parentZone == null) { if (this.parentZone == null) {
this.parentZone = zone; this.parentZone = zone;
this.setLoc(new Vector3fImmutable(this.statLat + zone.absX, this.statAlt + zone.absY, this.statLon + zone.absZ)); this.setLoc(new Vector3fImmutable(this.statLat + zone.absX, this.statAlt + zone.absY, this.statLon + zone.absZ));
} else } else
this.parentZone = zone; 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; //Sets the relative position to a parent zone
this.statAlt = locY;
this.statLon = locZ;
this.parentZone = zone;
}
public float getStatLat() { public float getStatLat() {
return statLat; return statLat;
@ -1757,4 +1745,13 @@ public class Building extends AbstractWorldObject {
return false; return false;
return this.taxDateTime != null; return this.taxDateTime != null;
} }
public void AddToBarracksList(){
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
playerCity.cityBarracks.add(this);
}
}
public void RemoveFromBarracksList(){
}
} }

1
src/engine/objects/City.java

@ -91,6 +91,7 @@ public class City extends AbstractWorldObject {
public volatile boolean protectionEnforced = true; public volatile boolean protectionEnforced = true;
private String hash; private String hash;
public ArrayList<Building>cityBarracks;
/** /**
* ResultSet Constructor * ResultSet Constructor

2
src/engine/objects/Mob.java

@ -1343,7 +1343,7 @@ public class Mob extends AbstractIntelligenceAgent {
} }
public boolean canRespawn() { public boolean canRespawn() {
return System.currentTimeMillis() > this.deathTime; return System.currentTimeMillis() > this.deathTime + (spawnTime * 1000);
} }
@Override @Override

Loading…
Cancel
Save