Compare commits
	
		
			1029 Commits 
		
	
	
		
			master
			...
			lakebane-r
		
	
	
				 192 changed files with 11475 additions and 2891 deletions
			
			
		| @ -0,0 +1,150 @@ | |||||||
|  | package engine.Dungeons; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.gameManager.BuildingManager; | ||||||
|  | import engine.gameManager.PowersManager; | ||||||
|  | import engine.gameManager.ZoneManager; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.net.ByteBufferWriter; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.powers.EffectsBase; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | import java.time.LocalDateTime; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashSet; | ||||||
|  | 
 | ||||||
|  | public class Dungeon { | ||||||
|  | 
 | ||||||
|  |     public static int NoFlyEffectID = -1733819072; | ||||||
|  |     public static int NoTeleportEffectID = -1971545187; | ||||||
|  |     public static int NoSummonEffectID = 2122002462; | ||||||
|  |     public ArrayList<PlayerCharacter> participants; | ||||||
|  |     public int maxPerGuild; | ||||||
|  |     public Vector3fImmutable entrance; | ||||||
|  |     public ArrayList<Mob> dungeon_mobs; | ||||||
|  |     public Long respawnTime = 0L; | ||||||
|  | 
 | ||||||
|  |     public Dungeon(Vector3fImmutable entrance, int maxCount){ | ||||||
|  |         this.participants = new ArrayList<>(); | ||||||
|  |         this.entrance = entrance; | ||||||
|  |         this.dungeon_mobs = new ArrayList<>(); | ||||||
|  |         this.maxPerGuild = maxCount; | ||||||
|  |     } | ||||||
|  |     public void applyDungeonEffects(PlayerCharacter player){ | ||||||
|  |         EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID); | ||||||
|  |         EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID); | ||||||
|  |         EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID); | ||||||
|  | 
 | ||||||
|  |         if(noFly != null) | ||||||
|  |             player.addEffectNoTimer(noFly.getName(),noFly,40,true); | ||||||
|  | 
 | ||||||
|  |         if(noTele != null) | ||||||
|  |             player.addEffectNoTimer(noTele.getName(),noTele,40,true); | ||||||
|  | 
 | ||||||
|  |         if(noSum != null) | ||||||
|  |             player.addEffectNoTimer(noSum.getName(),noSum,40,true); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void removeDungeonEffects(PlayerCharacter player) { | ||||||
|  |         EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID); | ||||||
|  |         EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID); | ||||||
|  |         EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID); | ||||||
|  |         for (Effect eff : player.effects.values()) { | ||||||
|  |             if (noFly != null && eff.getEffectsBase().equals(noFly)) | ||||||
|  |                 eff.endEffect(); | ||||||
|  | 
 | ||||||
|  |             if (noTele != null && eff.getEffectsBase().equals(noTele)) | ||||||
|  |                 eff.endEffect(); | ||||||
|  | 
 | ||||||
|  |             if (noSum != null && eff.getEffectsBase().equals(noSum)) | ||||||
|  |                 eff.endEffect(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void serializeForClientMsgTeleport(ByteBufferWriter writer) { | ||||||
|  |         Guild rulingGuild = Guild.getErrantGuild(); | ||||||
|  |         Guild rulingNation = Guild.getErrantGuild(); | ||||||
|  | 
 | ||||||
|  |         Zone zone = ZoneManager.getZoneByUUID(994); | ||||||
|  |         // Begin Serialzing soverign guild data
 | ||||||
|  |         writer.putInt(Enum.GameObjectType.Zone.ordinal()); | ||||||
|  |         writer.putInt(994); | ||||||
|  |         writer.putString("Whitehorn Citadel"); | ||||||
|  |         writer.putInt(rulingGuild.getObjectType().ordinal()); | ||||||
|  |         writer.putInt(rulingGuild.getObjectUUID()); | ||||||
|  | 
 | ||||||
|  |         writer.putString("Whitehorn Militants"); // guild name
 | ||||||
|  |         writer.putString("In the Citadel, We Fight!"); // motto
 | ||||||
|  |         writer.putString(rulingGuild.getLeadershipType()); | ||||||
|  | 
 | ||||||
|  |         // Serialize guild ruler's name
 | ||||||
|  |         // If tree is abandoned blank out the name
 | ||||||
|  |         // to allow them a rename.
 | ||||||
|  | 
 | ||||||
|  |         writer.putString("Kol'roth The Destroyer");//sovreign
 | ||||||
|  | 
 | ||||||
|  |         writer.putInt(rulingGuild.getCharter()); | ||||||
|  |         writer.putInt(0); // always 00000000
 | ||||||
|  | 
 | ||||||
|  |         writer.put((byte)0); | ||||||
|  | 
 | ||||||
|  |         writer.put((byte) 1); | ||||||
|  |         writer.put((byte) 1);  // *** Refactor: What are these flags?
 | ||||||
|  |         writer.put((byte) 1); | ||||||
|  |         writer.put((byte) 1); | ||||||
|  |         writer.put((byte) 1); | ||||||
|  | 
 | ||||||
|  |         GuildTag._serializeForDisplay(rulingGuild.getGuildTag(), writer); | ||||||
|  |         GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer); | ||||||
|  | 
 | ||||||
|  |         writer.putInt(0);// TODO Implement description text
 | ||||||
|  | 
 | ||||||
|  |         writer.put((byte) 1); | ||||||
|  |         writer.put((byte) 0); | ||||||
|  |         writer.put((byte) 1); | ||||||
|  | 
 | ||||||
|  |         // Begin serializing nation guild info
 | ||||||
|  | 
 | ||||||
|  |         if (rulingNation.isEmptyGuild()) { | ||||||
|  |             writer.putInt(rulingGuild.getObjectType().ordinal()); | ||||||
|  |             writer.putInt(rulingGuild.getObjectUUID()); | ||||||
|  |         } else { | ||||||
|  |             writer.putInt(rulingNation.getObjectType().ordinal()); | ||||||
|  |             writer.putInt(rulingNation.getObjectUUID()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         // Serialize nation name
 | ||||||
|  | 
 | ||||||
|  |         writer.putString("Whitehorn Militants"); //nation name
 | ||||||
|  | 
 | ||||||
|  |         writer.putInt(-1);//city rank, -1 puts it at top of list always
 | ||||||
|  | 
 | ||||||
|  |         writer.putInt(0xFFFFFFFF); | ||||||
|  | 
 | ||||||
|  |         writer.putInt(0); | ||||||
|  | 
 | ||||||
|  |         writer.putString("Kol'roth The Destroyer");//nation ruler
 | ||||||
|  | 
 | ||||||
|  |         writer.putLocalDateTime(LocalDateTime.now()); | ||||||
|  | 
 | ||||||
|  |         //location
 | ||||||
|  |         Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f); | ||||||
|  | 
 | ||||||
|  |         writer.putFloat(loc.x); | ||||||
|  |         writer.putFloat(loc.y); | ||||||
|  |         writer.putFloat(loc.z); | ||||||
|  | 
 | ||||||
|  |         writer.putInt(0); | ||||||
|  | 
 | ||||||
|  |         writer.put((byte) 1); | ||||||
|  |         writer.put((byte) 0); | ||||||
|  |         writer.putInt(0x64); | ||||||
|  |         writer.put((byte) 0); | ||||||
|  |         writer.put((byte) 0); | ||||||
|  |         writer.put((byte) 0); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,105 @@ | |||||||
|  | package engine.Dungeons; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.gameManager.DbManager; | ||||||
|  | import engine.gameManager.ZoneManager; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.powers.EffectsBase; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashSet; | ||||||
|  | 
 | ||||||
|  | public class DungeonManager { | ||||||
|  |     public static ArrayList<Dungeon> dungeons; | ||||||
|  | 
 | ||||||
|  |     private static final float dungeonAiRange = 64f; | ||||||
|  |     private static final float maxTravel = 64f; | ||||||
|  | 
 | ||||||
|  |     public static void joinDungeon(PlayerCharacter pc, Dungeon dungeon){ | ||||||
|  |         if(requestEnter(pc,dungeon)) { | ||||||
|  |             dungeon.participants.add(pc); | ||||||
|  |             dungeon.applyDungeonEffects(pc); | ||||||
|  |             translocateToDungeon(pc, dungeon); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void leaveDungeon(PlayerCharacter pc, Dungeon dungeon){ | ||||||
|  |         dungeon.participants.remove(pc); | ||||||
|  |         dungeon.removeDungeonEffects(pc); | ||||||
|  |         translocateOutOfDungeon(pc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static boolean requestEnter(PlayerCharacter pc, Dungeon dungeon){ | ||||||
|  |         int current = 0; | ||||||
|  |         Guild nation = pc.guild.getNation(); | ||||||
|  | 
 | ||||||
|  |         if(nation == null) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter participant : dungeon.participants){ | ||||||
|  |             if(participant.guild.getNation().equals(nation)){ | ||||||
|  |                 current ++; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(current >= dungeon.maxPerGuild) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void translocateToDungeon(PlayerCharacter pc, Dungeon dungeon){ | ||||||
|  |         pc.teleport(dungeon.entrance); | ||||||
|  |         pc.setSafeMode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void translocateOutOfDungeon(PlayerCharacter pc){ | ||||||
|  |         pc.teleport(pc.bindLoc); | ||||||
|  |         pc.setSafeMode(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void pulse_dungeons(){ | ||||||
|  |         for(Dungeon dungeon : dungeons){ | ||||||
|  | 
 | ||||||
|  |             //early exit, if no players present don't waste resources
 | ||||||
|  |             if(dungeon.participants.isEmpty()) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             if(dungeon.respawnTime > 0 && System.currentTimeMillis() > dungeon.respawnTime){ | ||||||
|  |                 respawnMobs(dungeon); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //remove any players that have left
 | ||||||
|  |             HashSet<AbstractWorldObject> obj = WorldGrid.getObjectsInRangePartial(dungeon.entrance,4096f,MBServerStatics.MASK_PLAYER); | ||||||
|  |             for(PlayerCharacter player : dungeon.participants) | ||||||
|  |                 if(!obj.contains(player)) | ||||||
|  |                     leaveDungeon(player,dungeon); | ||||||
|  | 
 | ||||||
|  |             //cycle dungeon mob AI
 | ||||||
|  |             for(Mob mob : dungeon.dungeon_mobs) | ||||||
|  |                 dungeonMobAI(mob); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void dungeonMobAI(Mob mob){ | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void respawnMobs(Dungeon dungeon){ | ||||||
|  |         for(Mob mob : dungeon.dungeon_mobs){ | ||||||
|  | 
 | ||||||
|  |             if(!mob.isAlive() && mob.despawned) | ||||||
|  |                 mob.respawn(); | ||||||
|  | 
 | ||||||
|  |             if(!mob.isAlive() && !mob.despawned){ | ||||||
|  |                 mob.despawn(); | ||||||
|  |                 mob.respawn(); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,116 @@ | |||||||
|  | package engine.ZergMehcanics; | ||||||
|  | 
 | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.gameManager.BuildingManager; | ||||||
|  | import engine.gameManager.ZergManager; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.HashSet; | ||||||
|  | 
 | ||||||
|  | public class MineAntiZerg { | ||||||
|  | 
 | ||||||
|  |     public static HashMap<Mine,HashMap<PlayerCharacter,Long>> leaveTimers = new HashMap<>(); | ||||||
|  |     public static HashMap<Mine,ArrayList<PlayerCharacter>> currentPlayers = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |     public static void runMines(){ | ||||||
|  |         for(Mine mine : Mine.getMines()){ | ||||||
|  | 
 | ||||||
|  |             Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); | ||||||
|  | 
 | ||||||
|  |             if(tower == null) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             if(!mine.isActive) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             logPlayersPresent(tower,mine); | ||||||
|  | 
 | ||||||
|  |             auditPlayersPresent(tower,mine); | ||||||
|  | 
 | ||||||
|  |             auditPlayers(mine); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void logPlayersPresent(Building tower, Mine mine){ | ||||||
|  |         HashSet<AbstractWorldObject> loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER); | ||||||
|  | 
 | ||||||
|  |         ArrayList<PlayerCharacter> playersPresent = new ArrayList<>(); | ||||||
|  |         for(AbstractWorldObject player : loadedPlayers){ | ||||||
|  |             playersPresent.add((PlayerCharacter)player); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         currentPlayers.put(mine,playersPresent); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void auditPlayersPresent(Building tower, Mine mine){ | ||||||
|  |         HashSet<AbstractWorldObject> loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER); | ||||||
|  | 
 | ||||||
|  |         ArrayList<PlayerCharacter> toRemove = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : currentPlayers.get(mine)){ | ||||||
|  |             if(!loadedPlayers.contains(player)){ | ||||||
|  |                 toRemove.add(player); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         currentPlayers.get(mine).removeAll(toRemove); | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : toRemove){ | ||||||
|  |             if(leaveTimers.containsKey(mine)){ | ||||||
|  |                 leaveTimers.get(mine).put(player,System.currentTimeMillis()); | ||||||
|  |             }else{ | ||||||
|  |                 HashMap<PlayerCharacter,Long> leaveTime = new HashMap<>(); | ||||||
|  |                 leaveTime.put(player,System.currentTimeMillis()); | ||||||
|  |                 leaveTimers.put(mine,leaveTime); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         toRemove.clear(); | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : leaveTimers.get(mine).keySet()){ | ||||||
|  |             long timeGone = System.currentTimeMillis() - leaveTimers.get(mine).get(player); | ||||||
|  |             if(timeGone > 180000L) {//3 minutes
 | ||||||
|  |                 toRemove.add(player); | ||||||
|  |                 player.ZergMultiplier = 1.0f; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : toRemove) { | ||||||
|  |             leaveTimers.get(mine).remove(player); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void auditPlayers(Mine mine){ | ||||||
|  | 
 | ||||||
|  |         HashMap<Guild,ArrayList<PlayerCharacter>> playersByNation = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : currentPlayers.get(mine)){ | ||||||
|  |             if(playersByNation.containsKey(player.guild.getNation())){ | ||||||
|  |                 playersByNation.get(player.guild.getNation()).add(player); | ||||||
|  |             }else{ | ||||||
|  |                 ArrayList<PlayerCharacter> players = new ArrayList<>(); | ||||||
|  |                 players.add(player); | ||||||
|  |                 playersByNation.put(player.guild.getNation(),players); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for(PlayerCharacter player : leaveTimers.get(mine).keySet()){ | ||||||
|  |             if(playersByNation.containsKey(player.guild.getNation())){ | ||||||
|  |                 playersByNation.get(player.guild.getNation()).add(player); | ||||||
|  |             }else{ | ||||||
|  |                 ArrayList<PlayerCharacter> players = new ArrayList<>(); | ||||||
|  |                 players.add(player); | ||||||
|  |                 playersByNation.put(player.guild.getNation(),players); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for(Guild nation : playersByNation.keySet()){ | ||||||
|  |             for(PlayerCharacter player : playersByNation.get(nation)){ | ||||||
|  |                 player.ZergMultiplier = ZergManager.getCurrentMultiplier(playersByNation.get(nation).size(), mine.capSize); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,54 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      Magicbane Emulator Project © 2013 - 2022
 | ||||||
|  | //                www.magicbane.com
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | package engine.devcmd.cmds; | ||||||
|  | 
 | ||||||
|  | import engine.Dungeons.DungeonManager; | ||||||
|  | import engine.Enum.GameObjectType; | ||||||
|  | import engine.devcmd.AbstractDevCmd; | ||||||
|  | import engine.gameManager.BuildingManager; | ||||||
|  | import engine.gameManager.ChatManager; | ||||||
|  | import engine.gameManager.DbManager; | ||||||
|  | import engine.gameManager.ZoneManager; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.objects.*; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @author Eighty | ||||||
|  |  */ | ||||||
|  | public class DungenonCmd extends AbstractDevCmd { | ||||||
|  | 
 | ||||||
|  |     public DungenonCmd() { | ||||||
|  |         super("dungeon"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected void _doCmd(PlayerCharacter pc, String[] words, | ||||||
|  |                           AbstractGameObject target) { | ||||||
|  | 
 | ||||||
|  |         Zone parent = ZoneManager.findSmallestZone(pc.loc); | ||||||
|  |         if(parent == null) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f); | ||||||
|  |         pc.teleport(loc); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected String _getHelpString() { | ||||||
|  |         return "indicate mob or building followed by an id and a level"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected String _getUsageString() { | ||||||
|  |         return "'/dungeon mob 2001 10'"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,63 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      Magicbane Emulator Project © 2013 - 2022
 | ||||||
|  | //                www.magicbane.com
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | package engine.devcmd.cmds; | ||||||
|  | 
 | ||||||
|  | import engine.Enum.ItemContainerType; | ||||||
|  | import engine.Enum.ItemType; | ||||||
|  | import engine.Enum.OwnerType; | ||||||
|  | import engine.devcmd.AbstractDevCmd; | ||||||
|  | import engine.gameManager.ChatManager; | ||||||
|  | import engine.gameManager.DbManager; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.powers.EffectsBase; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @author Eighty | ||||||
|  |  */ | ||||||
|  | public class GimmeCmd extends AbstractDevCmd { | ||||||
|  | 
 | ||||||
|  |     public GimmeCmd() { | ||||||
|  |         super("gimme"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected void _doCmd(PlayerCharacter pc, String[] words, | ||||||
|  |                           AbstractGameObject target) { | ||||||
|  |         int amt = 0; | ||||||
|  |         int currentGold = pc.getCharItemManager().getGoldInventory().getNumOfItems(); | ||||||
|  |         amt = 10000000 - currentGold; | ||||||
|  |         if (!pc.getCharItemManager().addGoldToInventory(amt, true)) { | ||||||
|  |             throwbackError(pc, "Failed to add gold to inventory"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         ChatManager.chatSayInfo(pc, amt + " gold added to inventory"); | ||||||
|  | 
 | ||||||
|  |         if(pc.level < 75) { | ||||||
|  |             pc.setLevel((short) 75); | ||||||
|  |             ChatManager.chatSayInfo(pc, "Level set to 75"); | ||||||
|  |         } | ||||||
|  |         pc.getCharItemManager().updateInventory(); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected String _getHelpString() { | ||||||
|  |         return "Round up current gold in inventory to 10,000,000"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected String _getUsageString() { | ||||||
|  |         return "'./gimme"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -1,77 +0,0 @@ | |||||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 |  | ||||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 |  | ||||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 |  | ||||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 |  | ||||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 |  | ||||||
| //      Magicbane Emulator Project © 2013 - 2022
 |  | ||||||
| //                www.magicbane.com
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| package engine.devcmd.cmds; |  | ||||||
| 
 |  | ||||||
| import engine.devcmd.AbstractDevCmd; |  | ||||||
| import engine.gameManager.ZoneManager; |  | ||||||
| import engine.objects.AbstractGameObject; |  | ||||||
| import engine.objects.PlayerCharacter; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * ./hotzone                      <- display the current hotzone & time remaining |  | ||||||
|  * ./hotzone random               <- change hotzone to random new zone |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| public class HotzoneCmd extends AbstractDevCmd { |  | ||||||
| 
 |  | ||||||
|     public HotzoneCmd() { |  | ||||||
|         super("hotzone"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected void _doCmd(PlayerCharacter playerCharacter, String[] words, |  | ||||||
|                           AbstractGameObject target) { |  | ||||||
| 
 |  | ||||||
|         StringBuilder data = new StringBuilder(); |  | ||||||
|         String outString; |  | ||||||
| 
 |  | ||||||
|         for (String s : words) { |  | ||||||
|             data.append(s); |  | ||||||
|             data.append(' '); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         String input = data.toString().trim(); |  | ||||||
| 
 |  | ||||||
|         if (input.length() == 0) { |  | ||||||
|             outString = "Current hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; |  | ||||||
|             outString += "Available hotZones: " + ZoneManager.availableHotZones(); |  | ||||||
|             throwbackInfo(playerCharacter, outString); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (input.equalsIgnoreCase("random")) { |  | ||||||
|             ZoneManager.generateAndSetRandomHotzone(); |  | ||||||
|             outString = "New hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; |  | ||||||
|             outString += "Available hotZones: " + ZoneManager.availableHotZones(); |  | ||||||
|             throwbackInfo(playerCharacter, outString); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (input.equalsIgnoreCase("reset")) { |  | ||||||
|             ZoneManager.resetHotZones(); |  | ||||||
|             throwbackInfo(playerCharacter, "Available hotZones: " + ZoneManager.availableHotZones()); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected String _getHelpString() { |  | ||||||
|         return "Use no arguments to see the current hotzone or \"random\" to change it randomly."; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected String _getUsageString() { |  | ||||||
|         return "'./hotzone [random]"; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,167 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.exception.MsgSendException; | ||||||
|  | import engine.math.Vector3f; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | import java.util.*; | ||||||
|  | import java.util.concurrent.ThreadLocalRandom; | ||||||
|  | 
 | ||||||
|  | public class ArenaManager { | ||||||
|  |     private static final List<Arena> activeArenas = new ArrayList<>(); | ||||||
|  |     public static final List<PlayerCharacter> playerQueue = new ArrayList<>(); | ||||||
|  |     public static Long pulseDelay = 180000L; | ||||||
|  |     public static Long lastExecution = 0L; | ||||||
|  | 
 | ||||||
|  |     public static float arena_radius = 500f; | ||||||
|  | 
 | ||||||
|  |     public static void pulseArenas() { | ||||||
|  |         if(lastExecution == 0L){ | ||||||
|  |             lastExecution = System.currentTimeMillis(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(activeArenas.isEmpty() && playerQueue.isEmpty()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         Iterator<Arena> iterator = activeArenas.iterator(); | ||||||
|  | 
 | ||||||
|  |         while (iterator.hasNext()) { | ||||||
|  |             Arena arena = iterator.next(); | ||||||
|  |             if (arena.checkToComplete()) { | ||||||
|  |                 iterator.remove(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(lastExecution + pulseDelay > System.currentTimeMillis()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         lastExecution = System.currentTimeMillis(); | ||||||
|  | 
 | ||||||
|  |         while (playerQueue.size() > 1) { | ||||||
|  |             createArena(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void joinQueue(PlayerCharacter player) { | ||||||
|  |         if (!playerQueue.contains(player)) { | ||||||
|  |             playerQueue.add(player); | ||||||
|  |         } | ||||||
|  |         for(PlayerCharacter pc : playerQueue){ | ||||||
|  |             if(pc.equals(player)) | ||||||
|  |                 continue; | ||||||
|  |             ChatManager.chatSystemInfo(pc, player.getName() + " has joined the arena que. There are now " + playerQueue.size() + " players queued."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void leaveQueue(PlayerCharacter player) { | ||||||
|  |         playerQueue.remove(player); | ||||||
|  |         for(PlayerCharacter pc : playerQueue){ | ||||||
|  |             if(pc.equals(player)) | ||||||
|  |                 continue; | ||||||
|  |             ChatManager.chatSystemInfo(pc, player.getName() + " has left the arena que. There are now " + playerQueue.size() + " players queued."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static void createArena() { | ||||||
|  |         if (playerQueue.size() > 1) { | ||||||
|  | 
 | ||||||
|  |             Collections.shuffle(playerQueue); | ||||||
|  |             Arena newArena = new Arena(); | ||||||
|  | 
 | ||||||
|  |             //set starting time
 | ||||||
|  |             newArena.startTime = System.currentTimeMillis(); | ||||||
|  | 
 | ||||||
|  |             //decide an arena location
 | ||||||
|  |             newArena.loc = selectRandomArenaLocation(); | ||||||
|  | 
 | ||||||
|  |             // Assign players to the arena
 | ||||||
|  |             newArena.player1 = playerQueue.remove(0); | ||||||
|  |             newArena.player2 = playerQueue.remove(0); | ||||||
|  | 
 | ||||||
|  |             // Teleport players to the arena location
 | ||||||
|  |             Zone sdr = ZoneManager.getZoneByUUID(656); | ||||||
|  |             MovementManager.translocate(newArena.player1, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null); | ||||||
|  |             MovementManager.translocate(newArena.player2, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null); | ||||||
|  | 
 | ||||||
|  |             // Add the new arena to the active arenas list
 | ||||||
|  |             activeArenas.add(newArena); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void endArena(Arena arena, PlayerCharacter winner, PlayerCharacter loser, String condition){ | ||||||
|  |         if (winner != null && loser != null) { | ||||||
|  |             Logger.info("[ARENA] The fight between {} and {} is concluded. Victor: {}", | ||||||
|  |                     arena.player1.getName(), arena.player2.getName(), winner.getName()); | ||||||
|  |         } else { | ||||||
|  |             Logger.info("[ARENA] The fight between {} and {} is concluded. No Winner Declared.", | ||||||
|  |                     arena.player1.getName(), arena.player2.getName()); | ||||||
|  |         } | ||||||
|  |         // Teleport players to the arena location
 | ||||||
|  |         Zone sdr = ZoneManager.getZoneByUUID(656); | ||||||
|  |         MovementManager.translocate(arena.player1, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null); | ||||||
|  |         MovementManager.translocate(arena.player2, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         activeArenas.remove(arena); | ||||||
|  | 
 | ||||||
|  |         if(winner != null){ | ||||||
|  |             ChatManager.chatPVP("[ARENA] " + winner.getName() + " has slain " + loser.getName() + " in the arena!"); | ||||||
|  |             //handle prize distribution of wrapped rune gift
 | ||||||
|  |             //ItemBase specialLoot = ItemBase.getItemBase(971070);
 | ||||||
|  |             //MobLoot winnings = new MobLoot(winner,specialLoot,false);
 | ||||||
|  |             //winner.getCharItemManager().addItemToInventory(winnings.promoteToItem(winner));
 | ||||||
|  |             //winner.getCharItemManager().updateInventory();
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Vector3fImmutable selectRandomArenaLocation() { | ||||||
|  |         boolean locSet = false; | ||||||
|  |         Vector3fImmutable loc = Vector3fImmutable.ZERO; | ||||||
|  | 
 | ||||||
|  |         while (!locSet) { | ||||||
|  |             try { | ||||||
|  |                 float x = ThreadLocalRandom.current().nextInt(114300, 123600); | ||||||
|  |                 float z = ThreadLocalRandom.current().nextInt(82675, 91700); | ||||||
|  |                 float y = 0; // Y coordinate is always 0
 | ||||||
|  | 
 | ||||||
|  |                 loc = new Vector3fImmutable(x, y, z * -1); | ||||||
|  |                 HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(loc,arena_radius, MBServerStatics.MASK_PLAYER); | ||||||
|  |                 if(inRange.isEmpty() && !isUnderWater(loc)) | ||||||
|  |                     locSet = true; | ||||||
|  |                 //}
 | ||||||
|  |             }catch(Exception e){ | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return loc; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static boolean isUnderWater(Vector3fImmutable loc) { | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             Zone zone = ZoneManager.findSmallestZone(loc); | ||||||
|  | 
 | ||||||
|  |             if (zone.getSeaLevel() != 0) { | ||||||
|  | 
 | ||||||
|  |                 float localAltitude = loc.y; | ||||||
|  |                 if (localAltitude < zone.getSeaLevel()) | ||||||
|  |                     return true; | ||||||
|  |             } else { | ||||||
|  |                 if (loc.y < 0) | ||||||
|  |                     return true; | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,45 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.objects.Bane; | ||||||
|  | import org.joda.time.DateTime; | ||||||
|  | 
 | ||||||
|  | public class BaneManager { | ||||||
|  | 
 | ||||||
|  |     public static void default_check(){ | ||||||
|  |         for(Bane bane : Bane.banes.values()){ | ||||||
|  |             if(!bane.daySet || !bane.timeSet || !bane.capSet){ | ||||||
|  |                 DateTime placementDate = bane.getPlacementDate(); | ||||||
|  |                 if(DateTime.now().isAfter(placementDate.plusHours(48))){ | ||||||
|  |                     //set bane for default time
 | ||||||
|  |                     if(!bane.daySet){ | ||||||
|  |                         bane.daySet = true; | ||||||
|  |                         DbManager.BaneQueries.SET_BANE_DAY_NEW(3,bane.getCityUUID()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if(!bane.timeSet){ | ||||||
|  |                         bane.timeSet = true; | ||||||
|  |                         DbManager.BaneQueries.SET_BANE_TIME_NEW(9,bane.getCityUUID()); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if(!bane.capSet){ | ||||||
|  |                         bane.capSet = true; | ||||||
|  |                         bane.capSize = 20; | ||||||
|  |                         DbManager.BaneQueries.SET_BANE_CAP_NEW(20,bane.getCityUUID()); | ||||||
|  |                     } | ||||||
|  |                     bane.setLiveDate(DbManager.BaneQueries.getLiveDate(bane.getCityUUID())); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void pulse_banes(){ | ||||||
|  |         //used to pulse the anti-zerg mechanic of active banes
 | ||||||
|  |         for(Bane bane : Bane.banes.values()){ | ||||||
|  |             if(bane.getSiegePhase().equals(Enum.SiegePhase.WAR)){ | ||||||
|  |                 // bane is live, handle bane anti-zerg mechanic stuff
 | ||||||
|  |                 bane.applyZergBuffs(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | 
 | ||||||
|  | import engine.objects.ForgeWorkOrder; | ||||||
|  | import engine.objects.NPC; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | 
 | ||||||
|  | public class ForgeManager { | ||||||
|  |     public HashMap<NPC, ArrayList<ForgeWorkOrder>> work_orders; | ||||||
|  | 
 | ||||||
|  |     public static void add_work_order(NPC npc, ForgeWorkOrder workOrder){ | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,396 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | import java.util.*; | ||||||
|  | import java.util.concurrent.ThreadLocalRandom; | ||||||
|  | public class SpecialLootHandler { | ||||||
|  | 
 | ||||||
|  |     public static final ArrayList<Integer> static_rune_ids_low = new ArrayList<>(Arrays.asList( | ||||||
|  |             250001, 250002, 250003, 250004, 250005, 250006, 250010, 250011, | ||||||
|  |             250012, 250013, 250014, 250015, 250019, 250020, 250021, 250022, | ||||||
|  |             250023, 250024, 250028, 250029, 250030, 250031, 250032, 250033, | ||||||
|  |             250037, 250038, 250039, 250040, 250041, 250042 | ||||||
|  |     )); | ||||||
|  |     public static final ArrayList<Integer> static_rune_ids_mid = new ArrayList<>(Arrays.asList( | ||||||
|  |             250006, 250007, 250008, | ||||||
|  |             250015, 250016, 250017, | ||||||
|  |             250024, 250025, 250026, | ||||||
|  |             250033, 250034, 250035, | ||||||
|  |             250042, 250043, 250044 | ||||||
|  |     )); | ||||||
|  |     public static final ArrayList<Integer> static_rune_ids_high = new ArrayList<>(Arrays.asList( | ||||||
|  |             250007, 250008, | ||||||
|  |             250016, 250017, | ||||||
|  |             250025, 250026, | ||||||
|  |             250034, 250035, | ||||||
|  |             250043, 250044 | ||||||
|  |     )); | ||||||
|  |     public static final List<Integer> DWARVEN_contracts = Arrays.asList( | ||||||
|  |             35250, 35251, 35252, 35253, 35254, 35255, 35256, 35257, 35258, 35259, 35260, 35261, 35262, 35263 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> INVORRI_contracts = Arrays.asList( | ||||||
|  |             35050, 35051, 35052, 35053, 35054, 35055, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> SHADE_contracts = Arrays.asList( | ||||||
|  |             35400, 35401, 35402, 35403, 35404, 35405, 35406, 35407, 35408, 35409, 35410, 35411, 35412, 35413, | ||||||
|  |             35414, 35415, 35416, 35417, 35418, 35419, 35420, 35421, 35422, 35423, 35424, 35425, 35426, 35427 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> VAMPIRE_contracts = Arrays.asList( | ||||||
|  |             35545, 35546, 35547, 35548, 35549, 35550, 35551, 35552, 35553, 35554, 35555, 35556, 35557, 35558, | ||||||
|  |             35559, 35560, 35561, 35562, 35563, 35564, 35565, 35566, 35567, 35568, 35569, 35570 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> IREKEI_contracts = Arrays.asList( | ||||||
|  |             35100, 35101, 35102, 35103, 35104, 35105, 35106, 35107, 35108, 35109, 35110, 35111, 35112, 35113, | ||||||
|  |             35114, 35115, 35116, 35117, 35118, 35119, 35120, 35121, 35122, 35123, 35124, 35125, 35126, 35127 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> AMAZON_contracts = Arrays.asList( | ||||||
|  |             35200, 35201, 35202, 35203, 35204, 35205, 35206, 35207, 35208, 35209, 35210, 35211, 35212, 35213 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> GWENDANNEN_contracts = Arrays.asList( | ||||||
|  |             35350, 35351, 35352, 35353, 35354, 35355, 35356, 35357, 35358, 35359, 35360, 35361, 35362, 35363, | ||||||
|  |             35364, 35365, 35366, 35367, 35368, 35369, 35370, 35371, 35372, 35373, 35374, 35375, 35376, 35377 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> NEPHILIM_contracts = Arrays.asList( | ||||||
|  |             35500, 35501, 35502, 35503, 35504, 35505, 35506, 35507, 35508, 35509, 35510, 35511, 35512, 35513, | ||||||
|  |             35514, 35515, 35516, 35517, 35518, 35519, 35520, 35521, 35522, 35523, 35524, 35525 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> ELVEN_contracts = Arrays.asList( | ||||||
|  |             35000, 35001, 35002, 35003, 35004, 35005, 35006, 35007, 35008, 35009, 35010, 35011, 35012, 35013, | ||||||
|  |             35014, 35015, 35016, 35017, 35018, 35019, 35020, 35021, 35022, 35023, 35024, 35025, 35026, 35027 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> CENTAUR_contracts = Arrays.asList( | ||||||
|  |             35150, 35151, 35152, 35153, 35154, 35155, 35156, 35157, 35158, 35159, 35160, 35161, 35162, 35163, | ||||||
|  |             35164, 35165, 35166, 35167, 35168, 35169, 35170, 35171, 35172, 35173, 35174, 35175, 35176, 35177 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> LIZARDMAN_contracts = Arrays.asList( | ||||||
|  |             35300, 35301, 35302, 35303, 35304, 35305, 35306, 35307, 35308, 35309, 35310, 35311, 35312, 35313 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> GLASS_ITEMS = Arrays.asList( | ||||||
|  |             7000100, 7000110, 7000120, 7000130, 7000140, 7000150, 7000160, 7000170, 7000180, 7000190, | ||||||
|  |             7000200, 7000210, 7000220, 7000230, 7000240, 7000250, 7000270, 7000280 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> STAT_RUNES = Arrays.asList( | ||||||
|  |             250001, 250002, 250003, 250004, 250005, 250006, 250007, 250008, 250010, 250011, | ||||||
|  |             250012, 250013, 250014, 250015, 250016, 250017, 250019, 250020, 250021, 250022, | ||||||
|  |             250023, 250024, 250025, 250026, 250028, 250029, 250030, 250031, 250032, 250033, | ||||||
|  |             250034, 250035, 250037, 250038, 250039, 250040, 250041, 250042, 250043, 250044 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> racial_guard = Arrays.asList( | ||||||
|  |             841,951,952,1050,1052,1180,1182,1250,1252,1350,1352,1450, | ||||||
|  |             1452,1500,1502,1525,1527,1550,1552,1575,1577,1600,1602,1650,1652,1700,980100, | ||||||
|  |             980102 | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     public static final List<Integer> gold_resources = Arrays.asList( | ||||||
|  |             1580000, 1580008, 1580009, 1580010, 1580011, 1580017 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> lumber_resources = Arrays.asList( | ||||||
|  |             1580004, 1580005, 1580006, 1580007, 1580018 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> ore_resources = Arrays.asList( | ||||||
|  |             1580000, 1580001, 1580002, 1580003, 1580019 | ||||||
|  |     ); | ||||||
|  |     public static final List<Integer> magic_resources = Arrays.asList( | ||||||
|  |             1580012, 1580013, 1580014, 1580015, 1580016, 1580020 | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     public static void RollContract(Mob mob){ | ||||||
|  |         Zone zone = getMacroZone(mob); | ||||||
|  |         if(zone == null) | ||||||
|  |             return; | ||||||
|  |         int contactId = 0; | ||||||
|  |         int roll = ThreadLocalRandom.current().nextInt(250); | ||||||
|  |         if(roll == 125){ | ||||||
|  |             contactId = getContractForZone(zone); | ||||||
|  |         } | ||||||
|  |         if(contactId == 0) | ||||||
|  |             return; | ||||||
|  |         ItemBase contractBase = ItemBase.getItemBase(contactId); | ||||||
|  |         if(contractBase == null) | ||||||
|  |             return; | ||||||
|  |         if(mob.getCharItemManager() == null) | ||||||
|  |             return; | ||||||
|  |         MobLoot contract = new MobLoot(mob,contractBase,false); | ||||||
|  |         mob.getCharItemManager().addItemToInventory(contract); | ||||||
|  |     } | ||||||
|  |     public static Zone getMacroZone(Mob mob){ | ||||||
|  |         Zone parentZone = mob.parentZone; | ||||||
|  |         if(parentZone == null) | ||||||
|  |             return null; | ||||||
|  |         while(!parentZone.isMacroZone() && !parentZone.equals(ZoneManager.getSeaFloor())){ | ||||||
|  |             parentZone = parentZone.getParent(); | ||||||
|  |         } | ||||||
|  |         return parentZone; | ||||||
|  |     } | ||||||
|  |     public static int getContractForZone(Zone zone){ | ||||||
|  |         Random random = new Random(); | ||||||
|  |         switch (zone.getObjectUUID()) | ||||||
|  |         { | ||||||
|  |             case 178: | ||||||
|  |                 // Kralgaar Holm
 | ||||||
|  |                 return DWARVEN_contracts.get(random.nextInt(DWARVEN_contracts.size())); | ||||||
|  |             case 122: | ||||||
|  |                 // Aurrochs Skrae
 | ||||||
|  |                 return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size())); | ||||||
|  |             case 197: | ||||||
|  |                 // Ymur's Crown
 | ||||||
|  |                 return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size())); | ||||||
|  |             case 234: | ||||||
|  |                 // Ecklund Wilds
 | ||||||
|  |                 return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size())); | ||||||
|  |             case 313: | ||||||
|  |                 // Greensward Pyre
 | ||||||
|  |                 return SHADE_contracts.get(random.nextInt(SHADE_contracts.size())); | ||||||
|  |             case 331: | ||||||
|  |                 // The Doomplain
 | ||||||
|  |                 return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size())); | ||||||
|  |             case 353: | ||||||
|  |                 // Thollok Marsh
 | ||||||
|  |                 return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size())); | ||||||
|  |             case 371: | ||||||
|  |                 // The Black Bog
 | ||||||
|  |                 return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size())); | ||||||
|  |             case 388: | ||||||
|  |                 // Sevaath Mere
 | ||||||
|  |                 return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size())); | ||||||
|  |             case 418: | ||||||
|  |                 // Valkos Wilds
 | ||||||
|  |                 return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size())); | ||||||
|  |             case 437: | ||||||
|  |                 // Grimscairne
 | ||||||
|  |                 return SHADE_contracts.get(random.nextInt(SHADE_contracts.size())); | ||||||
|  |             case 475: | ||||||
|  |                 // Phaedra's Prize
 | ||||||
|  |                 return AMAZON_contracts.get(random.nextInt(AMAZON_contracts.size())); | ||||||
|  |             case 491: | ||||||
|  |                 // Holloch Forest
 | ||||||
|  |                 return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size())); | ||||||
|  |             case 508: | ||||||
|  |                 // Aeran Belendor
 | ||||||
|  |                 return ELVEN_contracts.get(random.nextInt(ELVEN_contracts.size())); | ||||||
|  |             case 532: | ||||||
|  |                 // Tainted Swamp
 | ||||||
|  |                 return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size())); | ||||||
|  |             case 550: | ||||||
|  |                 // Aerath Hellendroth
 | ||||||
|  |                 return ELVEN_contracts.get(random.nextInt(ELVEN_contracts.size())); | ||||||
|  |             case 569: | ||||||
|  |                 // Aedroch Highlands
 | ||||||
|  |                 return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size())); | ||||||
|  |             case 590: | ||||||
|  |                 // Fellgrim Forest
 | ||||||
|  |                 return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size())); | ||||||
|  |             case 616: | ||||||
|  |                 // Derros Plains
 | ||||||
|  |                 return CENTAUR_contracts.get(random.nextInt(CENTAUR_contracts.size())); | ||||||
|  |             case 632: | ||||||
|  |                 // Ashfell Plain
 | ||||||
|  |                 return SHADE_contracts.get(random.nextInt(SHADE_contracts.size())); | ||||||
|  |             case 717: | ||||||
|  |                 // Kharsoom
 | ||||||
|  |                 return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size())); | ||||||
|  |             case 737: | ||||||
|  |                 // Leth'khalivar Desert
 | ||||||
|  |                 return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size())); | ||||||
|  |             case 761: | ||||||
|  |                 // The Blood Sands
 | ||||||
|  |                 return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size())); | ||||||
|  |             case 785: | ||||||
|  |                 // Vale of Nar Addad
 | ||||||
|  |                 return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size())); | ||||||
|  |             case 824: | ||||||
|  |                 // Western Battleground
 | ||||||
|  |                 return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size())); | ||||||
|  |             case 842: | ||||||
|  |                 // Pandemonium
 | ||||||
|  |                 return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size())); | ||||||
|  |             case 951: | ||||||
|  |                 //Bone Marches
 | ||||||
|  |                 return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size())); | ||||||
|  |             case 952: | ||||||
|  |                 //plain of ashes
 | ||||||
|  |                 return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size())); | ||||||
|  |         } | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |     public static void RollGlass(Mob mob){ | ||||||
|  |         int roll = ThreadLocalRandom.current().nextInt(10000); | ||||||
|  |         if(roll != 5000) | ||||||
|  |             return; | ||||||
|  |         Random random = new Random(); | ||||||
|  |         int glassId = GLASS_ITEMS.get(random.nextInt(GLASS_ITEMS.size())); | ||||||
|  |         ItemBase glassBase = ItemBase.getItemBase(glassId); | ||||||
|  |         if(glassBase == null) | ||||||
|  |             return; | ||||||
|  |         if(mob.getCharItemManager() == null) | ||||||
|  |             return; | ||||||
|  |         MobLoot glass = new MobLoot(mob,glassBase,false); | ||||||
|  |         mob.getCharItemManager().addItemToInventory(glass); | ||||||
|  |     } | ||||||
|  |     public static void RollRune(Mob mob){ | ||||||
|  |         int runeID = 0; | ||||||
|  |         int roll = ThreadLocalRandom.current().nextInt(250); | ||||||
|  |         Random random = new Random(); | ||||||
|  |         if(roll == 125){ | ||||||
|  |             runeID = STAT_RUNES.get(random.nextInt(STAT_RUNES.size())); | ||||||
|  |         } | ||||||
|  |         if(runeID == 0) | ||||||
|  |             return; | ||||||
|  |         ItemBase runeBase = ItemBase.getItemBase(runeID); | ||||||
|  |         if(runeBase == null) | ||||||
|  |             return; | ||||||
|  |         if(mob.getCharItemManager() == null) | ||||||
|  |             return; | ||||||
|  |         MobLoot rune = new MobLoot(mob,runeBase,false); | ||||||
|  |         mob.getCharItemManager().addItemToInventory(rune); | ||||||
|  |     } | ||||||
|  |     public static void RollRacialGuard(Mob mob){ | ||||||
|  |         int roll = ThreadLocalRandom.current().nextInt(5000); | ||||||
|  |         if(roll != 2500) | ||||||
|  |             return; | ||||||
|  |         Random random = new Random(); | ||||||
|  |         int guardId = racial_guard.get(random.nextInt(racial_guard.size())); | ||||||
|  |         ItemBase guardBase = ItemBase.getItemBase(guardId); | ||||||
|  |         if(guardBase == null) | ||||||
|  |             return; | ||||||
|  |         if(mob.getCharItemManager() == null) | ||||||
|  |             return; | ||||||
|  |         MobLoot guard = new MobLoot(mob,guardBase,false); | ||||||
|  |         mob.getCharItemManager().addItemToInventory(guard); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void ResourceDrop(Mob mob){ | ||||||
|  |         Zone zone = getMacroZone(mob); | ||||||
|  |         if(zone == null) | ||||||
|  |             return; | ||||||
|  |         int resourceId = 0; | ||||||
|  |         int roll = ThreadLocalRandom.current().nextInt(125); | ||||||
|  |         if(roll == 75){ | ||||||
|  |             resourceId = getResourceForZone(zone); | ||||||
|  |         } | ||||||
|  |         if(resourceId == 0) | ||||||
|  |             return; | ||||||
|  |         ItemBase resourceBase = ItemBase.getItemBase(resourceId); | ||||||
|  |         if(resourceBase == null) | ||||||
|  |             return; | ||||||
|  |         if(mob.getCharItemManager() == null) | ||||||
|  |             return; | ||||||
|  |         MobLoot resource = new MobLoot(mob,resourceBase,false); | ||||||
|  |     try { | ||||||
|  |         int stackMax = (int) (getMaxResource(resourceId) * 0.02f); | ||||||
|  |         if (stackMax > 100) | ||||||
|  |             stackMax = 100; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         int amount = ThreadLocalRandom.current().nextInt(stackMax); | ||||||
|  |         resource.setNumOfItems(amount); | ||||||
|  | 
 | ||||||
|  |         Logger.error("Set Stack Size For: " +resource.getName() + " To: " +  amount + ". Actual Amount = " + resource.getNumOfItems()); | ||||||
|  | 
 | ||||||
|  |     }catch(Exception e) { | ||||||
|  |         Logger.error("Unable To Get Max Resource Stack Size For: " + resourceId); | ||||||
|  |     } | ||||||
|  |         mob.getCharItemManager().addItemToInventory(resource); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getResourceForZone(Zone zone){ | ||||||
|  |         Random random = new Random(); | ||||||
|  |         switch (zone.getObjectUUID()) | ||||||
|  |         { | ||||||
|  |             case 178: | ||||||
|  |             case 717: | ||||||
|  |             case 632: | ||||||
|  |             case 952: | ||||||
|  |             case 475: | ||||||
|  |             case 371: | ||||||
|  |             case 313: | ||||||
|  |             case 234: | ||||||
|  |                 // Ecklund Wilds // ORE MINE
 | ||||||
|  |                 // Greensward Pyre // ORE MINE
 | ||||||
|  |                 // The Black Bog // ORE MINE
 | ||||||
|  |                 // Phaedra's Prize // ORE MINE
 | ||||||
|  |                 //plain of ashes ORE MINE
 | ||||||
|  |                 // Ashfell Plain // ORE MINE
 | ||||||
|  |                 // Kharsoom // ORE MINE
 | ||||||
|  |                 // Kralgaar Holm // ORE MINE
 | ||||||
|  |                 return ore_resources.get(random.nextInt(ore_resources.size())); | ||||||
|  |             case 122: | ||||||
|  |             case 824: | ||||||
|  |             case 737: | ||||||
|  |             case 569: | ||||||
|  |             case 590: | ||||||
|  |             case 437: | ||||||
|  |             case 388: | ||||||
|  |                 // Sevaath Mere // LUMBER MINE
 | ||||||
|  |                 // Grimscairne // LUMBER MINE
 | ||||||
|  |                 // Fellgrim Forest // LUMBER MINE
 | ||||||
|  |                 // Aedroch Highlands // LUMBER MINE
 | ||||||
|  |                 // Leth'khalivar Desert // LUMBER MINE
 | ||||||
|  |                 // Western Battleground // LUMBER MINE
 | ||||||
|  |                 // Aurrochs Skrae // LUMBER MINE
 | ||||||
|  |                 return lumber_resources.get(random.nextInt(lumber_resources.size())); | ||||||
|  |             case 197: | ||||||
|  |             case 761: | ||||||
|  |             case 616: | ||||||
|  |             case 951: | ||||||
|  |             case 532: | ||||||
|  |             case 491: | ||||||
|  |             case 353: | ||||||
|  |             case 331: | ||||||
|  |                 // The Doomplain // GOLD MINE
 | ||||||
|  |                 // Thollok Marsh // GOLD MINE
 | ||||||
|  |                 // Holloch Forest // GOLD MINE
 | ||||||
|  |                 // Tainted Swamp // GOLD MINE
 | ||||||
|  |                 //Bone Marches // GOLD MINE
 | ||||||
|  |                 // Derros Plains // GOLD MINE
 | ||||||
|  |                 // The Blood Sands // GOLD MINE
 | ||||||
|  |                 // Ymur's Crown // GOLD MINE
 | ||||||
|  |                 return gold_resources.get(random.nextInt(gold_resources.size())); | ||||||
|  |             case 418: | ||||||
|  |             case 842: | ||||||
|  |             case 785: | ||||||
|  |             case 550: | ||||||
|  |             case 508: | ||||||
|  |                 // Aeran Belendor // MAGIC MINE
 | ||||||
|  |                 // Aerath Hellendroth // MAGIC MINE
 | ||||||
|  |                 // Vale of Nar Addad // MAGIC MINE
 | ||||||
|  |                 // Pandemonium // MAGIC MINE
 | ||||||
|  |                 // Valkos Wilds // MAGIC MINE
 | ||||||
|  |                 return magic_resources.get(random.nextInt(magic_resources.size())); | ||||||
|  |         } | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getMaxResource(int key) { | ||||||
|  |         switch (key) { | ||||||
|  |             case 1580000: return 10000; | ||||||
|  |             case 1580001: return 2000; | ||||||
|  |             case 1580002: return 2000; | ||||||
|  |             case 1580003: return 1000; | ||||||
|  |             case 1580004: return 10000; | ||||||
|  |             case 1580005: return 3000; | ||||||
|  |             case 1580006: return 3000; | ||||||
|  |             case 1580007: return 1000; | ||||||
|  |             case 1580008: return 3000; | ||||||
|  |             case 1580009: return 2000; | ||||||
|  |             case 1580010: return 2000; | ||||||
|  |             case 1580011: return 1000; | ||||||
|  |             case 1580012: return 2000; | ||||||
|  |             case 1580013: return 3000; | ||||||
|  |             case 1580014: return 1000; | ||||||
|  |             case 1580015: return 1000; | ||||||
|  |             case 1580016: return 1000; | ||||||
|  |             case 1580017: return 500; | ||||||
|  |             case 1580018: return 500; | ||||||
|  |             case 1580019: return 500; | ||||||
|  |             case 1580020: return 500; | ||||||
|  |             case 1580021: return 500; | ||||||
|  |             default: return 0; // Default value if the key is not found
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,347 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.InterestManagement.InterestManager; | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.math.Vector3f; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.objects.*; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.concurrent.ThreadLocalRandom; | ||||||
|  | 
 | ||||||
|  | public class StrongholdManager { | ||||||
|  | 
 | ||||||
|  |     public static void processStrongholds() { | ||||||
|  |         ArrayList<Mine> mines = Mine.getMines(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         //process strongholds selecting 3 randomly to become active
 | ||||||
|  |         int count = 0; | ||||||
|  |         while (count < 3) { | ||||||
|  |             int random = ThreadLocalRandom.current().nextInt(1, mines.size()) - 1; | ||||||
|  |             Mine mine = mines.get(random); | ||||||
|  |             if (mine != null) { | ||||||
|  |                 if (!mine.isActive && !mine.isStronghold) { | ||||||
|  |                     StartStronghold(mine); | ||||||
|  |                     count++; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void StartStronghold(Mine mine){ | ||||||
|  | 
 | ||||||
|  |         //remove buildings
 | ||||||
|  |         Building tower = BuildingManager.getBuilding(mine.getBuildingID()); | ||||||
|  |         if(tower == null) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         mine.isStronghold = true; | ||||||
|  |         mine.strongholdMobs = new ArrayList<>(); | ||||||
|  |         mine.oldBuildings = new HashMap<>(); | ||||||
|  | 
 | ||||||
|  |         Zone mineZone = ZoneManager.findSmallestZone(tower.loc); | ||||||
|  |         for(Building building : mineZone.zoneBuildingSet){ | ||||||
|  |             mine.oldBuildings.put(building.getObjectUUID(),building.meshUUID); | ||||||
|  |             building.setMeshUUID(407650); | ||||||
|  |             building.setMeshScale(new Vector3f(0,0,0)); | ||||||
|  |             InterestManager.setObjectDirty(building); | ||||||
|  |             WorldGrid.updateObject(building); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //update tower to become stronghold mesh
 | ||||||
|  |         tower.setMeshUUID(getStrongholdMeshID(mine.getParentZone())); | ||||||
|  |         tower.setMeshScale(new Vector3f(1,1,1)); | ||||||
|  |         InterestManager.setObjectDirty(tower); | ||||||
|  |         WorldGrid.updateObject(tower); | ||||||
|  | 
 | ||||||
|  |         //create elite mobs
 | ||||||
|  |         for(int i = 0; i < mine.capSize * 2; i++){ | ||||||
|  |             Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(tower.loc,30); | ||||||
|  |             MobBase guardBase = MobBase.getMobBase(getStrongholdGuardianID(tower.meshUUID)); | ||||||
|  |             Mob guard = Mob.createStrongholdMob(guardBase.getLoadID(), loc, Guild.getErrantGuild(),true,mineZone,null,0, guardBase.getFirstName(),65); | ||||||
|  |             if(guard != null){ | ||||||
|  |                 guard.parentZone = mine.getParentZone(); | ||||||
|  |                 guard.bindLoc = loc; | ||||||
|  |                 guard.setLoc(loc); | ||||||
|  |                 guard.StrongholdGuardian = true; | ||||||
|  |                 guard.equipmentSetID = getStrongholdMobEquipSetID(guard); | ||||||
|  |                 guard.runAfterLoad(); | ||||||
|  |                 guard.setLevel((short)65); | ||||||
|  |                 guard.setResists(new Resists("Elite")); | ||||||
|  |                 guard.spawnTime = 1000000000; | ||||||
|  |                 guard.BehaviourType = Enum.MobBehaviourType.Aggro; | ||||||
|  |                 mine.strongholdMobs.add(guard); | ||||||
|  |                 LootManager.GenerateStrongholdLoot(guard,false,false); | ||||||
|  |                 guard.healthMax  = 12500; | ||||||
|  |                 guard.setHealth(guard.healthMax); | ||||||
|  |                 guard.maxDamageHandOne = 1550; | ||||||
|  |                 guard.minDamageHandOne = 750; | ||||||
|  |                 guard.atrHandOne = 1800; | ||||||
|  |                 guard.defenseRating = 2200; | ||||||
|  |                 guard.setFirstName("Elite Guardian"); | ||||||
|  |                 InterestManager.setObjectDirty(guard); | ||||||
|  |                 WorldGrid.addObject(guard,loc.x,loc.z); | ||||||
|  |                 WorldGrid.updateObject(guard); | ||||||
|  |                 guard.stronghold = mine; | ||||||
|  |                 guard.mobPowers.clear(); | ||||||
|  |                 guard.mobPowers.put(429399948,20); // find weakness
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         //create stronghold commander
 | ||||||
|  |         Vector3fImmutable loc = tower.loc; | ||||||
|  |         MobBase commanderBase = MobBase.getMobBase(getStrongholdCommanderID(tower.meshUUID)); | ||||||
|  |         Mob commander = Mob.createStrongholdMob(commanderBase.getLoadID(), loc,Guild.getErrantGuild(),true,mineZone,null,0, commanderBase.getFirstName(),75); | ||||||
|  |         if(commander != null){ | ||||||
|  |             commander.parentZone = mine.getParentZone(); | ||||||
|  |             commander.bindLoc = loc; | ||||||
|  |             commander.setLoc(loc); | ||||||
|  |             commander.StrongholdCommander = true; | ||||||
|  |             commander.equipmentSetID = getStrongholdMobEquipSetID(commander); | ||||||
|  |             commander.runAfterLoad(); | ||||||
|  |             commander.setLevel((short)75); | ||||||
|  |             commander.setResists(new Resists("Elite")); | ||||||
|  |             commander.spawnTime = 1000000000; | ||||||
|  |             commander.BehaviourType = Enum.MobBehaviourType.Aggro; | ||||||
|  |             commander.mobPowers.clear(); | ||||||
|  |             commander.mobPowers.put(429032838, 40); // gravechill
 | ||||||
|  |             commander.mobPowers.put(429757701,20); // magebolt
 | ||||||
|  |             commander.mobPowers.put(429121388,20); // blight
 | ||||||
|  |             commander.mobPowers.put(431566891,20); // lightning bolt
 | ||||||
|  |             commander.mobPowers.put(428716075,20); // fire bolt
 | ||||||
|  |             commander.mobPowers.put(429010987,20); // ice bolt
 | ||||||
|  |             mine.strongholdMobs.add(commander); | ||||||
|  |             LootManager.GenerateStrongholdLoot(commander,true, false); | ||||||
|  |             commander.healthMax = 50000; | ||||||
|  |             commander.setHealth(commander.healthMax); | ||||||
|  |             commander.maxDamageHandOne = 3500; | ||||||
|  |             commander.minDamageHandOne = 1500; | ||||||
|  |             commander.atrHandOne = 3500; | ||||||
|  |             commander.defenseRating = 3500; | ||||||
|  |             commander.setFirstName("Guardian Commander"); | ||||||
|  |             InterestManager.setObjectDirty(commander); | ||||||
|  |             WorldGrid.addObject(commander,loc.x,loc.z); | ||||||
|  |             WorldGrid.updateObject(commander); | ||||||
|  |             commander.stronghold = mine; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         mine.isActive = true; | ||||||
|  |         tower.setProtectionState(Enum.ProtectionState.PROTECTED); | ||||||
|  |         tower.getBounds().setRegions(tower); | ||||||
|  |         InterestManager.setObjectDirty(tower); | ||||||
|  |         WorldGrid.updateObject(tower); | ||||||
|  |         ChatManager.chatSystemChannel(mine.getZoneName() + "'s Stronghold Has Begun!"); | ||||||
|  |         Logger.info(mine.getZoneName() + "'s Stronghold Has Begun!"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void EndStronghold(Mine mine){ | ||||||
|  | 
 | ||||||
|  |         //restore the buildings
 | ||||||
|  |         Building tower = BuildingManager.getBuilding(mine.getBuildingID()); | ||||||
|  |         if(tower == null) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         mine.isStronghold = false; | ||||||
|  | 
 | ||||||
|  |         //get rid of the mobs
 | ||||||
|  |         for(Mob mob : mine.strongholdMobs) { | ||||||
|  |             mob.despawn(); | ||||||
|  |             mob.removeFromCache(); | ||||||
|  |             DbManager.MobQueries.DELETE_MOB(mob); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //restore the buildings
 | ||||||
|  |         Zone mineZone = ZoneManager.findSmallestZone(tower.loc); | ||||||
|  |         for(Building building : mineZone.zoneBuildingSet){ | ||||||
|  |             if(mine.oldBuildings.containsKey(building.getObjectUUID())) { | ||||||
|  |                 building.setMeshUUID(mine.oldBuildings.get(building.getObjectUUID())); | ||||||
|  |                 building.setMeshScale(new Vector3f(1, 1, 1)); | ||||||
|  |                 InterestManager.setObjectDirty(building); | ||||||
|  |                 WorldGrid.updateObject(building); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //update tower to become Mine Tower again
 | ||||||
|  |         tower.setMeshUUID(1500100); | ||||||
|  | 
 | ||||||
|  |         mine.isActive = false; | ||||||
|  |         tower.setProtectionState(Enum.ProtectionState.NPC); | ||||||
|  |         tower.getBounds().setRegions(tower); | ||||||
|  |         InterestManager.setObjectDirty(tower); | ||||||
|  |         WorldGrid.updateObject(tower); | ||||||
|  |         ChatManager.chatSystemChannel(mine.getZoneName() + "'s Stronghold Has Concluded!"); | ||||||
|  |         Logger.info(mine.getZoneName() + "'s Stronghold Has Concluded!"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getStrongholdMeshID(Zone parent){ | ||||||
|  |         while(!parent.isMacroZone()){ | ||||||
|  |             parent = parent.getParent(); | ||||||
|  |             if(parent.getName().equalsIgnoreCase("seafloor")){ | ||||||
|  |                 return 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         switch(parent.getObjectUUID()){ | ||||||
|  |             case 197: | ||||||
|  |             case 234: | ||||||
|  |             case 178: | ||||||
|  |             case 122: | ||||||
|  |                 return 814000; //Frost Giant Hall (ICE)
 | ||||||
|  |             case 968: | ||||||
|  |             case 951: | ||||||
|  |             case 313: | ||||||
|  |             case 331: | ||||||
|  |                 return 5001500; // Lich Queens Keep (UNDEAD)
 | ||||||
|  |             case 785: | ||||||
|  |             case 761: | ||||||
|  |             case 717: | ||||||
|  |             case 737: | ||||||
|  |                 return 1306600; // Temple of the Dragon (DESERT)
 | ||||||
|  |             case 353: | ||||||
|  |             case 371: | ||||||
|  |             case 388: | ||||||
|  |             case 532: | ||||||
|  |                 return 564600; // Undead Lord's Keep (SWAMP)
 | ||||||
|  |             case 550: | ||||||
|  |             case 508: | ||||||
|  |             case 475: | ||||||
|  |             case 418: | ||||||
|  |                 return 1326600; // elven hall
 | ||||||
|  |             case 437: | ||||||
|  |             case 491: | ||||||
|  |             case 590: | ||||||
|  |             case 569: | ||||||
|  |                 return 602400; | ||||||
|  |             case 824: | ||||||
|  |             case 842: | ||||||
|  |             case 632: | ||||||
|  |                 return 1600000; // chaos temple
 | ||||||
|  |         } | ||||||
|  |         return 456100; // small stockade
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getStrongholdGuardianID(int ID){ | ||||||
|  |         switch(ID){ | ||||||
|  |             case 814000: | ||||||
|  |                 return 253004; // Mountain Giant Raider Axe
 | ||||||
|  |             case 5001500: | ||||||
|  |                 return 253008; // Vampire Spear Warrior
 | ||||||
|  |             case 1306600: | ||||||
|  |                 return 253007; // Desert Orc Warrior
 | ||||||
|  |             case 564600: | ||||||
|  |                 return 253010; // Kolthoss Warrior
 | ||||||
|  |             case 1326600: | ||||||
|  |                 return 253005; //elven warrior
 | ||||||
|  |             case 602400: | ||||||
|  |                 return 253009; // templar missionary
 | ||||||
|  |             case 1600000: | ||||||
|  |                 return 253006; // scourger
 | ||||||
|  |         } | ||||||
|  |         return 13434; // human sword and board warrior
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getStrongholdEpicID(int ID){ | ||||||
|  |         switch(ID){ | ||||||
|  |             case 814000: | ||||||
|  |                 return 253023; // Mountain Giant Raider Axe
 | ||||||
|  |             case 5001500: | ||||||
|  |                 return 253022; // Vampire Spear Warrior
 | ||||||
|  |             case 1306600: | ||||||
|  |                 return 253021; // Desert Orc Warrior
 | ||||||
|  |             case 564600: | ||||||
|  |                 return 253018; // Kolthoss Warrior
 | ||||||
|  |             case 1326600: | ||||||
|  |                 return 253019; //elven warrior
 | ||||||
|  |             case 602400: | ||||||
|  |                 return 253024; // templar missionary
 | ||||||
|  |             case 1600000: | ||||||
|  |                 return 253020; // scourger
 | ||||||
|  |         } | ||||||
|  |         return 13434; // human sword and board warrior
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getStrongholdCommanderID(int ID){ | ||||||
|  |         switch(ID){ | ||||||
|  |             case 814000: | ||||||
|  |                 return 253017; | ||||||
|  |             case 5001500: | ||||||
|  |                 return 253012; | ||||||
|  |             case 1306600: | ||||||
|  |                 return 253016; // Desert Orc Xbow
 | ||||||
|  |             case 564600: | ||||||
|  |                 return 253011; // xbow kolthoss
 | ||||||
|  |             case 1326600: | ||||||
|  |                 return 253013; //elven bow warrior
 | ||||||
|  |             case 602400: | ||||||
|  |                 return 253015; // dune giant with xbow
 | ||||||
|  |             case 1600000: | ||||||
|  |                 return 253014; // barbator
 | ||||||
|  |         } | ||||||
|  |         return 13433; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static int getStrongholdMobEquipSetID(Mob mob) { | ||||||
|  |         if(mob.StrongholdGuardian){ | ||||||
|  |             return 6327; | ||||||
|  |         }else{ | ||||||
|  |             return 10790; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckToEndStronghold(Mine mine) { | ||||||
|  | 
 | ||||||
|  |         boolean stillAlive = false; | ||||||
|  |         for (Mob mob : mine.strongholdMobs) | ||||||
|  |             if (mob.isAlive()) | ||||||
|  |                 stillAlive = true; | ||||||
|  | 
 | ||||||
|  |         if (!stillAlive) { | ||||||
|  |             // Epic encounter
 | ||||||
|  | 
 | ||||||
|  |             Building tower = BuildingManager.getBuilding(mine.getBuildingID()); | ||||||
|  |             if (tower == null) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             Zone mineZone = ZoneManager.findSmallestZone(tower.loc); | ||||||
|  | 
 | ||||||
|  |             Vector3fImmutable loc = tower.loc; | ||||||
|  |             MobBase commanderBase = MobBase.getMobBase(getStrongholdEpicID(tower.meshUUID)); | ||||||
|  |             Mob commander = Mob.createStrongholdMob(commanderBase.getLoadID(), loc, Guild.getErrantGuild(), true, mineZone, null, 0, commanderBase.getFirstName(), 75); | ||||||
|  |             if (commander != null) { | ||||||
|  |                 commander.parentZone = mine.getParentZone(); | ||||||
|  |                 commander.bindLoc = loc; | ||||||
|  |                 commander.setLoc(loc); | ||||||
|  |                 commander.StrongholdEpic = true; | ||||||
|  |                 commander.equipmentSetID = getStrongholdMobEquipSetID(commander); | ||||||
|  |                 commander.runAfterLoad(); | ||||||
|  |                 commander.setLevel((short) 85); | ||||||
|  |                 commander.setResists(new Resists("Elite")); | ||||||
|  |                 commander.spawnTime = 1000000000; | ||||||
|  |                 commander.BehaviourType = Enum.MobBehaviourType.Aggro; | ||||||
|  |                 commander.mobPowers.clear(); | ||||||
|  |                 commander.mobPowers.put(429032838, 40); // gravechill
 | ||||||
|  |                 commander.mobPowers.put(429757701,40); // magebolt
 | ||||||
|  |                 commander.mobPowers.put(429121388,40); // blight
 | ||||||
|  |                 commander.mobPowers.put(431566891,40); // lightning bolt
 | ||||||
|  |                 commander.mobPowers.put(428716075,40); // fire bolt
 | ||||||
|  |                 commander.mobPowers.put(429010987,40); // ice bolt
 | ||||||
|  |                 mine.strongholdMobs.add(commander); | ||||||
|  |                 LootManager.GenerateStrongholdLoot(commander, true, true); | ||||||
|  |                 commander.healthMax = 250000; | ||||||
|  |                 commander.setHealth(commander.healthMax); | ||||||
|  |                 commander.maxDamageHandOne = 5000; | ||||||
|  |                 commander.minDamageHandOne = 2500; | ||||||
|  |                 commander.atrHandOne = 5000; | ||||||
|  |                 commander.defenseRating = 3500; | ||||||
|  |                 commander.setFirstName("Defender of " + mine.getParentZone().getParent().getName()); | ||||||
|  |                 InterestManager.setObjectDirty(commander); | ||||||
|  |                 WorldGrid.addObject(commander,loc.x,loc.z); | ||||||
|  |                 WorldGrid.updateObject(commander); | ||||||
|  |                 commander.stronghold = mine; | ||||||
|  | 
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,195 @@ | |||||||
|  | package engine.gameManager; | ||||||
|  | import engine.objects.Guild; | ||||||
|  | public class ZergManager { | ||||||
|  | 
 | ||||||
|  |     public static float getCurrentMultiplier(int count, int maxCount){ | ||||||
|  |         switch(maxCount) { | ||||||
|  |             case 3: return getMultiplier3Man(count); | ||||||
|  |             case 5: return getMultiplier5Man(count); | ||||||
|  |             case 10: return getMultiplier10Man(count); | ||||||
|  |             case 20: return getMultiplier20Man(count); | ||||||
|  |             case 30: return getMultiplier30Man(count); | ||||||
|  |             case 40: return getMultiplier40Man(count); | ||||||
|  |             default: return 1.0f; //unlimited
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier3Man(int count) { | ||||||
|  |         if(count < 4) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 6) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch(count){ | ||||||
|  |             case 4: return 0.50f; | ||||||
|  |             case 5: return 0.0f; | ||||||
|  |             case 6: return 0.0f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier5Man(int count) { | ||||||
|  |         if(count < 6) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 10) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch(count){ | ||||||
|  |             case 6: return 0.75f; | ||||||
|  |             case 7: return 0.57f; | ||||||
|  |             case 8: return 0.44f; | ||||||
|  |             case 9: return 0.33f; | ||||||
|  |             case 10: return 0.25f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier10Man(int count) { | ||||||
|  |         if(count < 11) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 20) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch(count){ | ||||||
|  |             case 11: return 0.86f; | ||||||
|  |             case 12: return 0.75f; | ||||||
|  |             case 13: return 0.65f; | ||||||
|  |             case 14: return 0.57f; | ||||||
|  |             case 15: return 0.50f; | ||||||
|  |             case 16: return 0.44f; | ||||||
|  |             case 17: return 0.38f; | ||||||
|  |             case 18: return 0.33f; | ||||||
|  |             case 19: return 0.29f; | ||||||
|  |             case 20: return 0.25f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier20Man(int count) { | ||||||
|  |         if(count < 21) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 40) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch (count) | ||||||
|  |         { | ||||||
|  |             case 21: return 0.93f; | ||||||
|  |             case 22: return 0.86f; | ||||||
|  |             case 23: return 0.80f; | ||||||
|  |             case 24: return 0.75f; | ||||||
|  |             case 25: return 0.70f; | ||||||
|  |             case 26: return 0.65f; | ||||||
|  |             case 27: return 0.61f; | ||||||
|  |             case 28: return 0.57f; | ||||||
|  |             case 29: return 0.53f; | ||||||
|  |             case 30: return 0.50f; | ||||||
|  |             case 31: return 0.47f; | ||||||
|  |             case 32: return 0.44f; | ||||||
|  |             case 33: return 0.41f; | ||||||
|  |             case 34: return 0.38f; | ||||||
|  |             case 35: return 0.36f; | ||||||
|  |             case 36: return 0.33f; | ||||||
|  |             case 37: return 0.31f; | ||||||
|  |             case 38: return 0.29f; | ||||||
|  |             case 39: return 0.27f; | ||||||
|  |             case 40: return 0.25f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier30Man(int count) { | ||||||
|  |         if(count < 31) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 60) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch (count) | ||||||
|  |         { | ||||||
|  |             case 31: return 0.95f; | ||||||
|  |             case 32: return 0.91f; | ||||||
|  |             case 33: return 0.86f; | ||||||
|  |             case 34: return 0.82f; | ||||||
|  |             case 35: return 0.79f; | ||||||
|  |             case 36: return 0.75f; | ||||||
|  |             case 37: return 0.72f; | ||||||
|  |             case 38: return 0.68f; | ||||||
|  |             case 39: return 0.65f; | ||||||
|  |             case 40: return 0.63f; | ||||||
|  |             case 41: return 0.60f; | ||||||
|  |             case 42: return 0.57f; | ||||||
|  |             case 43: return 0.55f; | ||||||
|  |             case 44: return 0.52f; | ||||||
|  |             case 45: return 0.50f; | ||||||
|  |             case 46: return 0.48f; | ||||||
|  |             case 47: return 0.46f; | ||||||
|  |             case 48: return 0.44f; | ||||||
|  |             case 49: return 0.42f; | ||||||
|  |             case 50: return 0.40f; | ||||||
|  |             case 51: return 0.38f; | ||||||
|  |             case 52: return 0.37f; | ||||||
|  |             case 53: return 0.35f; | ||||||
|  |             case 54: return 0.33f; | ||||||
|  |             case 55: return 0.32f; | ||||||
|  |             case 56: return 0.30f; | ||||||
|  |             case 57: return 0.29f; | ||||||
|  |             case 58: return 0.28f; | ||||||
|  |             case 59: return 0.26f; | ||||||
|  |             case 60: return 0.25f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     public static float getMultiplier40Man(int count) { | ||||||
|  |         if(count < 41) | ||||||
|  |             return 1.0f; | ||||||
|  | 
 | ||||||
|  |         if(count > 80) | ||||||
|  |             return 0.0f; | ||||||
|  | 
 | ||||||
|  |         switch (count) | ||||||
|  |         { | ||||||
|  |             case 41: return 0.96f; | ||||||
|  |             case 42: return 0.93f; | ||||||
|  |             case 43: return 0.90f; | ||||||
|  |             case 44: return 0.86f; | ||||||
|  |             case 45: return 0.83f; | ||||||
|  |             case 46: return 0.80f; | ||||||
|  |             case 47: return 0.78f; | ||||||
|  |             case 48: return 0.75f; | ||||||
|  |             case 49: return 0.72f; | ||||||
|  |             case 50: return 0.70f; | ||||||
|  |             case 51: return 0.68f; | ||||||
|  |             case 52: return 0.65f; | ||||||
|  |             case 53: return 0.63f; | ||||||
|  |             case 54: return 0.61f; | ||||||
|  |             case 55: return 0.59f; | ||||||
|  |             case 56: return 0.57f; | ||||||
|  |             case 57: return 0.55f; | ||||||
|  |             case 58: return 0.53f; | ||||||
|  |             case 59: return 0.52f; | ||||||
|  |             case 60: return 0.50f; | ||||||
|  |             case 61: return 0.48f; | ||||||
|  |             case 62: return 0.47f; | ||||||
|  |             case 63: return 0.45f; | ||||||
|  |             case 64: return 0.44f; | ||||||
|  |             case 65: return 0.42f; | ||||||
|  |             case 66: return 0.41f; | ||||||
|  |             case 67: return 0.40f; | ||||||
|  |             case 68: return 0.38f; | ||||||
|  |             case 69: return 0.37f; | ||||||
|  |             case 70: return 0.36f; | ||||||
|  |             case 71: return 0.35f; | ||||||
|  |             case 72: return 0.33f; | ||||||
|  |             case 73: return 0.32f; | ||||||
|  |             case 74: return 0.31f; | ||||||
|  |             case 75: return 0.30f; | ||||||
|  |             case 76: return 0.29f; | ||||||
|  |             case 77: return 0.28f; | ||||||
|  |             case 78: return 0.27f; | ||||||
|  |             case 79: return 0.26f; | ||||||
|  |             case 80: return 0.25f; | ||||||
|  |             default: return 1.0f; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,75 @@ | |||||||
|  | package engine.job; | ||||||
|  | 
 | ||||||
|  | import engine.server.world.WorldServer; | ||||||
|  | import org.pmw.tinylog.Logger; | ||||||
|  | 
 | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | import java.util.concurrent.locks.ReentrantLock; | ||||||
|  | 
 | ||||||
|  | public class JobThread implements Runnable { | ||||||
|  |     private final AbstractJob currentJob; | ||||||
|  |     private final ReentrantLock lock = new ReentrantLock(); | ||||||
|  | 
 | ||||||
|  |     private static Long nextThreadPrint; | ||||||
|  | 
 | ||||||
|  |     public JobThread(AbstractJob job){ | ||||||
|  |         this.currentJob = job; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void run() { | ||||||
|  |         try { | ||||||
|  |             if (this.currentJob != null) { | ||||||
|  |                 if (lock.tryLock(5, TimeUnit.SECONDS)) { // Timeout to prevent deadlock
 | ||||||
|  |                     try { | ||||||
|  |                         this.currentJob.doJob(); | ||||||
|  |                     } finally { | ||||||
|  |                         lock.unlock(); | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     Logger.warn("JobThread could not acquire lock in time, skipping job."); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             Logger.error(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void startJobThread(AbstractJob job){ | ||||||
|  |         JobThread jobThread = new JobThread(job); | ||||||
|  |         Thread thread = new Thread(jobThread); | ||||||
|  |         thread.setName("JOB THREAD: " + job.getWorkerID()); | ||||||
|  |         thread.start(); | ||||||
|  | 
 | ||||||
|  |        if(JobThread.nextThreadPrint == null){ | ||||||
|  |            JobThread.nextThreadPrint = System.currentTimeMillis(); | ||||||
|  |        }else{ | ||||||
|  |            if(JobThread.nextThreadPrint < System.currentTimeMillis()){ | ||||||
|  |                JobThread.tryPrintThreads(); | ||||||
|  |                JobThread.nextThreadPrint = System.currentTimeMillis() + 10000L; | ||||||
|  |            } | ||||||
|  |        } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void tryPrintThreads(){ | ||||||
|  |         ThreadGroup rootGroup = Thread.currentThread().getThreadGroup(); | ||||||
|  |         while (rootGroup.getParent() != null) { | ||||||
|  |             rootGroup = rootGroup.getParent(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Estimate the number of threads
 | ||||||
|  |         int activeThreads = rootGroup.activeCount(); | ||||||
|  | 
 | ||||||
|  |         // Create an array to hold the threads
 | ||||||
|  |         Thread[] threads = new Thread[activeThreads]; | ||||||
|  | 
 | ||||||
|  |         // Get the active threads
 | ||||||
|  |         rootGroup.enumerate(threads, true); | ||||||
|  | 
 | ||||||
|  |         int availableThreads = Runtime.getRuntime().availableProcessors(); | ||||||
|  | 
 | ||||||
|  |         // Print the count
 | ||||||
|  |         if(threads.length > 30) | ||||||
|  |             Logger.info("Total threads in application: " + threads.length + " / " + availableThreads); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,282 @@ | |||||||
|  | package engine.mobileAI.MobHandlers; | ||||||
|  | 
 | ||||||
|  | import engine.InterestManagement.WorldGrid; | ||||||
|  | import engine.gameManager.PowersManager; | ||||||
|  | import engine.mobileAI.Threads.MobAIThread; | ||||||
|  | import engine.mobileAI.utilities.CombatUtilities; | ||||||
|  | import engine.mobileAI.utilities.MovementUtilities; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.powers.PowersBase; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | 
 | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.concurrent.ThreadLocalRandom; | ||||||
|  | 
 | ||||||
|  | public class MobHandler { | ||||||
|  |     public static void run(Mob mob){ | ||||||
|  | 
 | ||||||
|  |         if (!mob.isAlive()) { | ||||||
|  |             CheckForRespawn(mob); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(mob.playerAgroMap.isEmpty()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         CheckToSendMobHome(mob); | ||||||
|  | 
 | ||||||
|  |         if(mob.combatTarget == null || !mob.combatTarget.isAlive()){ | ||||||
|  |             CheckForAggro(mob); | ||||||
|  |         } | ||||||
|  |         if(mob.combatTarget != null) | ||||||
|  |             CheckToDropAggro(mob); | ||||||
|  | 
 | ||||||
|  |         if(MovementUtilities.canMove(mob)) | ||||||
|  |             CheckMobMovement(mob); | ||||||
|  | 
 | ||||||
|  |         if(mob.combatTarget != null && CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) | ||||||
|  |             CheckToAttack(mob); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckToDropAggro(Mob mob){ | ||||||
|  |         if(mob.loc.distanceSquared(mob.combatTarget.loc) > (128f * 128f)) | ||||||
|  |             mob.setCombatTarget(null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckForRespawn(Mob mob){ | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if (mob.deathTime == 0) { | ||||||
|  |                 mob.setDeathTime(System.currentTimeMillis()); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //handles checking for respawn of dead mobs even when no players have mob loaded
 | ||||||
|  |             //Despawn Timer with Loot currently in inventory.
 | ||||||
|  | 
 | ||||||
|  |             if (!mob.despawned) { | ||||||
|  | 
 | ||||||
|  |                 if (mob.getCharItemManager().getInventoryCount() > 0) { | ||||||
|  |                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { | ||||||
|  |                         mob.despawn(); | ||||||
|  |                         mob.deathTime = System.currentTimeMillis(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     //No items in inventory.
 | ||||||
|  |                 } else if (mob.isHasLoot()) { | ||||||
|  |                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { | ||||||
|  |                         mob.despawn(); | ||||||
|  |                         mob.deathTime = System.currentTimeMillis(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                     //Mob never had Loot.
 | ||||||
|  |                 } else { | ||||||
|  |                     if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER) { | ||||||
|  |                         mob.despawn(); | ||||||
|  |                         mob.deathTime = System.currentTimeMillis(); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(Mob.discDroppers.contains(mob)) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if (mob.despawned && System.currentTimeMillis() > (mob.deathTime + (mob.spawnTime * 1000L))) { | ||||||
|  |                 if (!Zone.respawnQue.contains(mob)) { | ||||||
|  |                     Zone.respawnQue.add(mob); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             //(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckForAggro(Mob mob){ | ||||||
|  |         switch(mob.BehaviourType){ | ||||||
|  |             case SimpleStandingGuard: | ||||||
|  |             case Simple: | ||||||
|  |             case None: | ||||||
|  |                 return; | ||||||
|  |         } | ||||||
|  |         PlayerCharacter tar = null; | ||||||
|  |         for(int id : mob.playerAgroMap.keySet()){ | ||||||
|  |             PlayerCharacter target = PlayerCharacter.getFromCache(id); | ||||||
|  | 
 | ||||||
|  |             if(target.loc.distanceSquared(mob.loc) > mob.getAggroRange() * mob.getAggroRange()) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             if(tar == null || mob.loc.distanceSquared(tar.loc) < mob.loc.distanceSquared(target.loc)) | ||||||
|  |                 if(MobCanAggro(mob,target)) | ||||||
|  |                     tar = target; | ||||||
|  |         } | ||||||
|  |         if(tar != null) | ||||||
|  |             mob.setCombatTarget(tar); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Boolean MobCanAggro(Mob mob, PlayerCharacter loadedPlayer){ | ||||||
|  |         if (loadedPlayer == null) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | ||||||
|  |         if (!loadedPlayer.isAlive()) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         //Can't see target, skip aggro.
 | ||||||
|  |         if (!mob.canSee(loadedPlayer)) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         // No aggro for this race type
 | ||||||
|  |         if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         //mob has enemies and this player race is not it
 | ||||||
|  |         if (mob.enemy != null && mob.enemy.size() > 0 && !mob.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckMobMovement(Mob mob){ | ||||||
|  |         if(!mob.isAlive()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         mob.updateLocation(); | ||||||
|  | 
 | ||||||
|  |         if(mob.combatTarget == null){ | ||||||
|  |             //patrol
 | ||||||
|  |             Patrol(mob); | ||||||
|  |         }else{ | ||||||
|  |             //combat movement
 | ||||||
|  |             if(CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) { | ||||||
|  |                 return; | ||||||
|  |             }else { | ||||||
|  |                 MovementUtilities.moveToLocation(mob, mob.combatTarget.loc, mob.getRange()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckToAttack(Mob mob){ | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if(mob.getLastAttackTime() > System.currentTimeMillis()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             PlayerCharacter target = (PlayerCharacter) mob.combatTarget; | ||||||
|  | 
 | ||||||
|  |             if (!mob.canSee(target)) { | ||||||
|  |                 mob.setCombatTarget(null); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //if (mob.BehaviourType.callsForHelp)
 | ||||||
|  |             MobCallForHelp(mob); | ||||||
|  | 
 | ||||||
|  |             if (mob.isMoving() && mob.getRange() > 20) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if(target.combatStats == null) | ||||||
|  |                 target.combatStats = new PlayerCombatStats(target); | ||||||
|  | 
 | ||||||
|  |             ItemBase mainHand = mob.getWeaponItemBase(true); | ||||||
|  |             ItemBase offHand = mob.getWeaponItemBase(false); | ||||||
|  | 
 | ||||||
|  |             if (mainHand == null && offHand == null) { | ||||||
|  |                 CombatUtilities.combatCycle(mob, target, true, null); | ||||||
|  |                 int delay = 3000; | ||||||
|  |                 mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||||
|  |             } else if (mob.getWeaponItemBase(true) != null) { | ||||||
|  |                 int delay = 3000; | ||||||
|  |                 CombatUtilities.combatCycle(mob, target, true, mob.getWeaponItemBase(true)); | ||||||
|  |                 mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||||
|  |             } else if (mob.getWeaponItemBase(false) != null) { | ||||||
|  |                 int attackDelay = 3000; | ||||||
|  |                 CombatUtilities.combatCycle(mob, target, false, mob.getWeaponItemBase(false)); | ||||||
|  |                 mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (target.getPet() != null) | ||||||
|  |                 if (target.getPet().getCombatTarget() == null && target.getPet().assist) | ||||||
|  |                     target.getPet().setCombatTarget(mob); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void MobCallForHelp(Mob mob) { | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             HashSet<AbstractWorldObject> helpers = WorldGrid.getObjectsInRangePartial(mob.loc,mob.getAggroRange() * 2, MBServerStatics.MASK_MOB); | ||||||
|  |             for (AbstractWorldObject awo : helpers) { | ||||||
|  |                 if(awo.equals(mob)) | ||||||
|  |                     continue; | ||||||
|  |                 Mob helper = (Mob) awo; | ||||||
|  | 
 | ||||||
|  |                 if(helper.equals(mob)) | ||||||
|  |                     continue; | ||||||
|  | 
 | ||||||
|  |                 if(helper.combatTarget != null) | ||||||
|  |                     continue; | ||||||
|  | 
 | ||||||
|  |                 helper.setCombatTarget(mob.getCombatTarget()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static void Patrol(Mob mob) { | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if(mob.isMoving()) | ||||||
|  |                 return; | ||||||
|  |             //make sure mob is out of combat stance
 | ||||||
|  | 
 | ||||||
|  |             int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; | ||||||
|  | 
 | ||||||
|  |             //early exit while waiting to patrol again
 | ||||||
|  | 
 | ||||||
|  |             if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) | ||||||
|  |                 mob.lastPatrolPointIndex = 0; | ||||||
|  | 
 | ||||||
|  |             mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); | ||||||
|  |             mob.lastPatrolPointIndex += 1; | ||||||
|  | 
 | ||||||
|  |             MovementUtilities.aiMove(mob, mob.destination, true); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static void CheckToSendMobHome(Mob mob) { | ||||||
|  | 
 | ||||||
|  |         if(mob.isNecroPet()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if (!MovementUtilities.inRangeOfBindLocation(mob)) { | ||||||
|  | 
 | ||||||
|  |                 PowersBase recall = PowersManager.getPowerByToken(-1994153779); | ||||||
|  |                 PowersManager.useMobPower(mob, mob, recall, 40); | ||||||
|  | 
 | ||||||
|  |                 for (Map.Entry playerEntry : mob.playerAgroMap.entrySet()) | ||||||
|  |                     PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0); | ||||||
|  | 
 | ||||||
|  |                 mob.setCombatTarget(null); | ||||||
|  |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             //(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,66 @@ | |||||||
|  | package engine.mobileAI.MobHandlers; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.gameManager.MovementManager; | ||||||
|  | import engine.gameManager.ZoneManager; | ||||||
|  | import engine.mobileAI.utilities.CombatUtilities; | ||||||
|  | import engine.mobileAI.utilities.MovementUtilities; | ||||||
|  | import engine.objects.City; | ||||||
|  | import engine.objects.Mob; | ||||||
|  | import engine.objects.PlayerCharacter; | ||||||
|  | 
 | ||||||
|  | public class PetHandler { | ||||||
|  | 
 | ||||||
|  |     public static void run(Mob pet){ | ||||||
|  |         PlayerCharacter owner = pet.getOwner(); | ||||||
|  | 
 | ||||||
|  |         if(owner == null) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         if(!pet.isAlive()){ | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(!owner.isAlive()) { | ||||||
|  |             owner.dismissPet(); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         pet.updateLocation(); | ||||||
|  | 
 | ||||||
|  |         if(pet.combatTarget == null){ | ||||||
|  |             //follow owner
 | ||||||
|  |             if(!CombatUtilities.inRangeToAttack(pet,owner)) { | ||||||
|  |                 MovementUtilities.moveToLocation(pet, owner.loc, pet.getRange()); | ||||||
|  |             } | ||||||
|  |         }else{ | ||||||
|  | 
 | ||||||
|  |             if (pet.combatTarget.equals(pet)) { | ||||||
|  |                 pet.setCombatTarget(null); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             //chase target
 | ||||||
|  |             if(!CombatUtilities.inRangeToAttack(pet,pet.combatTarget)) { | ||||||
|  |                 MovementUtilities.moveToLocation(pet, pet.combatTarget.loc, pet.getRange()); | ||||||
|  |             }else{ | ||||||
|  |                 if(pet.getLastAttackTime() > System.currentTimeMillis()) | ||||||
|  |                     return; | ||||||
|  | 
 | ||||||
|  |                 pet.setLastAttackTime(System.currentTimeMillis() + 3000); | ||||||
|  | 
 | ||||||
|  |                 //attack target
 | ||||||
|  |                 if(pet.combatTarget.getObjectType().equals(Enum.GameObjectType.Building)){ | ||||||
|  |                     //attacking building
 | ||||||
|  |                     City playercity = ZoneManager.getCityAtLocation(pet.getLoc()); | ||||||
|  |                     if (playercity != null) | ||||||
|  |                         for (Mob guard : playercity.getParent().zoneMobSet) | ||||||
|  |                             if (guard.combatTarget == null && guard.getGuild() != null && pet.getGuild() != null && !guard.getGuild().equals(pet.getGuild())) | ||||||
|  |                                 MovementUtilities.aiMove(guard,pet.loc,false); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 CombatUtilities.combatCycle(pet,pet.combatTarget,true,null); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,449 @@ | |||||||
|  | package engine.mobileAI.MobHandlers; | ||||||
|  | 
 | ||||||
|  | import engine.gameManager.PowersManager; | ||||||
|  | import engine.math.Vector3fImmutable; | ||||||
|  | import engine.mobileAI.Threads.MobAIThread; | ||||||
|  | import engine.mobileAI.utilities.CombatUtilities; | ||||||
|  | import engine.mobileAI.utilities.MovementUtilities; | ||||||
|  | import engine.net.client.msg.PerformActionMsg; | ||||||
|  | import engine.objects.*; | ||||||
|  | import engine.powers.ActionsBase; | ||||||
|  | import engine.powers.PowersBase; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.concurrent.ThreadLocalRandom; | ||||||
|  | 
 | ||||||
|  | public class PlayerGuardHandler { | ||||||
|  |     public static void run(Mob guard) { | ||||||
|  |         if(!guard.isAlive() || guard.despawned){ | ||||||
|  |             CheckRespawn(guard); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         CheckForRecall(guard); | ||||||
|  | 
 | ||||||
|  |         if (guard.contract != null && guard.contract.getName().contains("Wall Archer")) { | ||||||
|  |             runWallArcherGuard(guard); | ||||||
|  |             return; | ||||||
|  |         }else if (guard.contract != null && guard.contract.getName().contains("Magister")) { | ||||||
|  |             runMagisterGuard(guard); | ||||||
|  |             return; | ||||||
|  |         }else if (guard.contract != null && guard.contract.getName().contains("Archer")) { | ||||||
|  |             runArcherGuard(guard); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         runMeleGuard(guard); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void runMeleGuard(Mob guard){ | ||||||
|  |         try { | ||||||
|  |             if (guard.combatTarget != null) | ||||||
|  |                 checkToDropGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget == null) | ||||||
|  |                 CheckForPlayerGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if(MovementUtilities.canMove(guard)) | ||||||
|  |                 CheckGuardMovement(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget != null && CombatUtilities.inRangeToAttack(guard, guard.combatTarget)) | ||||||
|  |                 CheckToAttack(guard); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception ignored) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void runArcherGuard(Mob guard){ | ||||||
|  |         try { | ||||||
|  |             if (guard.combatTarget != null) | ||||||
|  |                 checkToDropGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget == null) | ||||||
|  |                 CheckForPlayerGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if(MovementUtilities.canMove(guard)) | ||||||
|  |                 CheckGuardMovement(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget != null && CombatUtilities.inRangeToAttack(guard, guard.combatTarget)) | ||||||
|  |                 CheckToAttack(guard); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception ignored) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void runMagisterGuard(Mob guard){ | ||||||
|  |         try { | ||||||
|  |             if (guard.combatTarget != null) | ||||||
|  |                 checkToDropGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget == null) | ||||||
|  |                 CheckForPlayerGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if(MovementUtilities.canMove(guard)) | ||||||
|  |                 CheckMagisterMovement(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget != null && inRangeToCast(guard, guard.combatTarget)) | ||||||
|  |                 GuardCast(guard); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception ignored) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void runWallArcherGuard(Mob guard){ | ||||||
|  |         try { | ||||||
|  |             if (guard.combatTarget != null) | ||||||
|  |                 checkToDropGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget == null) | ||||||
|  |                 CheckForPlayerGuardAggro(guard); | ||||||
|  | 
 | ||||||
|  |             if (guard.combatTarget != null && CombatUtilities.inRangeToAttack(guard, guard.combatTarget)) | ||||||
|  |                 CheckToAttack(guard); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception ignored) { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void checkToDropGuardAggro(Mob guard){ | ||||||
|  |         if(guard.combatTarget.loc.distanceSquared(guard.loc) > (128f * 128f)) | ||||||
|  |             guard.setCombatTarget(null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckForPlayerGuardAggro(Mob guard){ | ||||||
|  |         PlayerCharacter tar = null; | ||||||
|  |         for(int id : guard.playerAgroMap.keySet()){ | ||||||
|  |             PlayerCharacter target = PlayerCharacter.getFromCache(id); | ||||||
|  | 
 | ||||||
|  |             float aggroRange = guard.getAggroRange(); | ||||||
|  | 
 | ||||||
|  |             if(guard.getEquip().get(2) != null && guard.getEquip().get(2).getItemBase().getRange() > 15) | ||||||
|  |                 aggroRange = guard.getEquip().get(2).getItemBase().getRange() * 1.5f; | ||||||
|  | 
 | ||||||
|  |             float squared = aggroRange * aggroRange; | ||||||
|  | 
 | ||||||
|  |             if(target.loc.distanceSquared(guard.loc) > squared) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             if(tar == null || guard.loc.distanceSquared(tar.loc) < guard.loc.distanceSquared(target.loc)) | ||||||
|  |                 if(GuardCanAggro(guard,target)) | ||||||
|  |                     tar = target; | ||||||
|  |         } | ||||||
|  |         if(tar != null) | ||||||
|  |             guard.setCombatTarget(tar); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Boolean GuardCanAggro(Mob guard, PlayerCharacter loadedPlayer){ | ||||||
|  |         if (loadedPlayer == null) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | ||||||
|  |         if (!loadedPlayer.isAlive()) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         //Can't see target, skip aggro.
 | ||||||
|  |         if (!guard.canSee(loadedPlayer)) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         if(guard.guardedCity != null && guard.guardedCity.cityOutlaws.contains(loadedPlayer.getObjectUUID())) | ||||||
|  |             return true; | ||||||
|  | 
 | ||||||
|  |         if(loadedPlayer.guild.getNation().equals(guard.guardedCity.getGuild().getNation())) | ||||||
|  |             return false; | ||||||
|  | 
 | ||||||
|  |         return !guard.guardedCity.isOpen(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void GuardCast(Mob mob) { | ||||||
|  | 
 | ||||||
|  |         if(mob.nextCastTime > System.currentTimeMillis()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             // Method picks a random spell from a mobile's list of powers
 | ||||||
|  |             // and casts it on the current target (or itself).  Validation
 | ||||||
|  |             // (including empty lists) is done previously within canCast();
 | ||||||
|  | 
 | ||||||
|  |             ArrayList<Integer> powerTokens; | ||||||
|  |             ArrayList<Integer> purgeTokens; | ||||||
|  |             AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); | ||||||
|  | 
 | ||||||
|  |             // Generate a list of tokens from the mob powers for this mobile.
 | ||||||
|  | 
 | ||||||
|  |             powerTokens = new ArrayList<>(mob.mobPowers.keySet()); | ||||||
|  |             purgeTokens = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |             // If player has this effect on them currently then remove
 | ||||||
|  |             // this token from our list.
 | ||||||
|  | 
 | ||||||
|  |             for (int powerToken : powerTokens) { | ||||||
|  | 
 | ||||||
|  |                 PowersBase powerBase = PowersManager.getPowerByToken(powerToken); | ||||||
|  | 
 | ||||||
|  |                 for (ActionsBase actionBase : powerBase.getActions()) { | ||||||
|  | 
 | ||||||
|  |                     String stackType = actionBase.stackType; | ||||||
|  | 
 | ||||||
|  |                     if (target.getEffects() != null && target.getEffects().containsKey(stackType)) | ||||||
|  |                         purgeTokens.add(powerToken); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             powerTokens.removeAll(purgeTokens); | ||||||
|  | 
 | ||||||
|  |             // Sanity check
 | ||||||
|  | 
 | ||||||
|  |             if (powerTokens.isEmpty()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             int powerToken; | ||||||
|  |             int nukeRoll = ThreadLocalRandom.current().nextInt(1,100); | ||||||
|  | 
 | ||||||
|  |             if (nukeRoll < 55) { | ||||||
|  | 
 | ||||||
|  |                 //use direct damage spell
 | ||||||
|  |                 powerToken = powerTokens.get(powerTokens.size() - 1); | ||||||
|  | 
 | ||||||
|  |             } else { | ||||||
|  |                 //use random spell
 | ||||||
|  |                 powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             int powerRank = 1; | ||||||
|  | 
 | ||||||
|  |             switch(mob.getRank()){ | ||||||
|  |                 case 1: | ||||||
|  |                     powerRank = 10; | ||||||
|  |                     break; | ||||||
|  |                 case 2: | ||||||
|  |                     powerRank = 15; | ||||||
|  |                     break; | ||||||
|  |                 case 3: | ||||||
|  |                     powerRank = 20; | ||||||
|  |                     break; | ||||||
|  |                 case 4: | ||||||
|  |                     powerRank = 25; | ||||||
|  |                     break; | ||||||
|  |                 case 5: | ||||||
|  |                     powerRank = 30; | ||||||
|  |                     break; | ||||||
|  |                 case 6: | ||||||
|  |                     powerRank = 35; | ||||||
|  |                     break; | ||||||
|  |                 case 7: | ||||||
|  |                     powerRank = 40; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             PowersBase mobPower = PowersManager.getPowerByToken(powerToken); | ||||||
|  | 
 | ||||||
|  |             //check for hit-roll
 | ||||||
|  | 
 | ||||||
|  |             if (mobPower.requiresHitRoll) | ||||||
|  |                 if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget())) | ||||||
|  |                     return; | ||||||
|  | 
 | ||||||
|  |             // Cast the spell
 | ||||||
|  | 
 | ||||||
|  |             if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) { | ||||||
|  | 
 | ||||||
|  |                 PerformActionMsg msg; | ||||||
|  | 
 | ||||||
|  |                 if (!mobPower.isHarmful() || mobPower.targetSelf) { | ||||||
|  | 
 | ||||||
|  |                     if (mobPower.category.equals("DISPEL")) { | ||||||
|  |                         PowersManager.useMobPower(mob, target, mobPower, powerRank); | ||||||
|  |                         msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | ||||||
|  |                     } else { | ||||||
|  |                         PowersManager.useMobPower(mob, mob, mobPower, powerRank); | ||||||
|  |                         msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob); | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     PowersManager.useMobPower(mob, target, mobPower, powerRank); | ||||||
|  |                     msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 msg.setUnknown04(2); | ||||||
|  | 
 | ||||||
|  |                 PowersManager.finishUseMobPower(msg, mob, 0, 0); | ||||||
|  |             } | ||||||
|  |             mob.nextCastTime = (long) (System.currentTimeMillis() + MobAIThread.AI_CAST_FREQUENCY); | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckToAttack(Mob guard){ | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if(guard.getLastAttackTime() > System.currentTimeMillis()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             PlayerCharacter target = (PlayerCharacter) guard.combatTarget; | ||||||
|  | 
 | ||||||
|  |             if (!guard.canSee(target)) { | ||||||
|  |                 guard.setCombatTarget(null); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (guard.isMoving() && guard.getRange() > 20) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if(target.combatStats == null) | ||||||
|  |                 target.combatStats = new PlayerCombatStats(target); | ||||||
|  | 
 | ||||||
|  |             ItemBase mainHand = guard.getWeaponItemBase(true); | ||||||
|  |             ItemBase offHand = guard.getWeaponItemBase(false); | ||||||
|  | 
 | ||||||
|  |             if (mainHand == null && offHand == null) { | ||||||
|  |                 CombatUtilities.combatCycle(guard, target, true, null); | ||||||
|  |                 int delay = 3000; | ||||||
|  |                 guard.setLastAttackTime(System.currentTimeMillis() + delay); | ||||||
|  |             } else if (guard.getWeaponItemBase(true) != null) { | ||||||
|  |                 int delay = 3000; | ||||||
|  |                 CombatUtilities.combatCycle(guard, target, true, guard.getWeaponItemBase(true)); | ||||||
|  |                 guard.setLastAttackTime(System.currentTimeMillis() + delay); | ||||||
|  |             } else if (guard.getWeaponItemBase(false) != null) { | ||||||
|  |                 int attackDelay = 3000; | ||||||
|  |                 CombatUtilities.combatCycle(guard, target, false, guard.getWeaponItemBase(false)); | ||||||
|  |                 guard.setLastAttackTime(System.currentTimeMillis() + attackDelay); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if (target.getPet() != null) | ||||||
|  |                 if (target.getPet().getCombatTarget() == null && target.getPet().assist) | ||||||
|  |                     target.getPet().setCombatTarget(guard); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             ////(guard.getObjectUUID() + " " + guard.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckGuardMovement(Mob guard){ | ||||||
|  |         if (guard.getCombatTarget() == null) { | ||||||
|  |             if (!guard.isMoving()) | ||||||
|  |                 Patrol(guard); | ||||||
|  |             else { | ||||||
|  |                 guard.stopPatrolTime = System.currentTimeMillis(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             MovementUtilities.moveToLocation(guard, guard.combatTarget.loc, guard.getRange()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static void Patrol(Mob mob) { | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  | 
 | ||||||
|  |             if(mob.isMoving()) | ||||||
|  |                 return; | ||||||
|  |             //make sure mob is out of combat stance
 | ||||||
|  | 
 | ||||||
|  |             int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; | ||||||
|  | 
 | ||||||
|  |             //early exit while waiting to patrol again
 | ||||||
|  | 
 | ||||||
|  |             if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis()) | ||||||
|  |                 return; | ||||||
|  | 
 | ||||||
|  |             if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) | ||||||
|  |                 mob.lastPatrolPointIndex = 0; | ||||||
|  | 
 | ||||||
|  |             mob.destination = Vector3fImmutable.getRandomPointOnCircle(mob.patrolPoints.get(mob.lastPatrolPointIndex),16f); | ||||||
|  |             mob.lastPatrolPointIndex += 1; | ||||||
|  | 
 | ||||||
|  |             MovementUtilities.aiMove(mob, mob.destination, true); | ||||||
|  | 
 | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             ////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private static boolean inRangeToCast(Mob guard, AbstractWorldObject target){ | ||||||
|  |         float castRangeSquared = 50f * 50f; | ||||||
|  |         float rangeSquared = guard.loc.distanceSquared(target.loc); | ||||||
|  |         return castRangeSquared >= rangeSquared; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckMagisterMovement(Mob guard){ | ||||||
|  |         if (guard.getCombatTarget() == null) { | ||||||
|  |             if (!guard.isMoving()) | ||||||
|  |                 Patrol(guard); | ||||||
|  |             else { | ||||||
|  |                 guard.stopPatrolTime = System.currentTimeMillis(); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             if(guard.isMoving()){ | ||||||
|  |                 float desiredRangeSquared = 40f * 40f; | ||||||
|  |                 float distance = guard.loc.distanceSquared(guard.combatTarget.loc); | ||||||
|  |                 if(distance <= desiredRangeSquared){ | ||||||
|  |                     guard.stopMovement(guard.getMovementLoc()); | ||||||
|  |                     guard.updateLocation(); | ||||||
|  |                 } | ||||||
|  |             }else { | ||||||
|  |                 MovementUtilities.moveToLocation(guard, guard.combatTarget.loc, guard.getRange()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckForRecall(Mob guard){ | ||||||
|  | 
 | ||||||
|  |         if(guard.loc.distanceSquared(guard.parentZone.getLoc()) > (800 * 800)) { | ||||||
|  | 
 | ||||||
|  |             PowersBase recall = PowersManager.getPowerByToken(-1994153779); | ||||||
|  |             PowersManager.useMobPower(guard, guard, recall, 40); | ||||||
|  | 
 | ||||||
|  |             for (Map.Entry playerEntry : guard.playerAgroMap.entrySet()) | ||||||
|  |                 PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0); | ||||||
|  | 
 | ||||||
|  |             guard.setCombatTarget(null); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void CheckRespawn(Mob guard){ | ||||||
|  |         if(!guard.despawned) | ||||||
|  |             guard.despawn(); | ||||||
|  | 
 | ||||||
|  |         long respawnTime = 0L; | ||||||
|  | 
 | ||||||
|  |         Building barracks = guard.building; | ||||||
|  |         if(barracks == null){ | ||||||
|  |             respawnTime = MBServerStatics.FIFTEEN_MINUTES; | ||||||
|  |         }else{ | ||||||
|  |             switch(barracks.getRank()) { | ||||||
|  |                 case 2: | ||||||
|  |                     respawnTime = 750000; // 12.5 minutes
 | ||||||
|  |                     break; | ||||||
|  |                 case 3: | ||||||
|  |                     respawnTime = 660000; // 11 minutes
 | ||||||
|  |                     break; | ||||||
|  |                 case 4: | ||||||
|  |                     respawnTime = 570000; // 9.5 minutes
 | ||||||
|  |                     break; | ||||||
|  |                 case 5: | ||||||
|  |                     respawnTime = 480000; // 8 minutes
 | ||||||
|  |                     break; | ||||||
|  |                 case 6: | ||||||
|  |                     respawnTime = 450000; // 6.5 minutes
 | ||||||
|  |                     break; | ||||||
|  |                 case 7: | ||||||
|  |                     respawnTime = MBServerStatics.FIVE_MINUTES; | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     respawnTime = MBServerStatics.FIFTEEN_MINUTES; | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(guard.deathTime + respawnTime < System.currentTimeMillis()){ | ||||||
|  |             if (!Zone.respawnQue.contains(guard)) { | ||||||
|  |                 Zone.respawnQue.add(guard); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,56 @@ | |||||||
|  | package engine.mobileAI.MobHandlers; | ||||||
|  | 
 | ||||||
|  | import engine.Enum; | ||||||
|  | import engine.gameManager.MovementManager; | ||||||
|  | import engine.gameManager.ZoneManager; | ||||||
|  | import engine.mobileAI.utilities.CombatUtilities; | ||||||
|  | import engine.mobileAI.utilities.MovementUtilities; | ||||||
|  | import engine.objects.Building; | ||||||
|  | import engine.objects.City; | ||||||
|  | import engine.objects.Mob; | ||||||
|  | import engine.server.MBServerStatics; | ||||||
|  | 
 | ||||||
|  | public class SiegeHandler { | ||||||
|  |     public static void run(Mob engine){ | ||||||
|  | 
 | ||||||
|  |         if(!engine.isAlive()) { | ||||||
|  |             check_siege_respawn(engine); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if(engine.getOwner() == null || !engine.getOwner().isAlive() || !engine.playerAgroMap.containsKey(engine.getOwner().getObjectUUID())) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         if(engine.combatTarget == null || !engine.combatTarget.getObjectType().equals(Enum.GameObjectType.Building)) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         siege_attack(engine); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void check_siege_respawn(Mob engine){ | ||||||
|  |         if(!engine.despawned) { | ||||||
|  |             engine.despawn(); | ||||||
|  |         }else{ | ||||||
|  |             if(engine.deathTime + MBServerStatics.FIFTEEN_MINUTES > System.currentTimeMillis()){ | ||||||
|  |                 engine.respawn(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static void siege_attack(Mob engine){ | ||||||
|  |         if(engine.getLastAttackTime() > System.currentTimeMillis()) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         if(CombatUtilities.inRangeToAttack(engine,engine.combatTarget)){ | ||||||
|  |             CombatUtilities.combatCycle(engine, engine.combatTarget, true, null); | ||||||
|  |             engine.setLastAttackTime(System.currentTimeMillis() + 15000); | ||||||
|  |             City playercity = ZoneManager.getCityAtLocation(engine.getLoc()); | ||||||
|  |             if (playercity != null) | ||||||
|  |                 for (Mob guard : playercity.getParent().zoneMobSet) | ||||||
|  |                     if (guard.isPlayerGuard && guard.combatTarget == null && guard.getGuild() != null && engine.getGuild() != null && !guard.getGuild().equals(engine.getGuild())) | ||||||
|  |                         MovementUtilities.aiMove(guard,engine.loc,false); | ||||||
|  | 
 | ||||||
|  |             MovementManager.sendRWSSMsg(engine); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,26 @@ | |||||||
|  | package engine.mobileAI; | ||||||
|  | 
 | ||||||
|  | import engine.mobileAI.MobHandlers.MobHandler; | ||||||
|  | import engine.mobileAI.MobHandlers.PetHandler; | ||||||
|  | import engine.mobileAI.MobHandlers.PlayerGuardHandler; | ||||||
|  | import engine.mobileAI.MobHandlers.SiegeHandler; | ||||||
|  | import engine.objects.Mob; | ||||||
|  | 
 | ||||||
|  | public class SuperSimpleMobAI { | ||||||
|  | 
 | ||||||
|  |     public static void run(Mob mob){ | ||||||
|  |         mob.updateLocation(); | ||||||
|  |         if(mob.isPet() && !mob.isSiege()) { | ||||||
|  |             PetHandler.run(mob); | ||||||
|  |             return; | ||||||
|  |         }else if (mob.isSiege()) { | ||||||
|  |             SiegeHandler.run(mob); | ||||||
|  |             return; | ||||||
|  |         }else if(mob.isPlayerGuard()){ | ||||||
|  |             PlayerGuardHandler.run(mob); | ||||||
|  |             return; | ||||||
|  |         }else { | ||||||
|  |             MobHandler.run(mob); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue