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