Compare commits
	
		
			1163 Commits 
		
	
	
	
				 192 changed files with 11768 additions and 2949 deletions
			
			
		| @ -0,0 +1,150 @@@@ -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 @@@@ -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 @@@@ -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 @@@@ -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,64 @@@@ -0,0 +1,64 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      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 engine.server.MBServerStatics; | ||||
| 
 | ||||
| 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 = MBServerStatics.PLAYER_GOLD_LIMIT - 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 @@@@ -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,75 @@@@ -0,0 +1,75 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.BuildingGroup; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.Enum.TargetColor; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.BuildingManager; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.gameManager.SessionManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import engine.powers.EffectsBase; | ||||
| import engine.server.MBServerStatics; | ||||
| import engine.util.StringUtils; | ||||
| 
 | ||||
| import java.text.DecimalFormat; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
|  * @author | ||||
|  */ | ||||
| public class PrintEffectsCmd extends AbstractDevCmd { | ||||
| 
 | ||||
|     public PrintEffectsCmd() { | ||||
|         super("printeffects"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
|                           AbstractGameObject target) { | ||||
| 
 | ||||
|         if(!target.getObjectType().equals(GameObjectType.PlayerCharacter)) { | ||||
|             throwbackInfo(pc, "Target Must PlayerCharacter"); | ||||
|             return; | ||||
|         } | ||||
|         String newline = "\r\n "; | ||||
|         String output = "Effects for Player:" + newline; | ||||
| 
 | ||||
|         AbstractCharacter absTar = (AbstractCharacter) target; | ||||
| 
 | ||||
|         for(String key : absTar.effects.keySet()){ | ||||
|             Effect eff = absTar.effects.get(key); | ||||
|             if(eff.getJobContainer() != null) { | ||||
|                 output += "[" + key + "] " + eff.getName() + " (" + eff.getTrains() + ") " + eff.getJobContainer().timeToExecutionLeft() * 0.001f + newline; | ||||
|             }else{ | ||||
|                 output += eff.getName() + " (" + eff.getTrains() + ") " + "PERMANENT" + newline; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         throwbackInfo(pc, output); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected String _getHelpString() { | ||||
|         return "Gets information on an Object."; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected String _getUsageString() { | ||||
|         return "' /info targetID'"; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,168 @@@@ -0,0 +1,168 @@ | ||||
| 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 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
 | ||||
|             //ItemBase specialLoot = ItemBase.getItemBase(866);
 | ||||
|             //Item promoted = new MobLoot(winner, specialLoot, 1, false).promoteToItem(winner);
 | ||||
|             //promoted.setNumOfItems(21235);
 | ||||
|             //promoted.setName("Special Banker(21235)");
 | ||||
|             //DbManager.ItemQueries.UPDATE_NUM_ITEMS(promoted,21235);
 | ||||
|             //winner.getCharItemManager().addItemToInventory(promoted);
 | ||||
|             //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,500f, 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,289 @@@@ -0,0 +1,289 @@ | ||||
| package engine.gameManager; | ||||
| 
 | ||||
| import engine.mobileAI.MobAI; | ||||
| import engine.mobileAI.utilities.CombatUtilities; | ||||
| import engine.mobileAI.utilities.MovementUtilities; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| public class HellgateManager { | ||||
|     public static ArrayList<Mob> hellgate_mobs; | ||||
|     public static ArrayList<Mob> hellgate_mini_bosses; | ||||
|     public static Mob hellgate_boss; | ||||
| 
 | ||||
|     public static Long hellgate_time_completed = 0L; | ||||
|     public static final int citadel_ruins_zone_id = 993; | ||||
|     public static final int hell_portal_1_zone_id = 994; | ||||
|     public static final int hell_portal_2_zone_id = 996; | ||||
|     public static final int hell_portal_3_zone_id = 997; | ||||
|     public static final int hell_portal_4_zone_id = 998; | ||||
| 
 | ||||
|     public static boolean initialized = false; | ||||
| 
 | ||||
|     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 void confiureHellgate(){ | ||||
|         compile_mob_list(); | ||||
|     } | ||||
|     public static void pulseHellgates(){ | ||||
|         if(!initialized){ | ||||
|             confiureHellgate(); | ||||
|             if(hellgate_boss != null) | ||||
|                 initialized = true; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(hellgate_mobs == null) { | ||||
|             return; | ||||
|         } | ||||
|         if(hellgate_mini_bosses == null) { | ||||
|             return; | ||||
|         } | ||||
|         if(hellgate_boss == null){ | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(!hellgate_boss.isAlive() && hellgate_time_completed == 0L) | ||||
|             hellgate_time_completed = System.currentTimeMillis(); | ||||
| 
 | ||||
|         if(hellgate_time_completed != 0L && System.currentTimeMillis() > hellgate_time_completed + MBServerStatics.THIRTY_MINUTES){ | ||||
|             ResetHellgate(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void compile_mob_list(){ | ||||
|         if(hellgate_mobs == null) { | ||||
|             hellgate_mobs =new ArrayList<>(); | ||||
|         } | ||||
|         if(hellgate_mini_bosses == null) { | ||||
|             hellgate_mini_bosses =new ArrayList<>(); | ||||
|         } | ||||
|         Zone hellgate_zone = ZoneManager.getZoneByUUID(citadel_ruins_zone_id); | ||||
|         if(hellgate_zone == null) | ||||
|             return; | ||||
| 
 | ||||
|         for(Mob mob : hellgate_zone.zoneMobSet){ | ||||
|             switch(mob.getMobBaseID()){ | ||||
|                 case 14163: // basic saetor warrior
 | ||||
|                     mob.getCharItemManager().clearInventory(); | ||||
|                     SpecialLootHandler(mob,false,false); | ||||
|                     mob.setResists(new Resists("Elite")); | ||||
|                     mob.healthMax = 8500; | ||||
|                     mob.setHealth(mob.healthMax); | ||||
|                     hellgate_mobs.add(mob); | ||||
|                     break; | ||||
|                 case 12770: // minotaur mini boss
 | ||||
|                     mob.getCharItemManager().clearInventory(); | ||||
|                     SpecialLootHandler(mob,true,false); | ||||
|                     mob.setResists(new Resists("Elite")); | ||||
|                     mob.healthMax = 12500; | ||||
|                     mob.setHealth(mob.healthMax); | ||||
|                     hellgate_mini_bosses.add(mob); | ||||
|                     break; | ||||
|                 case 14180: // mordoth, son of morlock
 | ||||
|                     mob.getCharItemManager().clearInventory(); | ||||
|                     SpecialLootHandler(mob,false,true); | ||||
|                     mob.setResists(new Resists("Elite")); | ||||
|                     mob.healthMax = mob.mobBase.getHealthMax(); | ||||
|                     mob.setHealth(mob.healthMax); | ||||
|                     hellgate_boss = mob; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void ResetHellgate(){ | ||||
|         hellgate_time_completed = 0L; | ||||
|         for(Mob mob : hellgate_mobs){ | ||||
|             if(!mob.isAlive()){ | ||||
|                 if(!mob.despawned){ | ||||
|                     mob.despawn(); | ||||
|                 } | ||||
|                 mob.respawn(); | ||||
|             } | ||||
|             mob.setHealth(mob.healthMax); | ||||
|             SpecialLootHandler(mob,false,false); | ||||
|         } | ||||
|         for(Mob mob : hellgate_mini_bosses){ | ||||
|             if(!mob.isAlive()){ | ||||
|                 if(!mob.despawned){ | ||||
|                     mob.despawn(); | ||||
|                 } | ||||
|                 mob.respawn(); | ||||
|             } | ||||
|             mob.setHealth(mob.healthMax); | ||||
|             SpecialLootHandler(mob,true,false); | ||||
|         } | ||||
|         if(!hellgate_boss.isAlive()){ | ||||
|             if(!hellgate_boss.despawned){ | ||||
|                 hellgate_boss.despawn(); | ||||
|             } | ||||
|             hellgate_boss.respawn(); | ||||
|         } | ||||
|         hellgate_boss.setHealth(hellgate_boss.healthMax); | ||||
|         SpecialLootHandler(hellgate_boss,false,true); | ||||
|     } | ||||
| 
 | ||||
|     public static void SpecialMobAIHandler(Mob mob){ | ||||
| 
 | ||||
|         if(mob.playerAgroMap.isEmpty()) | ||||
|             return; | ||||
| 
 | ||||
|         if(!mob.isAlive()) | ||||
|             return; | ||||
| 
 | ||||
|         if(mob.combatTarget == null) | ||||
|             MobAI.NewAggroMechanic(mob); | ||||
| 
 | ||||
|         if(MovementUtilities.canMove(mob) &&  mob.combatTarget != null && !CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) | ||||
|             MobAI.chaseTarget(mob); | ||||
| 
 | ||||
|         if(mob.combatTarget != null) | ||||
|             MobAI.CheckForAttack(mob); | ||||
| 
 | ||||
|         if(mob.combatTarget == null && mob.loc.distanceSquared(mob.bindLoc) > 1024) {//32 units
 | ||||
|             mob.teleport(mob.bindLoc); | ||||
|             mob.setCombatTarget(null); | ||||
|             MovementUtilities.aiMove(mob,mob.bindLoc,true); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void SpecialLootHandler(Mob mob, Boolean commander, Boolean epic){ | ||||
|         mob.getCharItemManager().clearInventory(); | ||||
|         int contractRoll = ThreadLocalRandom.current().nextInt(1,101); | ||||
|         if(contractRoll <= 25){ | ||||
|             //generate random contract
 | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         int runeRoll = ThreadLocalRandom.current().nextInt(1,101); | ||||
|         ItemBase runeBase = null; | ||||
|         int roll; | ||||
|         int itemId; | ||||
|         if(runeRoll <= 60 && !commander && !epic) { | ||||
|             //generate random rune (standard 5-30)
 | ||||
|             roll = ThreadLocalRandom.current().nextInt(static_rune_ids_low.size() + 1); | ||||
|             itemId = static_rune_ids_low.get(0); | ||||
|             try { | ||||
|                 itemId = static_rune_ids_low.get(roll); | ||||
|             } catch (Exception e) { | ||||
| 
 | ||||
|             } | ||||
|             runeBase = ItemBase.getItemBase(itemId); | ||||
|             if (runeBase != null) { | ||||
|                 MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|                 if (rune != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(rune); | ||||
|             } | ||||
|         } | ||||
|         if(runeRoll <= 50 && commander) { | ||||
|             //generate random rune (30-40)
 | ||||
|             roll = ThreadLocalRandom.current().nextInt(static_rune_ids_mid.size() + 1); | ||||
|             itemId = static_rune_ids_mid.get(0); | ||||
|             try { | ||||
|                 itemId = static_rune_ids_mid.get(roll); | ||||
|             } catch (Exception e) { | ||||
| 
 | ||||
|             } | ||||
|             runeBase = ItemBase.getItemBase(itemId); | ||||
|             if (runeBase != null) { | ||||
|                 MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|                 if (rune != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(rune); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(runeRoll <= 80 && epic) { | ||||
|             //generate random rune (35-40)
 | ||||
|             roll = ThreadLocalRandom.current().nextInt(static_rune_ids_high.size() + 1); | ||||
|             itemId = static_rune_ids_high.get(0); | ||||
|             try { | ||||
|                 itemId = static_rune_ids_high.get(roll); | ||||
|             } catch (Exception e) { | ||||
| 
 | ||||
|             } | ||||
|             runeBase = ItemBase.getItemBase(itemId); | ||||
|             if (runeBase != null) { | ||||
|                 MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|                 if (rune != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(rune); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(commander || epic) { | ||||
|             //handle special case for racial guards
 | ||||
| 
 | ||||
|             roll = ThreadLocalRandom.current().nextInt(LootManager.racial_guard_uuids.size() + 1); | ||||
|             itemId = LootManager.racial_guard_uuids.get(0); | ||||
|             try { | ||||
|                 itemId = LootManager.racial_guard_uuids.get(roll); | ||||
|             } catch (Exception e) { | ||||
| 
 | ||||
|             } | ||||
|             runeBase = ItemBase.getItemBase(itemId); | ||||
|             if (runeBase != null) { | ||||
|                 MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|                 if (rune != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(rune); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(epic){ | ||||
|             //handle glass chance for epic
 | ||||
|             int glassRoll = ThreadLocalRandom.current().nextInt(1,101); | ||||
|             if(glassRoll < 5){ | ||||
|                 int glassID = LootManager.rollRandomItem(126); | ||||
|                 ItemBase glassItem = ItemBase.getItemBase(glassID); | ||||
|                 if (glassItem != null) { | ||||
|                     MobLoot glass = new MobLoot(mob, glassItem, true); | ||||
| 
 | ||||
|                     if (glass != null) | ||||
|                         mob.getCharItemManager().addItemToInventory(glass); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         //handle gold drops
 | ||||
|         int goldDrop; | ||||
|         if(!commander && !epic){ | ||||
|             goldDrop = ThreadLocalRandom.current().nextInt(25000); | ||||
|             mob.getCharItemManager().addGoldToInventory(goldDrop,false); | ||||
|         } | ||||
|         if(commander){ | ||||
|             goldDrop = ThreadLocalRandom.current().nextInt(100000,250000); | ||||
|             mob.getCharItemManager().addGoldToInventory(goldDrop,false); | ||||
|         } | ||||
|         if(epic){ | ||||
|             goldDrop = ThreadLocalRandom.current().nextInt(2500000,5000000); | ||||
|             mob.getCharItemManager().addGoldToInventory(goldDrop,false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,238 @@@@ -0,0 +1,238 @@ | ||||
| package engine.gameManager; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.net.Dispatch; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.msg.HotzoneChangeMsg; | ||||
| import engine.net.client.msg.chat.ChatSystemMsg; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| import java.util.Random; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| public class HotzoneManager { | ||||
|     public static Long lastPulseTime = 0L; | ||||
|     public static HashMap<Guild, ArrayList<PlayerCharacter>> playersPresent; | ||||
|     public static Mob hotzoneMob = null; | ||||
|     public static boolean three_quarter_health = false; | ||||
|     public static boolean half_health = false; | ||||
|     public static boolean quarter_health = false; | ||||
|     public static void SelectRandomHotzone(){ | ||||
|         if(hotzoneMob != null){ | ||||
|             hotzoneMob.killCharacter("Hotzone Over"); | ||||
|             hotzoneMob.despawn(); | ||||
|             hotzoneMob.spawnTime = 1000000000; | ||||
|             DbManager.MobQueries.DELETE_MOB( hotzoneMob); | ||||
|         } | ||||
|         Random random = new Random(); | ||||
|         Zone newHotzone = null; | ||||
|         while (newHotzone == null || newHotzone.getObjectUUID() == 931 || newHotzone.getObjectUUID() == 913) | ||||
|             newHotzone = (Zone) ZoneManager.macroZones.toArray()[random.nextInt(ZoneManager.macroZones.size())]; | ||||
|         ZoneManager.setHotZone(newHotzone); | ||||
|         ZoneManager.hotZone = newHotzone; | ||||
|         int R8UUId = 0; | ||||
|         switch(random.nextInt(5)) { | ||||
|             case 1: | ||||
|                 R8UUId = 14152; | ||||
|                 break; | ||||
|             case 2: | ||||
|                 R8UUId = 14179; | ||||
|                 break; | ||||
|             case 3: | ||||
|                 R8UUId = 14180; | ||||
|                 break; | ||||
|             case 4: | ||||
|                 R8UUId = 14220; | ||||
|                 break; | ||||
|             default: | ||||
|                 R8UUId = 14319; | ||||
|                 break; | ||||
|         } | ||||
|         Mob created = Mob.createMob(R8UUId,newHotzone.getLoc(), Guild.getErrantGuild(),true,newHotzone,null,0,"",85); | ||||
|         if(created == null){ | ||||
|             Logger.error("Failed To Generate Hotzone R8 Mob"); | ||||
|             return; | ||||
|         } | ||||
|         ChatSystemMsg chatMsg = new ChatSystemMsg(null, created.getFirstName() + " has spawned in " + newHotzone.getName() + ". Glory and riches await adventurers who dare defeat it!"); | ||||
|         chatMsg.setMessageType(10); | ||||
|         chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); | ||||
|         DispatchMessage.dispatchMsgToAll(chatMsg); | ||||
| 
 | ||||
|         created.bindLoc = newHotzone.getLoc(); | ||||
|         created.runAfterLoad(); | ||||
|         WorldGrid.addObject(created,created.bindLoc.x,created.bindLoc.z); | ||||
|         created.teleport(created.bindLoc); | ||||
|         created.BehaviourType = Enum.MobBehaviourType.Aggro; | ||||
|         hotzoneMob = created; | ||||
|         created.setHealth(100000); | ||||
|         created.setResists(new Resists("Dropper")); | ||||
|         GenerateHotzoneEpicLoot(created); | ||||
|         ZoneManager.hotZone = newHotzone; | ||||
| 
 | ||||
|         for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()) { | ||||
|             HotzoneChangeMsg hcm = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID()); | ||||
|             Dispatch dispatch = Dispatch.borrow(player, hcm); | ||||
|             DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); | ||||
|         } | ||||
|         three_quarter_health = false; | ||||
|         half_health = false; | ||||
|         quarter_health = false; | ||||
|     } | ||||
| 
 | ||||
|     public static void GenerateHotzoneEpicLoot(Mob mob) { | ||||
|         mob.getCharItemManager().clearInventory(); | ||||
|         Random random = new Random(); | ||||
|         int roll; | ||||
|         int itemId; | ||||
|         //wrapped rune:
 | ||||
|         ItemBase runeBase = ItemBase.getItemBase(971070); | ||||
|         if (runeBase != null) { | ||||
|             MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|             if (rune != null) | ||||
|                 mob.getCharItemManager().addItemToInventory(rune); | ||||
|         } | ||||
| 
 | ||||
|         roll = ThreadLocalRandom.current().nextInt(1, 101); | ||||
|         if (roll >= 95) { | ||||
|             //glass
 | ||||
|             int glassID = LootManager.rollRandomItem(126); | ||||
|             ItemBase glassItem = ItemBase.getItemBase(glassID); | ||||
|             if (glassItem != null) { | ||||
|                 MobLoot glass = new MobLoot(mob, glassItem, true); | ||||
| 
 | ||||
|                 if (glass != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(glass); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         roll = ThreadLocalRandom.current().nextInt(1, 101); | ||||
|         if (roll >= 95) { | ||||
|             //r8 banescroll
 | ||||
|             int baneID = 910018; | ||||
|             ItemBase baneItem = ItemBase.getItemBase(baneID); | ||||
|             if (baneItem != null) { | ||||
|                 MobLoot bane = new MobLoot(mob, baneItem, true); | ||||
| 
 | ||||
|                 if (bane != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(bane); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         roll = ThreadLocalRandom.current().nextInt(1, 101); | ||||
|         if (roll >= 95) { | ||||
|             //guard captain
 | ||||
|             roll = ThreadLocalRandom.current().nextInt(LootManager.racial_guard_uuids.size() + 1); | ||||
|             itemId = LootManager.racial_guard_uuids.get(0); | ||||
|             try { | ||||
|                 itemId = LootManager.racial_guard_uuids.get(roll); | ||||
|             } catch (Exception e) { | ||||
| 
 | ||||
|             } | ||||
|             runeBase = ItemBase.getItemBase(itemId); | ||||
|             if (runeBase != null) { | ||||
|                 MobLoot rune = new MobLoot(mob, runeBase, true); | ||||
| 
 | ||||
|                 if (rune != null) | ||||
|                     mob.getCharItemManager().addItemToInventory(rune); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void ClearHotzone(){ | ||||
|         ZoneManager.hotZone = null; | ||||
|         for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()) { | ||||
|             HotzoneChangeMsg hcm = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), 0); | ||||
|             Dispatch dispatch = Dispatch.borrow(player, hcm); | ||||
|             DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void pulse(){ | ||||
|         if(HotzoneManager.playersPresent == null) | ||||
|             HotzoneManager.playersPresent = new HashMap<>(); | ||||
| 
 | ||||
|         if(ZoneManager.hotZone == null) | ||||
|             return; | ||||
| 
 | ||||
|         if(lastPulseTime + 5000L > System.currentTimeMillis()) | ||||
|             return; | ||||
| 
 | ||||
|         lastPulseTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         //handle world announcements for HZ boss
 | ||||
|         if(hotzoneMob != null){ | ||||
|             float health = hotzoneMob.getHealth(); | ||||
|             if(health < 75000 && health > 50000 && !three_quarter_health){ | ||||
|                 //mob at 50%-75% health
 | ||||
|                 three_quarter_health = true; | ||||
|                 String name = hotzoneMob.getName(); | ||||
|                 ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 75% Health"); | ||||
|                 chatMsg.setMessageType(10); | ||||
|                 chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); | ||||
|                 DispatchMessage.dispatchMsgToAll(chatMsg); | ||||
|             }else if(health < 50000 && health > 25000 && !half_health){ | ||||
|                 //mob ta 25%-50% health
 | ||||
|                 half_health = true; | ||||
|                 String name = hotzoneMob.getName(); | ||||
|                 ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 50% Health"); | ||||
|                 chatMsg.setMessageType(10); | ||||
|                 chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); | ||||
|                 DispatchMessage.dispatchMsgToAll(chatMsg); | ||||
|             }else if(health < 25000 && !quarter_health){ | ||||
|                 //mob under 25% health
 | ||||
|                 quarter_health = true; | ||||
|                 String name = hotzoneMob.getName(); | ||||
|                 ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 25% Health"); | ||||
|                 chatMsg.setMessageType(10); | ||||
|                 chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); | ||||
|                 DispatchMessage.dispatchMsgToAll(chatMsg); | ||||
|             }else if (health > 75000){ | ||||
|                 //mob at 75% - 100% health
 | ||||
| 
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(ZoneManager.hotZone.getLoc(),ZoneManager.hotZone.getBounds().getHalfExtents().x * 2, MBServerStatics.MASK_PLAYER); | ||||
| 
 | ||||
|         //clear out old players who aren't here anymore
 | ||||
|         for(Guild nation : HotzoneManager.playersPresent.keySet()){ | ||||
|             for(PlayerCharacter pc : HotzoneManager.playersPresent.get(nation)){ | ||||
|                 if (!inRange.contains(pc)) { | ||||
|                     HotzoneManager.playersPresent.get(nation).remove(pc); | ||||
|                     if(HotzoneManager.playersPresent.get(nation).size() < 1){ | ||||
|                         HotzoneManager.playersPresent.remove(nation); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         //check status of current players/nation in vicinity
 | ||||
|         for(AbstractWorldObject awo : inRange){ | ||||
|             PlayerCharacter pc = (PlayerCharacter)awo; | ||||
|             Guild nation = pc.guild.getNation(); | ||||
|             if(HotzoneManager.playersPresent.containsKey(nation)){ | ||||
|                 //nation already here, add to list
 | ||||
|                 if(HotzoneManager.playersPresent.get(nation).size() >= 5 && !HotzoneManager.playersPresent.get(nation).contains(pc)){ | ||||
|                     //more than 5, boot player out
 | ||||
|                     MovementManager.translocate(pc, Vector3fImmutable.getRandomPointOnCircle(ZoneManager.getZoneByUUID(656).getLoc(),30f),Regions.GetRegionForTeleport(ZoneManager.getZoneByUUID(656).getLoc())); | ||||
|                 } | ||||
|                 if(!HotzoneManager.playersPresent.get(nation).contains(pc)){ | ||||
|                     //less than 5, allow player in
 | ||||
|                     HotzoneManager.playersPresent.get(nation).add(pc); | ||||
|                 } | ||||
|             }else{ | ||||
|                 ArrayList<PlayerCharacter> newList = new ArrayList<>(); | ||||
|                 newList.add(pc); | ||||
|                 HotzoneManager.playersPresent.put(nation,newList); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,130 @@@@ -0,0 +1,130 @@ | ||||
| package engine.gameManager; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.Guild; | ||||
| import engine.objects.Mine; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Regions; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| public class LoreMineManager { | ||||
| 
 | ||||
|     //Saetor Allowed Charters:
 | ||||
|     //BARBARIAN
 | ||||
|     //MILITARY
 | ||||
|     //RANGER
 | ||||
|     //AMAZON
 | ||||
|     //WIZARD
 | ||||
|     //MERCENARY
 | ||||
|     //THIEVES
 | ||||
|     //SCOURGE
 | ||||
|     //UNHOLY
 | ||||
|     public static final Map<Enum.GuildType, List<String>> GUILD_RACES = new HashMap<>(); | ||||
|     public static final Map<Enum.GuildType, List<String>> GUILD_CLASSES = new HashMap<>(); | ||||
|     public static final Map<Enum.GuildType, Boolean> GUILD_GENDER_RESTRICTION = new HashMap<>(); | ||||
| 
 | ||||
|     static { | ||||
|         GUILD_RACES.put(Enum.GuildType.CATHEDRAL, Arrays.asList("Aelfborn", "Centaur", "Elf", "Half Giant", "Human")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.CATHEDRAL, Arrays.asList("Bard", "Channeler", "Crusader", "Nightstalker", "Prelate", "Priest", "Scout", "Sentinel")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.MILITARY, Arrays.asList("Centaur", "Half Giant", "Human", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.MILITARY, Arrays.asList("Bard", "Priest", "Scout", "Warlock", "Warrior", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.TEMPLE, Arrays.asList("Half Giant", "Human")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.TEMPLE, Arrays.asList("Assassin", "Bard", "Channeler", "Confessor", "Nightstalker", "Priest", "Scout", "Templar")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.BARBARIAN, Arrays.asList("Aelfborn", "Half Giant", "Human", "Minotaur", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.BARBARIAN, Arrays.asList("Barbarian", "Bard", "Doomsayer", "Fury", "Priest", "Scout", "Thief", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.RANGER, Arrays.asList("Aelfborn", "Elf", "Half Giant", "Human", "Shade", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.RANGER, Arrays.asList("Bard", "Channeler", "Druid", "Priest", "Ranger", "Scout", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.AMAZON, Arrays.asList("Aelfborn", "Elf", "Half Giant", "Human", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.AMAZON, Arrays.asList("Bard", "Druid", "Fury", "Huntress", "Priest", "Scout", "Warrior", "Wizard")); | ||||
|         GUILD_GENDER_RESTRICTION.put(Enum.GuildType.AMAZON, true); // Female only
 | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.NOBLE, Arrays.asList("Aelfborn", "Half Giant", "Human")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.NOBLE, Arrays.asList("Assassin", "Bard", "Channeler", "Priest", "Scout", "Thief", "Warlock", "Warrior", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.WIZARD, Arrays.asList("Aelfborn", "Elf", "Human", "Nephilim", "Shade", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.WIZARD, Arrays.asList("Assassin", "Bard", "Channeler", "Doomsayer", "Fury", "Necromancer", "Priest", "Warlock", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.MERCENARY, Arrays.asList("Aelfborn", "Aracoix", "Half Giant", "Human", "Shade", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.MERCENARY, Arrays.asList("Assassin", "Bard", "Priest", "Scout", "Thief", "Warlock", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.THIEVES, Arrays.asList("Aelfborn", "Aracoix", "Elf", "Human", "Irekei", "Nephilim", "Shade", "Vampire", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.THIEVES, Arrays.asList("Assassin", "Barbarian", "Bard", "Priest", "Scout", "Thief", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.DWARF, Arrays.asList("Dwarf")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.DWARF, Arrays.asList("Crusader", "Prelate", "Priest", "Sentinel", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.HIGHCOURT, Arrays.asList("Elf", "Minotaur")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.HIGHCOURT, Arrays.asList("Assassin", "Bard", "Channeler", "Druid", "Necromancer", "Priest", "Ranger", "Scout", "Thief", "Warrior", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.VIRAKT, Arrays.asList("Irekei")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.VIRAKT, Arrays.asList("Assassin", "Bard", "Channeler", "Fury", "Huntress", "Nightstalker", "Priest", "Ranger", "Scout", "Thief", "Warrior", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.SCOURGE, Arrays.asList("Aelfborn", "Human", "Minotaur", "Nephilim", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.SCOURGE, Arrays.asList("Bard", "Channeler", "Doomsayer", "Priest", "Scout", "Warrior", "Wizard")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.KHREE, Arrays.asList("Aracoix")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.KHREE, Arrays.asList("Assassin", "Barbarian", "Bard", "Huntress", "Priest", "Ranger", "Scout", "Thief", "Warlock", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.CENTAUR, Arrays.asList("Centaur")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.CENTAUR, Arrays.asList("Barbarian", "Crusader", "Druid", "Huntress", "Prelate", "Priest", "Ranger", "Sentinel", "Warrior")); | ||||
| 
 | ||||
|         GUILD_RACES.put(Enum.GuildType.UNHOLY, Arrays.asList("Human", "Shade", "Vampire", "Saetor")); | ||||
|         GUILD_CLASSES.put(Enum.GuildType.UNHOLY, Arrays.asList("Assassin", "Channeler", "Necromancer", "Priest", "Scout", "Thief", "Warlock", "Warrior", "Wizard")); | ||||
|     } | ||||
| 
 | ||||
|     public static void AuditPlayer(PlayerCharacter pc, Mine mine){ | ||||
|         Guild nation = pc.guild.getNation(); | ||||
| 
 | ||||
|         if(mine.chosen_charters == null){ | ||||
|             mine.chosen_charters = new HashMap<>(); | ||||
|         } | ||||
| 
 | ||||
|         Enum.GuildType guildType; | ||||
|         if (mine.chosen_charters.containsKey(nation)) { | ||||
|             guildType = mine.chosen_charters.get(nation); | ||||
|         }else{ | ||||
|             guildType = Enum.GuildType.getGuildTypeFromInt(pc.guild.getCharter()); | ||||
|             mine.chosen_charters.put(nation,guildType); | ||||
|         } | ||||
| 
 | ||||
|         if(!validForCharter(pc,guildType)){ | ||||
|             //bounce out to SDR
 | ||||
|             Vector3fImmutable bounceLoc = Vector3fImmutable.getRandomPointOnCircle(ZoneManager.getZoneByUUID(656).getLoc(),30f); | ||||
|             pc.setLoc(bounceLoc); | ||||
|             MovementManager.translocate(pc, bounceLoc, Regions.GetRegionForTeleport(ZoneManager.getZoneByUUID(656).getLoc())); | ||||
|             ChatManager.chatSystemInfo(pc, "You Failed To Meet Lore Requirements"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static boolean validForCharter(PlayerCharacter pc, Enum.GuildType guildType) { | ||||
|         if(pc.getPromotionClass() == null) | ||||
|             return false; | ||||
| 
 | ||||
|         // Define the races and classes for each GuildType
 | ||||
| 
 | ||||
| 
 | ||||
|         // Get the allowed races and classes for this guildType
 | ||||
|         List<String> allowedRaces = GUILD_RACES.getOrDefault(guildType, Collections.emptyList()); | ||||
|         List<String> allowedClasses = GUILD_CLASSES.getOrDefault(guildType, Collections.emptyList()); | ||||
| 
 | ||||
|         // Validate player's race and class
 | ||||
|         if (!allowedRaces.contains(pc.getRace().getName()) || !allowedClasses.contains(pc.getPromotionClass().getName())) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         // Gender restriction check for AMAZON
 | ||||
|         if (guildType.equals(Enum.GuildType.AMAZON) && pc.isMale() && pc.getRaceID() != 1999) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,277 @@@@ -0,0 +1,277 @@ | ||||
| package engine.gameManager; | ||||
| 
 | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.*; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| public class SpecialLootHandler { | ||||
|     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 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; | ||||
| 
 | ||||
|         //for(Zone zone : ZoneManager.macroZones){
 | ||||
|         //    HashSet<AbstractWorldObject> inZone = WorldGrid.getObjectsInRangePartial(zone.getLoc(),zone.getBounds().getHalfExtents().x * 2f, MBServerStatics.MASK_MOB);
 | ||||
|         //    if(inZone.contains(mob)){
 | ||||
|         //        return zone;
 | ||||
|          //   }
 | ||||
|         //}
 | ||||
|         //return null;
 | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,347 @@@@ -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,274 @@@@ -0,0 +1,274 @@ | ||||
| package engine.gameManager; | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| 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; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void MineTracker(Mine mine){ | ||||
|         Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID()); | ||||
|         if(tower == null) | ||||
|             return; | ||||
| 
 | ||||
|         float affectedRange = MBServerStatics.CHARACTER_LOAD_RANGE * 3; | ||||
|         mine.zergTracker.compileCurrent(tower.loc, affectedRange); | ||||
|         mine.zergTracker.sortByNation(); | ||||
|         mine.zergTracker.compileLeaveQue(tower.loc, affectedRange); | ||||
|         mine.zergTracker.processLeaveQue(); | ||||
|         mine.zergTracker.applyMultiplier(mine.capSize); | ||||
|     } | ||||
| 
 | ||||
|     public static void PrintDetailsToClient(PlayerCharacter pc){ | ||||
|         String newline = "\r\n "; | ||||
|         String outstring = newline + "ZERG MANAGER DETAILS FOR: " + pc.getFirstName() + newline; | ||||
|         Mine attended = null; | ||||
|         for(Mine mine : Mine.getMines()){ | ||||
|             Building tower = BuildingManager.getBuilding(mine.getBuildingID()); | ||||
|             if(tower == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             float rangeSquared = (MBServerStatics.CHARACTER_LOAD_RANGE * 3) * (MBServerStatics.CHARACTER_LOAD_RANGE * 3); | ||||
| 
 | ||||
|             if(pc.loc.distanceSquared(tower.loc) < rangeSquared){ | ||||
|                 attended = mine; | ||||
|             } | ||||
|         } | ||||
|         if(attended != null){ | ||||
|             outstring += "Mine Cap: " + attended.capSize + newline; | ||||
|             Building tower = BuildingManager.getBuilding(attended.getBuildingID()); | ||||
|             if(tower == null) | ||||
|                 return; | ||||
| 
 | ||||
|             int count = 0; | ||||
|             ArrayList<PlayerCharacter> stillPresent = new ArrayList<>(); | ||||
|             ArrayList<PlayerCharacter> gonePlayers = new ArrayList<>(); | ||||
|             for(Integer countedID : attended.mineAttendees.keySet()){ | ||||
|                 PlayerCharacter counted = PlayerCharacter.getFromCache(countedID); | ||||
|                 if(counted != null){ | ||||
|                     if(counted.guild.getNation().equals(pc.guild.getNation())) { | ||||
|                         Long timeGone = System.currentTimeMillis() - attended.mineAttendees.get(countedID); | ||||
|                         if(timeGone > 5000){ | ||||
|                             //outstring += counted.getFirstName() + " GONE FOR: " + timeGone/1000 + " SECONDS" + newline;
 | ||||
|                             gonePlayers.add(counted); | ||||
|                         }else{ | ||||
|                             //outstring += counted.getFirstName() + " STILL PRESENT" + newline;
 | ||||
|                             stillPresent.add(counted); | ||||
|                         } | ||||
|                         count ++; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             outstring += newline + "TOTAL NATION MEMBERS COUNTED: " + count + newline; | ||||
|             outstring += newline + "PLAYERS PRESENT:" + newline; | ||||
|             for(PlayerCharacter present : stillPresent){ | ||||
|                 outstring += present.getFirstName() + newline; | ||||
|             } | ||||
|             outstring += newline + "PLAYERS GONE:" + newline; | ||||
|             for(PlayerCharacter gone : gonePlayers){ | ||||
|                 Long timeGone = System.currentTimeMillis() - attended.mineAttendees.get(gone.getObjectUUID()); | ||||
|                 if(timeGone > 5000) { | ||||
|                     outstring += gone.getFirstName() + " GONE FOR: " + timeGone / 1000 + " SECONDS" + newline; | ||||
|                 } | ||||
|             } | ||||
|         }else{ | ||||
|             outstring += "Mine: Not Within Mine Distance" + newline; | ||||
|         } | ||||
| 
 | ||||
|         outstring += newline + "Zerg Multiplier: " + pc.ZergMultiplier + newline; | ||||
| 
 | ||||
|         ChatManager.chatSystemInfo(pc, outstring); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,75 @@@@ -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,266 @@@@ -0,0 +1,266 @@ | ||||
| package engine.mobileAI.Behaviours; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.InterestManagement.InterestManager; | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.mobileAI.utilities.CombatUtilities; | ||||
| import engine.mobileAI.utilities.MovementUtilities; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| public class StandardMob { | ||||
| 
 | ||||
|     public static void run(Mob mob){ | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); | ||||
| 
 | ||||
|         if(inRange.isEmpty()) | ||||
|             return; | ||||
| 
 | ||||
|         if(!mob.isAlive()){ | ||||
|             CheckForRespawn(mob); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (mob.isMoving()) { | ||||
|             mob.setLoc(mob.getMovementLoc()); | ||||
|             mob.updateLocation(); | ||||
|         } | ||||
| 
 | ||||
|         if(mob.combatTarget == null) { | ||||
|             if (!inRange.isEmpty()) { | ||||
|                 CheckForAggro(mob); | ||||
|             } | ||||
|         }else{ | ||||
|             CheckToDropCombatTarget(mob); | ||||
|             if(mob.combatTarget == null){ | ||||
|                 CheckForAggro(mob); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(MovementUtilities.canMove(mob)) | ||||
|             CheckForMovement(mob); | ||||
| 
 | ||||
|         if(mob.combatTarget != null && !mob.isMoving()) | ||||
|             CheckForAttack(mob); | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckToDropCombatTarget(Mob mob){ | ||||
| 
 | ||||
|         if(!mob.combatTarget.isAlive()){ | ||||
|             mob.setCombatTarget(null); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){ | ||||
|             PlayerCharacter pcTarget = (PlayerCharacter) mob.combatTarget; | ||||
|             if (!mob.canSee(pcTarget)) { | ||||
|                 mob.setCombatTarget(null); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if(mob.bindLoc.distanceSquared(mob.combatTarget.loc) > 90 * 90){ | ||||
|             mob.setCombatTarget(null); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForRespawn(Mob mob){ | ||||
|         if (mob.deathTime == 0) { | ||||
|             mob.setDeathTime(System.currentTimeMillis()); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         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_ONCE_LOOTED) { | ||||
|                     mob.despawn(); | ||||
|                     mob.deathTime = System.currentTimeMillis(); | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(Mob.discDroppers.contains(mob)) | ||||
|             return; | ||||
|         float baseRespawnTimer = mob.spawnTime; | ||||
|         float reduction = (100-mob.level) * 0.01f; | ||||
|         float reducedRespawnTime = baseRespawnTimer * (1.0f - reduction); | ||||
|         float respawnTimer = reducedRespawnTime * 1000f; | ||||
|         if (System.currentTimeMillis() > (mob.deathTime + respawnTimer)) { | ||||
|             Zone.respawnQue.add(mob); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForAggro(Mob mob){ | ||||
| 
 | ||||
|         if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){ | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(!mob.BehaviourType.isAgressive) | ||||
|             return; | ||||
| 
 | ||||
|         if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){ | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if(mob.hate_values == null) | ||||
|             mob.hate_values = new HashMap<>(); | ||||
| 
 | ||||
|         if(mob.combatTarget != null) | ||||
|             return; | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, 60f, MBServerStatics.MASK_PLAYER); | ||||
| 
 | ||||
|         if(inRange.isEmpty()){ | ||||
|             mob.setCombatTarget(null); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         //clear out any players who are not in hated range anymore
 | ||||
|         ArrayList<PlayerCharacter> toRemove = new ArrayList<>(); | ||||
|         for(PlayerCharacter pc : mob.hate_values.keySet()){ | ||||
|             if(!inRange.contains(pc)) | ||||
|                 toRemove.add(pc); | ||||
|         } | ||||
|         for(PlayerCharacter pc : toRemove){ | ||||
|             mob.hate_values.remove(pc); | ||||
|         } | ||||
| 
 | ||||
|         //find most hated target
 | ||||
|         PlayerCharacter mostHated = null; | ||||
|         for(AbstractWorldObject awo : inRange){ | ||||
|             PlayerCharacter loadedPlayer = (PlayerCharacter)awo; | ||||
|             if (loadedPlayer == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             //Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
 | ||||
|             if (!loadedPlayer.isAlive()) | ||||
|                 continue; | ||||
| 
 | ||||
|             //Can't see target, skip aggro.
 | ||||
|             if (!mob.canSee(loadedPlayer)) | ||||
|                 continue; | ||||
| 
 | ||||
|             // No aggro for this race type
 | ||||
|             if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType())) | ||||
|                 continue; | ||||
| 
 | ||||
|             //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())) | ||||
|                 continue; | ||||
| 
 | ||||
|             if(mostHated == null) | ||||
|                 mostHated = loadedPlayer; | ||||
| 
 | ||||
|             if(mob.hate_values.containsKey(loadedPlayer)) | ||||
|                 if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated)) | ||||
|                     mostHated = loadedPlayer; | ||||
|         } | ||||
| 
 | ||||
|         if(mostHated != null) | ||||
|             mob.setCombatTarget(mostHated); | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForMovement(Mob mob){ | ||||
| 
 | ||||
|         if(!mob.BehaviourType.canRoam) | ||||
|             return; | ||||
| 
 | ||||
|         if(mob.combatTarget != null){ | ||||
|             //chase player
 | ||||
|             if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) { | ||||
|                 if(mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { | ||||
|                     PlayerCharacter target = (PlayerCharacter)mob.combatTarget; | ||||
|                     if(target.isMoving()){ | ||||
|                         MovementUtilities.aiMove(mob, mob.combatTarget.loc, false); | ||||
|                         return; | ||||
|                     }else{ | ||||
|                         Vector3fImmutable smoothLoc = Vector3fImmutable.getRandomPointOnCircle(mob.combatTarget.loc,mob.getRange() -1); | ||||
|                         MovementUtilities.aiMove(mob, smoothLoc, false); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
|                 MovementUtilities.aiMove(mob, mob.combatTarget.loc, false); | ||||
|             } | ||||
| 
 | ||||
|         }else{ | ||||
|             //patrol
 | ||||
|             if (mob.isMoving()) { | ||||
|                 mob.stopPatrolTime = System.currentTimeMillis(); | ||||
|                 return; | ||||
|             } | ||||
|             if(mob.stopPatrolTime + 5000L < System.currentTimeMillis()) { | ||||
|                 Vector3fImmutable patrolPoint = Vector3fImmutable.getRandomPointOnCircle(mob.bindLoc, 40f); | ||||
|                 MovementUtilities.aiMove(mob, patrolPoint, true); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void CheckForAttack(Mob mob){ | ||||
| 
 | ||||
|         if(mob.isMoving()) | ||||
|             return; | ||||
| 
 | ||||
|         if(mob.getLastAttackTime() > System.currentTimeMillis()) | ||||
|             return; | ||||
| 
 | ||||
|         if (mob.BehaviourType.callsForHelp) | ||||
|             MobCallForHelp(mob); | ||||
| 
 | ||||
|         ItemBase mainHand = mob.getWeaponItemBase(true); | ||||
|         ItemBase offHand = mob.getWeaponItemBase(false); | ||||
| 
 | ||||
|         if(!CombatUtilities.inRangeToAttack(mob,mob.combatTarget)) | ||||
|             return; | ||||
| 
 | ||||
|         InterestManager.setObjectDirty(mob); | ||||
| 
 | ||||
|         if (mainHand == null && offHand == null) { | ||||
|             CombatUtilities.combatCycle(mob, mob.combatTarget, true, null); | ||||
|             int delay = 3000; | ||||
|             mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||
|         } else if (mob.getWeaponItemBase(true) != null) { | ||||
|             int delay = 3000; | ||||
|             CombatUtilities.combatCycle(mob, mob.combatTarget, true, mob.getWeaponItemBase(true)); | ||||
|             mob.setLastAttackTime(System.currentTimeMillis() + delay); | ||||
|         } else if (mob.getWeaponItemBase(false) != null) { | ||||
|             int attackDelay = 3000; | ||||
|             CombatUtilities.combatCycle(mob, mob.combatTarget, false, mob.getWeaponItemBase(false)); | ||||
|             mob.setLastAttackTime(System.currentTimeMillis() + attackDelay); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void MobCallForHelp(Mob mob){ | ||||
|         HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,60f, MBServerStatics.MASK_MOB); | ||||
|         for(AbstractWorldObject awo : mobs){ | ||||
|             Mob responder = (Mob)awo; | ||||
|             if(responder.combatTarget == null) | ||||
|                 if(MovementUtilities.canMove(responder)) | ||||
|                     MovementUtilities.aiMove(responder,mob.loc,false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue