diff --git a/README.md b/README.md index 68f192aa..c83b332d 100644 --- a/README.md +++ b/README.md @@ -20,70 +20,11 @@ The Magicbane Team has wanted to open source Shadowbane for half a decade. We a ## Contributing +- Project is released under an MIT license. Please see the LICENSE file. - Inbound == Outbound. - IntelliJ is the supported IDE. - Write code today see it running on the Magicbane production server tomorrow. -## Project setup +## Support -**Prerequisites**: - -- Git -- IntelliJ -- Java 8 JDK -- Account on the Magicbane [Public Repository](http://repo.magicbane.com) - - -Copy the HTTP link if you haven't yet installed a public key: - -![CopyUrl](https://www.magicbane.com/Development/images/repo.png) - -- Clone the Magicbane public repo to your local machine using the copied URL. - -![CloneURL](https://www.magicbane.com/Development/images/intellij1.png) - -- Under Settings->VersionControl->Git make sure to turn off these two settings. - -![CommitOff](https://www.magicbane.com/Development/images/commit.png) - -- Select the Project Structure settings within the IDE. - -![ProjectStructure](https://www.magicbane.com/Development/images/projectstructure.png) - -- Select Java 8 as the IDE target as shown. - -![Java8](https://www.magicbane.com/Development/images/project.png) - -- Delete and recreate content root pointing at the **Server** directory. -- Make sure the Language Level still reflects Java 8. -- The IDE should now autodetect the cloned source. - -![hmm](https://www.magicbane.com/Development/images/module.png) - -Magicbane currently has the following dependencies. -
- -- [EnumBitSet](https://github.com/claudemartin/enum-bit-set) -- [HikariCP](https://github.com/brettwooldridge/HikariCP) -- [JDA](https://github.com/DV8FromTheWorld/JDA) -- [JodaTime](https://github.com/JodaOrg/joda-time) -- [TinyLog](https://github.com/tinylog-org/tinylog/tree/v1.3) -- [MySqlConnector](https://dev.mysql.com/downloads/connector/j/) - -They are all directly obtainable from a running MagicBox instance. - -``` docker cp magicbox:/usr/share/java/EnumBitSet.jar Dependencies/``` - -Add the jar files as project libraries as shown. - -![Libs](https://www.magicbane.com/Development/images/libraries.png) - -You should now be able to build the game! - -![Build](https://magicbane.com/Development/images/buildproject.png) - -### Next Steps - -You can now move onto the [Development Workflow](http://repo.magicbane.com/MagicBane/Server/wiki/Development-workflow) or [MagicBox Setup](http://repo.magicbane.com/MagicBane/Server/wiki/MagicBox-:-Magicbane-in-a-Box) pages for further information. - -Support is also available through the Magicbane [Discord server](www.magicbane.com). Feel free to stop in and pick Magicbot's brain! \ No newline at end of file +Documentation is available through the Magicbane [Wiki](http://repo.magicbane.com/MagicBane/Server/wiki) and [Discord server](www.magicbane.com). \ No newline at end of file diff --git a/src/discord/MagicBot.java b/src/discord/MagicBot.java index b74cc2a8..8744e3e4 100644 --- a/src/discord/MagicBot.java +++ b/src/discord/MagicBot.java @@ -10,7 +10,6 @@ package discord; import discord.handlers.*; -import engine.Enum; import engine.gameManager.ConfigManager; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; @@ -29,8 +28,6 @@ import org.pmw.tinylog.writers.RollingFileWriter; import javax.security.auth.login.LoginException; import java.io.*; -import java.net.MalformedURLException; -import java.net.URL; import java.util.Arrays; import java.util.EnumSet; import java.util.List; diff --git a/src/engine/Enum.java b/src/engine/Enum.java index 43d8f499..7bfa1d5f 100644 --- a/src/engine/Enum.java +++ b/src/engine/Enum.java @@ -2416,9 +2416,9 @@ public class Enum { public enum CityBoundsType { - GRID(576), - ZONE(640), - SIEGE(814); + GRID(512), + ZONE(576), + SIEGE(1040); public final float extents; diff --git a/src/engine/ai/MobileFSM.java b/src/engine/ai/MobileFSM.java index 4861fa4e..fe6a2aa3 100644 --- a/src/engine/ai/MobileFSM.java +++ b/src/engine/ai/MobileFSM.java @@ -1130,7 +1130,6 @@ public class MobileFSM { } HashMap staticPowers = aiAgent.getMobBase().getStaticPowers(); - if (staticPowers != null && !staticPowers.isEmpty()) { int chance = ThreadLocalRandom.current().nextInt(100); diff --git a/src/engine/ai/MobileFSMManager.java b/src/engine/ai/MobileFSMManager.java index 0529224b..a0458546 100644 --- a/src/engine/ai/MobileFSMManager.java +++ b/src/engine/ai/MobileFSMManager.java @@ -16,8 +16,6 @@ import engine.server.MBServerStatics; import engine.util.ThreadUtils; import org.pmw.tinylog.Logger; -import java.util.HashSet; - public class MobileFSMManager { diff --git a/src/engine/ai/utilities/CombatUtilities.java b/src/engine/ai/utilities/CombatUtilities.java index 60b538b9..32fb1fe5 100644 --- a/src/engine/ai/utilities/CombatUtilities.java +++ b/src/engine/ai/utilities/CombatUtilities.java @@ -15,13 +15,19 @@ import engine.Enum.*; import engine.ai.MobileFSM.STATE; import engine.gameManager.ChatManager; import engine.gameManager.CombatManager; +import engine.gameManager.PowersManager; import engine.math.Vector3fImmutable; import engine.net.DispatchMessage; +import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.TargetedActionMsg; import engine.objects.*; +import engine.powers.ActionsBase; +import engine.powers.PowersBase; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; +import java.util.Map; +import java.util.Random; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; @@ -237,7 +243,6 @@ public class CombatUtilities { speed = agent.getSpeedHandOne(); else speed = agent.getSpeedHandTwo(); - DamageType dt = DamageType.Crush; if (agent.isSiege()) dt = DamageType.Siege; @@ -271,15 +276,85 @@ public class CombatUtilities { int passiveAnim = CombatManager.getSwingAnimation(wb, null,mainHand); if(canSwing(agent)) { - if(triggerDefense(agent,target)) - swingIsMiss(agent,target, passiveAnim); - else if(triggerDodge(agent,target)) - swingIsDodge(agent,target, passiveAnim); - else if(triggerParry(agent,target)) - swingIsParry(agent,target, passiveAnim); - else if(triggerBlock(agent,target)) - swingIsBlock(agent,target, passiveAnim); + if(triggerDefense(agent,target)) { + swingIsMiss(agent, target, passiveAnim); + return; + } + else if(triggerDodge(agent,target)) { + swingIsDodge(agent, target, passiveAnim); + return; + } + else if (triggerParry(agent, target)){ + swingIsParry(agent, target, passiveAnim); + + return; + } + else if(triggerBlock(agent,target)) { + swingIsBlock(agent, target, passiveAnim); + return; + } else + //check for a cast here? + + //agent.mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(agent.getMobBaseID()); + + if(agent.mobPowers.size() > 0 && agent.mobPowers != null) + { + //get cast chance 33% cast 67% mele + int random = ThreadLocalRandom.current().nextInt(agent.mobPowers.size() * 10); + //allow casting of spell + if(random <= agent.mobPowers.size()) + { + int powerToken; + int powerRank; + //cast a spell + Map entries = agent.mobPowers; + int count = 0; + for(Map.Entry entry : entries.entrySet()) + { + count += 1; + if(count == random) + { + powerToken = entry.getKey(); + //powerRank = entry.getValue(); + switch(agent.getLevel()) + { + default: + powerRank = 1; + break; + case 10: + powerRank = 5; + break; + case 20: + powerRank = 10; + break; + case 30: + powerRank = 15; + break; + case 40: + powerRank = 25; + break; + case 50: + powerRank = 30; + break; + case 60: + powerRank = 35; + break; + case 70: + powerRank = 40; + break; + } + //System.out.println(agent.getMobBase().getFirstName() + " is casting: " + PowersManager.getPowerByToken(powerToken).skillName); + PowersManager.applyPower(agent,target,target.getLoc(),powerToken,powerRank, false); + //PerformActionMsg msg = new PerformActionMsg(); + //PowersManager.sendPowerMsg((PlayerCharacter)target,0,msg); + //return; + } + } + return; + } + } + //finished with casting check swingIsDamage(agent,target, determineDamage(agent,target, mainHand, speed, dt), anim); if (agent.getWeaponPower() != null) @@ -380,11 +455,46 @@ public class CombatUtilities { public static float determineDamage(Mob agent,AbstractWorldObject target, boolean mainHand, float speed, DamageType dt) { float min = (mainHand) ? agent.getMinDamageHandOne() : agent.getMinDamageHandTwo(); - float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo();; + float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo(); + if(agent.isSummonedPet() == true) + { + min = 40 * (1 + (agent.getLevel()/10)); + max = 60 * (1 + (agent.getLevel()/8)); + //check if we have powers to cast + if(agent.mobPowers.isEmpty() == false) { + //check for power usage + Random random = new Random(); + int value = random.nextInt(0 + (agent.mobPowers.size() + (agent.mobPowers.size() * 5))) + 0; + if (value <= agent.mobPowers.size()) + { + //do power + int powerId = agent.mobPowers.get(value); + PowersManager.runPowerAction(agent,target,target.getLoc(),new ActionsBase(),40, PowersManager.getPowerByToken(powerId)); + } + else + { + //do mele damage + float range = max - min; + float damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2; + if (AbstractWorldObject.IsAbstractCharacter(target)) + if (((AbstractCharacter) target).isSit()) + damage *= 2.5f; //increase damage if sitting + + if (AbstractWorldObject.IsAbstractCharacter(target)) + return ((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, damage, 0); + + if (target.getObjectType() == GameObjectType.Building) { + Building building = (Building) target; + Resists resists = building.getResists(); + return damage * (1 - (resists.getResist(dt, 0) / 100)); + } + } + } + } float range = max - min; float damage = min + ((ThreadLocalRandom.current().nextFloat()*range)+(ThreadLocalRandom.current().nextFloat()*range))/2; - +//DAMAGE FORMULA FOR PET if (AbstractWorldObject.IsAbstractCharacter(target)) if (((AbstractCharacter)target).isSit()) damage *= 2.5f; //increase damage if sitting @@ -404,10 +514,7 @@ public class CombatUtilities { public static boolean RunAIRandom(){ int random = ThreadLocalRandom.current().nextInt(4); - - if (random == 0) - return true; - - return false; + + return random == 0; } } diff --git a/src/engine/db/archive/DataWarehouse.java b/src/engine/db/archive/DataWarehouse.java index 3947d72d..5483e18b 100644 --- a/src/engine/db/archive/DataWarehouse.java +++ b/src/engine/db/archive/DataWarehouse.java @@ -39,7 +39,7 @@ public class DataWarehouse implements Runnable { // If WarehousePush is disabled // then early exit - if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equals("false")) { + if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equalsIgnoreCase("false")) { Logger.info("Warehouse Remote Connection disabled along with push"); return; } diff --git a/src/engine/gameManager/ConfigManager.java b/src/engine/gameManager/ConfigManager.java index 38e6c8f0..16768e87 100644 --- a/src/engine/gameManager/ConfigManager.java +++ b/src/engine/gameManager/ConfigManager.java @@ -20,6 +20,7 @@ import org.pmw.tinylog.Logger; import java.util.HashMap; import java.util.Map; +import java.util.regex.Pattern; public enum ConfigManager { @@ -47,6 +48,8 @@ public enum ConfigManager { MB_LOGIN_PORT, MB_LOGIN_AUTOREG, + MB_LOGIN_FNAME_REGEX, + MB_MAJOR_VER, MB_MINOR_VER, @@ -87,6 +90,7 @@ public enum ConfigManager { public static NetMsgHandler handler; public static WorldServer worldServer; public static LoginServer loginServer; + public static Map regex = new HashMap<>(); // Called at bootstrap: ensures that all config values are loaded. @@ -99,9 +103,15 @@ public enum ConfigManager { Logger.info(configSetting.name() + ":" + configSetting.getValue()); else { Logger.error("Missing Config: " + configSetting.name()); + Logger.error("This codebase requires >= MagicBox v1.3"); + Logger.error("docker pull magicbane/magicbox:latest"); return false; } + // compile regex here + + regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue())); + return true; } diff --git a/src/engine/gameManager/MaintenanceManager.java b/src/engine/gameManager/MaintenanceManager.java index 35185ebd..89ef12a3 100644 --- a/src/engine/gameManager/MaintenanceManager.java +++ b/src/engine/gameManager/MaintenanceManager.java @@ -349,7 +349,7 @@ public enum MaintenanceManager { // Run maintenance on player buildings - if ((boolean) ConfigManager.MB_WORLD_MAINTENANCE.getValue().equals("true")) + if ((boolean) ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true")) processBuildingMaintenance(); else Logger.info("Maintenance Costings: DISABLED"); diff --git a/src/engine/gameManager/MovementManager.java b/src/engine/gameManager/MovementManager.java index b66ba50a..60785270 100644 --- a/src/engine/gameManager/MovementManager.java +++ b/src/engine/gameManager/MovementManager.java @@ -15,16 +15,11 @@ import engine.Enum.SourceType; import engine.InterestManagement.InterestManager; import engine.InterestManagement.WorldGrid; import engine.exception.MsgSendException; -import engine.job.JobContainer; -import engine.job.JobScheduler; -import engine.jobs.ChangeAltitudeJob; -import engine.jobs.FlightJob; import engine.math.Bounds; import engine.math.Vector3f; import engine.math.Vector3fImmutable; import engine.net.DispatchMessage; import engine.net.client.ClientConnection; -import engine.net.client.msg.ChangeAltitudeMsg; import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.TeleportToPointMsg; import engine.net.client.msg.UpdateStateMsg; @@ -339,61 +334,7 @@ public enum MovementManager { } - //Update for when the character is in flight - public static void updateFlight(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) { - if (pc == null) - return; - - // clear flight timer job as we are about to update stuff and submit a new job - pc.clearTimer(flightTimerJobName); - - if (!pc.isActive()) { - pc.setAltitude(0); - pc.setDesiredAltitude(0); - pc.setTakeOffTime(0); - return; - } - - // Check to see if we are mid height change - JobContainer cjc = pc.getTimers().get(changeAltitudeTimerJobName); - if (cjc != null) { - addFlightTimer(pc, msg, MBServerStatics.FLY_FREQUENCY_MS); - return; - } - - // Altitude is zero, do nothing - if (pc.getAltitude() < 1) - return; - //make sure player is still allowed to fly - boolean canFly = false; - PlayerBonuses bonus = pc.getBonuses(); - - if (bonus != null && !bonus.getBool(ModType.NoMod, SourceType.Fly) && bonus.getBool(ModType.Fly, SourceType.None) && pc.isAlive()) - canFly = true; - - // if stam less that 2 - time to force a landing - if (pc.getStamina() < 10f || !canFly) { - - // dont call stop movement here as we want to - // preserve endloc - //pc.stopMovement(); - // sync world location - pc.setLoc(pc.getLoc()); - // force a landing - msg.setStartAlt(pc.getAltitude()); - msg.setTargetAlt(0); - msg.setAmountToMove(pc.getAltitude()); - msg.setUp(false); - DispatchMessage.dispatchMsgToInterestArea(pc, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); - MovementManager.addChangeAltitudeTimer(pc, msg.getStartAlt(), msg.getTargetAlt(), (int) (MBServerStatics.HEIGHT_CHANGE_TIMER_MS * pc.getAltitude())); - pc.setAltitude(msg.getStartAlt() - 10); - - } else //Add a new flight timer to check stam / force land - if (pc.getAltitude() > 0) - addFlightTimer(pc, msg, MBServerStatics.FLY_FREQUENCY_MS); - - } public static void finishChangeAltitude(AbstractCharacter ac, float targetAlt) { @@ -529,27 +470,6 @@ public enum MovementManager { member.setEndLoc(destination); } } - - //Getting rid of flgith timer. - - public static void addFlightTimer(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) { - if (pc == null || pc.getTimers() == null) - return; - if (!pc.getTimers().containsKey(flightTimerJobName)) { - FlightJob ftj = new FlightJob(pc, msg, duration); - JobContainer jc = JobScheduler.getInstance().scheduleJob(ftj, duration); - pc.getTimers().put(flightTimerJobName, jc); - } - } - - public static void addChangeAltitudeTimer(PlayerCharacter pc, float startAlt, float targetAlt, int duration) { - if (pc == null || pc.getTimers() == null) - return; - ChangeAltitudeJob catj = new ChangeAltitudeJob(pc, startAlt, targetAlt); - JobContainer jc = JobScheduler.getInstance().scheduleJob(catj, duration); - pc.getTimers().put(changeAltitudeTimerJobName, jc); - } - public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc, Regions region) { @@ -557,15 +477,10 @@ public enum MovementManager { if (targetLoc == null) return; - Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc()); - - + teleporter.stopMovement(targetLoc); - teleporter.setRegion(region); - - //mobs ignore region sets for now. if (teleporter.getObjectType().equals(GameObjectType.Mob)){ @@ -588,17 +503,11 @@ public enum MovementManager { public static void translocateToObject(AbstractCharacter teleporter, AbstractWorldObject worldObject) { - - Vector3fImmutable targetLoc = teleporter.getLoc(); Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc()); - teleporter.stopMovement(teleporter.getLoc()); - - - - + teleporter.stopMovement(teleporter.getLoc()); //mobs ignore region sets for now. if (teleporter.getObjectType().equals(GameObjectType.Mob)){ @@ -609,6 +518,7 @@ public enum MovementManager { DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); return; } + boolean collide = false; int maxFloor = -1; int buildingID = 0; @@ -619,6 +529,7 @@ public enum MovementManager { if (collide) break; } + if (!collide) { teleporter.setInBuildingID(0); teleporter.setInBuilding(-1); @@ -633,7 +544,6 @@ public enum MovementManager { } } - TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1); //we shouldnt need to send teleport message to new area, as loadjob should pick it up. // DispatchMessage.dispatchMsgToInterestArea(teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); diff --git a/src/engine/jobs/FlightJob.java b/src/engine/jobs/FlightJob.java deleted file mode 100644 index 1bd9366c..00000000 --- a/src/engine/jobs/FlightJob.java +++ /dev/null @@ -1,40 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.jobs; - -import engine.gameManager.MovementManager; -import engine.job.AbstractScheduleJob; -import engine.net.client.msg.ChangeAltitudeMsg; -import engine.objects.PlayerCharacter; - -public class FlightJob extends AbstractScheduleJob { - - private final PlayerCharacter pc; - private final ChangeAltitudeMsg msg; - private final int duration; - - public FlightJob(PlayerCharacter pc, ChangeAltitudeMsg msg, int duration) { - super(); - this.msg = msg; - this.duration = duration; - this.pc = pc; - } - - @Override - protected void doJob() { - if (this.pc != null && this.msg != null) - MovementManager.updateFlight(pc, msg, duration); - } - - @Override - protected void _cancelJob() { - } - -} diff --git a/src/engine/net/client/handlers/AbandonAssetMsgHandler.java b/src/engine/net/client/handlers/AbandonAssetMsgHandler.java index 111a2319..648b5e87 100644 --- a/src/engine/net/client/handlers/AbandonAssetMsgHandler.java +++ b/src/engine/net/client/handlers/AbandonAssetMsgHandler.java @@ -92,7 +92,23 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler { // Trees require special handling beyond an individual building if ((building.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)) + { + // CHECK IF GUILD HAS A BANE DROPPED + City city = ZoneManager.getCityAtLocation(building.getLoc()); + if(city.getGuild().getSubGuildList().isEmpty() == false) + { + //nations cant abandon their tree + ErrorPopupMsg.sendErrorMsg(player, "Nations Cannot Abandon Their Capital!"); + return true; + } + if(Bane.getBaneByAttackerGuild(city.getGuild()) != null) + { + ErrorPopupMsg.sendErrorMsg(player, "You Cannot Abandon Your Tree With An Active Siege!"); + return true; + } + AbandonAllCityObjects(player, building); + } else AbandonSingleAsset(player, building); diff --git a/src/engine/net/client/handlers/DestroyBuildingHandler.java b/src/engine/net/client/handlers/DestroyBuildingHandler.java index 7e53d1be..d26723ee 100644 --- a/src/engine/net/client/handlers/DestroyBuildingHandler.java +++ b/src/engine/net/client/handlers/DestroyBuildingHandler.java @@ -8,10 +8,8 @@ import engine.gameManager.BuildingManager; import engine.net.client.ClientConnection; import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.DestroyBuildingMsg; -import engine.objects.Blueprint; -import engine.objects.Building; -import engine.objects.City; -import engine.objects.PlayerCharacter; +import engine.net.client.msg.ErrorPopupMsg; +import engine.objects.*; /* * @Author: @@ -43,7 +41,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { Blueprint blueprint; blueprint = building.getBlueprint(); - + City city = building.getCity(); // Can't destroy buildings without a blueprint. if (blueprint == null) @@ -57,7 +55,11 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { if (!BuildingManager.PlayerCanControlNotOwner(building, pc)) return true; - +Bane bane = city.getBane(); +if(bane.getSiegePhase() == Enum.SiegePhase.WAR && bane != null) { + ErrorPopupMsg.sendErrorPopup(pc, 171); + return true; +} // Can't destroy a tree of life if (blueprint.getBuildingGroup() == BuildingGroup.TOL) return true; @@ -71,15 +73,12 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { if (blueprint.getBuildingGroup() == BuildingGroup.RUNEGATE) return true; - +//stop if active siege // Turn off spire if destoying if (blueprint.getBuildingGroup() == BuildingGroup.SPIRE) building.disableSpire(true); if (blueprint.getBuildingGroup() == BuildingGroup.WAREHOUSE) { - - City city = building.getCity(); - if (city != null) city.setWarehouseBuildingID(0); } diff --git a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java index 6b4c1c84..d7b12aef 100644 --- a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java +++ b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java @@ -92,7 +92,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if (buildingList == null) { Logger.error("Player " + playerCharacter.getCombinedName() - + " null building list on deed use"); + + " null building list on deed use"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); closePlaceAssetWindow(origin); return true; @@ -115,7 +115,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if (buildingBlueprint == null) { Logger.error("Player " + playerCharacter.getCombinedName() - + " null blueprint UUID: " + buildingList.getBlueprintUUID() + " on deed use"); + + " null blueprint UUID: " + buildingList.getBlueprintUUID() + " on deed use"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); closePlaceAssetWindow(origin); return true; @@ -130,66 +130,66 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { boolean close = true; lock.writeLock().lock(); - + boolean isSiege = false; try { switch (buildingBlueprint.getBuildingGroup()) { - case TOL: - if (contract == null) - break; - buildingCreated = placeTreeOfLife(playerCharacter, origin, msg); - break; - case WAREHOUSE: - if (contract == null) - break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) - break; - buildingCreated = placeWarehouse(playerCharacter, origin, msg); - break; - case SIEGETENT: - case BULWARK: - if (contract == null) - break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) - break; - buildingCreated = placeSiegeEquip(playerCharacter, origin, msg); - break; - case SPIRE: - if (contract == null) + case TOL: + if (contract == null) + break; + buildingCreated = placeTreeOfLife(playerCharacter, origin, msg); break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + case WAREHOUSE: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeWarehouse(playerCharacter, origin, msg); break; - buildingCreated = placeSpire(playerCharacter, origin, msg); - break; - case SHRINE: - if (contract == null) + case SIEGETENT: + case BULWARK: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeSiegeEquip(playerCharacter, origin, msg); break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + case SPIRE: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeSpire(playerCharacter, origin, msg); break; - buildingCreated = placeShrine(playerCharacter, origin, msg); - break; - case BARRACK: - if (contract == null) + case SHRINE: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeShrine(playerCharacter, origin, msg); break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + case BARRACK: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeBarrack(playerCharacter, origin, msg); break; - buildingCreated = placeBarrack(playerCharacter, origin, msg); - break; - case WALLSTRAIGHT: - case WALLCORNER: - case SMALLGATE: - case ARTYTOWER: - case WALLSTAIRS: - buildingCreated = placeCityWalls(playerCharacter, origin, msg); - close = false; - break; - default: - if (contract == null) + case WALLSTRAIGHT: + case WALLCORNER: + case SMALLGATE: + case ARTYTOWER: + case WALLSTAIRS: + buildingCreated = placeCityWalls(playerCharacter, origin, msg); + close = false; break; - if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + default: + if (contract == null) + break; + if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) + break; + buildingCreated = placeSingleBuilding(playerCharacter, origin, msg); break; - buildingCreated = placeSingleBuilding(playerCharacter, origin, msg); - break; } } catch (Exception e) { Logger.error("PlaceAssetHandler", e.getMessage()); @@ -230,7 +230,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { buildingList = msg.getFirstPlacementInfo(); serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); - // Early exit if something went horribly wrong // with locating the current or zone @@ -346,125 +345,125 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { City attackerCity = null; if (bane != null) attackerCity = bane.getCity(); - + if (attackerCity != null) if (buildingList.getLoc().isInsideCircle(attackerCity.getLoc(), Enum.CityBoundsType.SIEGE.extents)) - serverCity = attackerCity; + serverCity = attackerCity; } //no city found for attacker city, //check if defender city - + if (serverCity == null){ if (player.getGuild().getOwnedCity() != null) if (buildingList.getLoc().isInsideCircle(player.getGuild().getOwnedCity().getLoc(), Enum.CityBoundsType.SIEGE.extents)) serverCity = player.getGuild().getOwnedCity(); } - - + + if ((serverCity != null) && - (serverCity.getBane() != null)) { + (serverCity.getBane() != null)) { // Set the server zone to the city zone in order to account for being inside // the siege bounds buffer area serverZone = serverCity.getParent(); - if ((player.getGuild().equals(serverCity.getBane().getOwner().getGuild()) == false) - && (player.getGuild().equals(serverCity.getGuild()) == false)) { - PlaceAssetMsg.sendPlaceAssetError(origin, 54, ""); // Must belong to attacker or defender - return false; - } + if ((player.getGuild().equals(serverCity.getBane().getOwner().getGuild()) == false) + && (player.getGuild().equals(serverCity.getGuild()) == false)) { + PlaceAssetMsg.sendPlaceAssetError(origin, 54, ""); // Must belong to attacker or defender + return false; + } } - + // cant place siege equipment off city zone. - - + + // Create the siege Building - siegeBuilding = createStructure(player, msg.getFirstPlacementInfo(), serverZone); - if (serverCity == null) - return true; - // Oops something went really wrong + siegeBuilding = createStructure(player, msg.getFirstPlacementInfo(), serverZone); + if (serverCity == null) + return true; + // Oops something went really wrong - if (siegeBuilding == null) - return false; + if (siegeBuilding == null) + return false; + + + if (serverCity.getBane() == null) + return true; - - if (serverCity.getBane() == null) - return true; - // If there is an bane placed, we protect 2x the stone rank's worth of attacker assets // and 1x the tree rank's worth of assets automatically - - HashSet awoList = WorldGrid.getObjectsInRangePartial(serverCity, 1000, MBServerStatics.MASK_BUILDING); - - + HashSet awoList = WorldGrid.getObjectsInRangePartial(serverCity, 1000, MBServerStatics.MASK_BUILDING); + + + for (AbstractWorldObject awo : awoList) { Building building = (Building)awo; - + if (building.getBlueprint() != null) if (!building.getBlueprint().isSiegeEquip()) continue; if (!building.getLoc().isInsideCircle(serverCity.getLoc(), Enum.CityBoundsType.SIEGE.extents)) continue; - + if (building.getGuild() == null) continue; - + if (building.getGuild().isErrant()) continue; - + if (!building.getGuild().equals(serverCity.getGuild()) && !building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) continue; - // Only count auto protected buildings - if (building.getProtectionState() != ProtectionState.PROTECTED) - continue; + // Only count auto protected buildings + if (building.getProtectionState() != ProtectionState.PROTECTED) + continue; + + if (building.getGuild().equals(serverCity.getGuild())) + numDefenderBuildings++; + else + if (building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) + numAttackerBuildings++; - if (building.getGuild().equals(serverCity.getGuild())) - numDefenderBuildings++; - else - if (building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) - numAttackerBuildings++; - } // Validate bane limits on siege assets if (serverCity.getBane() != null) - if ((player.getGuild().equals(serverCity.getBane().getOwner().getGuild())) && - (numAttackerBuildings >= serverCity.getBane().getStone().getRank() * 2)) { - return true; - } + if ((player.getGuild().equals(serverCity.getBane().getOwner().getGuild())) && + (numAttackerBuildings >= serverCity.getBane().getStone().getRank() * 2)) { + return true; + } if ((player.getGuild().equals(serverCity.getGuild())) && (numDefenderBuildings >= serverCity.getTOL().getRank())) { return true; } - - + + // passes validation: can assign auto-protection to war asset - + if (serverCity.getBane() != null) - if (serverCity.isLocationOnCityGrid(siegeBuilding.getBounds())) - if (player.getGuild().equals(serverCity.getBane().getOwner().getGuild())) - return true; - - + if (serverCity.isLocationOnCityGrid(siegeBuilding.getBounds())) + if (player.getGuild().equals(serverCity.getBane().getOwner().getGuild())) + return true; + + + + - - siegeBuilding.setProtectionState(ProtectionState.PROTECTED); // No bane placed. We're done! - + return true; } @@ -507,8 +506,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { } Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x, - serverZone.getHeightMap().getInterpolatedTerrainHeight(treeInfo.getLoc()), - treeInfo.getLoc().z); + serverZone.getHeightMap().getInterpolatedTerrainHeight(treeInfo.getLoc()), + treeInfo.getLoc().z); cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(), serverRealm.getRealmID(), @@ -527,18 +526,18 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { for (AbstractGameObject gameObject : cityObjects) { switch (gameObject.getObjectType()) { - case Building: - treeObject = (Building) gameObject; - treeObject.runAfterLoad(); - break; - case City: - cityObject = (City) gameObject; - break; - case Zone: - cityZone = (Zone) gameObject; - break; - default: - // log some error here? *** Refactor + case Building: + treeObject = (Building) gameObject; + treeObject.runAfterLoad(); + break; + case City: + cityObject = (City) gameObject; + break; + case Zone: + cityZone = (Zone) gameObject; + break; + default: + // log some error here? *** Refactor } } @@ -562,7 +561,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { ZoneManager.addZone(cityZone.getObjectUUID(), cityZone); ZoneManager.addPlayerCityZone(cityZone); serverZone.addNode(cityZone); - + cityZone.generateWorldAltitude(); cityObject.setParent(cityZone); @@ -708,7 +707,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { } blueprint = Blueprint.getBlueprint(msg.getFirstPlacementInfo().getBlueprintUUID()); - + if (blueprint == null){ return false; } @@ -716,7 +715,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { for (Building building : serverZone.zoneBuildingSet) { if (building.getBlueprint() == null) continue; - + if (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE) { if (building.getBlueprintUUID() == blueprint.getMeshForRank(0)) { PlaceAssetMsg.sendPlaceAssetError(origin, 43, ""); // "shrine of that type exists" @@ -811,13 +810,13 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if (serverZone == null) return false; - - - if (player.getCharItemManager().getGoldTrading() > 0){ - ErrorPopupMsg.sendErrorPopup(player, 195); - return false; - } - + + + if (player.getCharItemManager().getGoldTrading() > 0){ + ErrorPopupMsg.sendErrorPopup(player, 195); + return false; + } + // Method checks validation conditions arising when placing // buildings. Player must be on a city grid, must be @@ -956,7 +955,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { // Method validates the location we have selected for our new city private static boolean validateTreeOfLifePlacement(PlayerCharacter playerCharacter, Realm serverRealm, Zone serverZone, - ClientConnection origin, PlaceAssetMsg msg) { + ClientConnection origin, PlaceAssetMsg msg) { PlacementInfo placementInfo = msg.getFirstPlacementInfo(); @@ -995,7 +994,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if ( (realmType.equals(RealmType.MAELSTROM)) || - (realmType.equals(RealmType.OBLIVION))) { + (realmType.equals(RealmType.OBLIVION))) { PlaceAssetMsg.sendPlaceAssetError(origin, 57, playerCharacter.getName()); // No building may be placed within this territory return false; } @@ -1107,7 +1106,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { float buildingRotation = buildingInfo.getRot().y; float vendorRotation = buildingInfo.getW(); - + ArrayList shrineObjects = DbManager.ShrineQueries.CREATE_SHRINE( currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0, @@ -1121,20 +1120,20 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { for (AbstractGameObject ago : shrineObjects) { switch (ago.getObjectType()) { - case Building: - newMesh = (Building) ago; - newMesh.runAfterLoad(); - newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); - MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); - WorldGrid.addObject(newMesh, player); - break; - case Shrine: - newShrine = (Shrine) ago; - newShrine.getShrineType().addShrineToServerList(newShrine); - break; - default: - PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); - break; + case Building: + newMesh = (Building) ago; + newMesh.runAfterLoad(); + newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); + MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); + WorldGrid.addObject(newMesh, player); + break; + case Shrine: + newShrine = (Shrine) ago; + newShrine.getShrineType().addShrineToServerList(newShrine); + break; + default: + PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); + break; } } @@ -1172,7 +1171,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { float vendorRotation = buildingInfo.getW(); DateTime completionDate = DateTime.now().plusHours(blueprint.getRankTime(1)); - + newMesh = DbManager.BuildingQueries.CREATE_BUILDING( currentZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getMeshForRank(0), localLoc, 1.0f, blueprint.getMaxHealth(0), ProtectionState.PROTECTED, 0, 0, @@ -1249,6 +1248,85 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { RealmType currentRealm; + if(Blueprint.getBlueprint(placementInfo.getBlueprintUUID()).isSiegeEquip() == false) + { + if (serverZone.isPlayerCity() == false) { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + City city = ZoneManager.getCityAtLocation(placementInfo.getLoc()); + + if (player.getGuild().equals(city.getGuild()) == false) { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + if (city.isLocationOnCityGrid(placementInfo.getLoc()) == false) { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + } + else + { + City city = ZoneManager.getCityAtLocation(placementInfo.getLoc()); + + if(city == null) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + Bane bane = city.getBane(); + //check if player is owner/IC of tree or bane + if (player.getGuild().equals(city.getGuild()) == true) + { + //is from owners guild + if(GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + } + else + { + //is not from owners guild + if(bane == null) + { + //bane was null + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + if(city == null) + { + //city was null + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + //check if player is from siege guild + if(player.getGuild().equals(bane.getOwner().getGuild()) == false) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + + //check if player is GL or IC of the bane guild + if(GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + + //cannot place on grid until bane is live + if(bane.getSiegePhase() != SiegePhase.WAR && city.isLocationOnCityGrid(placementInfo.getLoc()) == true) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + if(city.isLocationWithinSiegeBounds(placementInfo.getLoc()) == false && city.isLocationOnCityZone(placementInfo.getLoc()) == false) + { + PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); + return false; + } + } + } // Retrieve the building details we're placing if (serverZone.isNPCCity() == true) { @@ -1259,7 +1337,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { // Errant guilds cannot place assets if (player.getGuild().getGuildState() == GuildState.Errant) { - PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Only soverign or sworn guilds may place assets."); + PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Only sovereign or sworn guilds may place assets."); + return false; + } + + // Player must be GL or IC of a guild to place buildings. + + if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) { + PlaceAssetMsg.sendPlaceAssetError(origin, 10, ""); // You must be a guild leader return false; } @@ -1282,7 +1367,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if ( (currentRealm.equals(RealmType.MAELSTROM)) || - (currentRealm.equals(RealmType.OBLIVION))) { + (currentRealm.equals(RealmType.OBLIVION))) { PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory return false; } @@ -1373,8 +1458,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { PlaceAssetMsg.sendPlaceAssetError(origin, 9, ""); //You must be a guild member to place this asset return false; } - return true; } - -} +} \ No newline at end of file diff --git a/src/engine/objects/City.java b/src/engine/objects/City.java index f4ed1b52..0d8a4ef1 100644 --- a/src/engine/objects/City.java +++ b/src/engine/objects/City.java @@ -999,11 +999,9 @@ public class City extends AbstractWorldObject { HashSet currentMemory; PlayerCharacter player; - // Gather current list of players within a distance defined by the x extent of the - // city zone. As we want to grab all players with even a remote possibility of - // being in the zone, we might have to increase this distance. + // Gather current list of players within a distance defined by the seige bounds - currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, this.parentZone.getBounds().getHalfExtents().x * 1.41421356237, MBServerStatics.MASK_PLAYER); + currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.SIEGE.extents, MBServerStatics.MASK_PLAYER); currentMemory = new HashSet<>(); for (AbstractWorldObject playerObject : currentPlayers) { @@ -1019,9 +1017,8 @@ public class City extends AbstractWorldObject { if (_playerMemory.contains(player.getObjectUUID())) continue; - if (!this.isLocationOnCityZone(player.getLoc())) + if (!this.isLocationWithinSiegeBounds(player.getLoc())) continue; - // Apply safehold affect to player if needed if ((this.isSafeHold == 1)) @@ -1065,7 +1062,8 @@ public class City extends AbstractWorldObject { player = PlayerCharacter.getFromCache(playerUUID); - if (this.isLocationOnCityZone(player.getLoc())) + + if (this.isLocationWithinSiegeBounds(player.getLoc())) continue; // Remove players safezone status if warranted diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index dfd30590..c54af843 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -111,7 +111,7 @@ public class Mob extends AbstractIntelligenceAgent { public boolean despawned = false; public Vector3fImmutable destination = Vector3fImmutable.ZERO; public Vector3fImmutable localLoc = Vector3fImmutable.ZERO; - + public HashMap mobPowers; /** * No Id Constructor */ @@ -365,6 +365,7 @@ public class Mob extends AbstractIntelligenceAgent { this.setObjectTypeMask(MBServerStatics.MASK_PET | this.getTypeMasks()); if (ConfigManager.serverType.equals(ServerType.LOGINSERVER)) this.setLoc(this.getLoc()); + mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(this.getMobBaseID()); } if (!isPet && this.contract == null) { this.level = (short) this.mobBase.getLevel(); @@ -393,10 +394,10 @@ public class Mob extends AbstractIntelligenceAgent { //TODO set these correctly later this.rangeHandOne = 8; this.rangeHandTwo = -1; - this.minDamageHandOne = 0; - this.maxDamageHandOne = 0; - this.minDamageHandTwo = 1; - this.maxDamageHandTwo = 4; + this.minDamageHandOne = 0; + this.maxDamageHandOne = 0; + this.minDamageHandTwo = 1; + this.maxDamageHandTwo = 4; this.atrHandOne = 300; this.atrHandOne = 300; this.defenseRating = (short) this.mobBase.getDefenseRating(); @@ -2201,7 +2202,7 @@ public class Mob extends AbstractIntelligenceAgent { } catch(Exception e){ Logger.error( e.getMessage()); } - + mobPowers = DbManager.MobBaseQueries.LOAD_STATIC_POWERS(this.getMobBaseID()); if (this.equip == null) { Logger.error("Null equipset returned for uuid " + currentID); this.equip = new HashMap<>(0); diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index ef6f623a..c7a55f57 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -4781,8 +4781,11 @@ public void dismissNecroPets() { }finally{ this.updateLock.writeLock().unlock(); } - } + //temp removal + if(AbstractCharacter.CanFly(this) == false && this.altitude > 0) + GroundPlayer(this); + } } @Override public void updateFlight() { diff --git a/src/engine/powers/poweractions/AbstractPowerAction.java b/src/engine/powers/poweractions/AbstractPowerAction.java index f7b1914f..20911147 100644 --- a/src/engine/powers/poweractions/AbstractPowerAction.java +++ b/src/engine/powers/poweractions/AbstractPowerAction.java @@ -76,75 +76,108 @@ public abstract class AbstractPowerAction { int token = DbManager.hasher.SBStringHash(IDString); //cache token, used for applying effects. PowersManager.ActionTokenByIDString.put(IDString, token); - if (type.equals("ApplyEffect")) - apa = new ApplyEffectPowerAction(rs, effects); - else if (type.equals("ApplyEffects")) - apa = new ApplyEffectsPowerAction(rs, effects); - else if (type.equals("DeferredPower")) - apa = new DeferredPowerPowerAction(rs, effects); - else if (type.equals("DamageOverTime")) - apa = new DamageOverTimePowerAction(rs, effects); - else if (type.equals("Peek")) - apa = new PeekPowerAction(rs); - else if (type.equals("Charm")) - apa = new CharmPowerAction(rs); - else if (type.equals("Fear")) - apa = new FearPowerAction(rs); - else if (type.equals("Confusion")) - apa = new ConfusionPowerAction(rs); - else if (type.equals("RemoveEffect")) - apa = new RemoveEffectPowerAction(rs); - else if (type.equals("Track")) - apa = new TrackPowerAction(rs, effects); - else if (type.equals("DirectDamage")) - apa = new DirectDamagePowerAction(rs, effects); - else if (type.equals("Transform")) - apa = new TransformPowerAction(rs, effects); - else if (type.equals("CreateMob")) - apa = new CreateMobPowerAction(rs); - else if (type.equals("Invis")) - apa = new InvisPowerAction(rs, effects); - else if (type.equals("ClearNearbyAggro")) - apa = new ClearNearbyAggroPowerAction(rs); - else if (type.equals("MobRecall")) - apa = new MobRecallPowerAction(rs); - else if (type.equals("SetItemFlag")) - apa = new SetItemFlagPowerAction(rs); - else if (type.equals("SimpleDamage")) - apa = new SimpleDamagePowerAction(rs); - else if (type.equals("TransferStatOT")) - apa = new TransferStatOTPowerAction(rs, effects); - else if (type.equals("TransferStat")) - apa = new TransferStatPowerAction(rs, effects); - else if (type.equals("Teleport")) - apa = new TeleportPowerAction(rs); - else if (type.equals("TreeChoke")) - apa = new TreeChokePowerAction(rs); - else if (type.equals("Block")) - apa = new BlockPowerAction(rs); - else if (type.equals("Resurrect")) - apa = new ResurrectPowerAction(rs); - else if (type.equals("ClearAggro")) - apa = new ClearAggroPowerAction(rs); - else if (type.equals("ClaimMine")) - apa = new ClaimMinePowerAction(rs); - else if (type.equals("Recall")) - apa = new RecallPowerAction(rs); - else if (type.equals("SpireDisable")) - apa = new SpireDisablePowerAction(rs); - else if (type.equals("Steal")) - apa = new StealPowerAction(rs); - else if (type.equals("Summon")) - apa = new SummonPowerAction(rs); - else if (type.equals("RunegateTeleport")) - apa = new RunegateTeleportPowerAction(rs); - else if (type.equals("RunegateTeleport")) - apa = new RunegateTeleportPowerAction(rs); - else if (type.equals("OpenGate")) - apa = new OpenGatePowerAction(rs); - else { - Logger.error("valid type not found for poweraction of ID" + rs.getInt("ID")); - continue; + apa = null; + switch (type) + { + default: + Logger.error("valid type not found for poweraction of ID" + rs.getInt("ID")); + break; + case "ApplyEffect": + apa = new ApplyEffectPowerAction(rs, effects); + break; + case "ApplyEffects": + apa = new ApplyEffectsPowerAction(rs, effects); + break; + case "DeferredPower": + apa = new DeferredPowerPowerAction(rs, effects); + break; + case "DamageOverTime": + apa = new DamageOverTimePowerAction(rs, effects); + break; + case "Peek": + apa = new PeekPowerAction(rs); + break; + case "Charm": + apa = new CharmPowerAction(rs); + break; + case "Fear": + apa = new FearPowerAction(rs); + break; + case "Confusion": + apa = new ConfusionPowerAction(rs); + break; + case "RemoveEffect": + apa = new RemoveEffectPowerAction(rs); + break; + case "Track": + apa = new TrackPowerAction(rs, effects); + break; + case "DirectDamage": + apa = new DirectDamagePowerAction(rs, effects); + break; + case "Transform": + apa = new TransformPowerAction(rs, effects); + break; + case "CreateMob": + apa = new CreateMobPowerAction(rs); + break; + case "Invis": + apa = new InvisPowerAction(rs, effects); + break; + case "ClearNearbyAggro": + apa = new ClearNearbyAggroPowerAction(rs); + break; + case "MobRecall": + apa = new MobRecallPowerAction(rs); + break; + case "SetItemFlag": + apa = new SetItemFlagPowerAction(rs); + break; + case "SimpleDamage": + apa = new SimpleDamagePowerAction(rs); + break; + case "TransferStatOT": + apa = new TransferStatOTPowerAction(rs, effects); + break; + case "TransferStat": + apa = new TransferStatPowerAction(rs, effects); + break; + case "Teleport": + apa = new TeleportPowerAction(rs); + break; + case "TreeChoke": + apa = new TreeChokePowerAction(rs); + break; + case "Block": + apa = new BlockPowerAction(rs); + break; + case "Resurrect": + apa = new ResurrectPowerAction(rs); + break; + case "ClearAggro": + apa = new ClearAggroPowerAction(rs); + break; + case "ClaimMine": + apa = new ClaimMinePowerAction(rs); + break; + case "Recall": + apa = new RecallPowerAction(rs); + break; + case "SpireDisable": + apa = new SpireDisablePowerAction(rs); + break; + case "Steal": + apa = new StealPowerAction(rs); + break; + case "Summon": + apa = new SummonPowerAction(rs); + break; + case "RunegateTeleport": + apa = new RunegateTeleportPowerAction(rs); + break; + case "OpenGate": + apa = new OpenGatePowerAction(rs); + break; } powerActions.put(IDString, apa); powerActionsByID.put(apa.UUID, apa); diff --git a/src/engine/server/MBServerStatics.java b/src/engine/server/MBServerStatics.java index 6c2b46fb..31ed073b 100644 --- a/src/engine/server/MBServerStatics.java +++ b/src/engine/server/MBServerStatics.java @@ -124,16 +124,6 @@ public class MBServerStatics { public static final int CHM_THREAD_MED = 2; public static final int CHM_THREAD_LOW = 1; - /* - * LoginServer related - */ - - public static final String PCMajorVer = "1.2.25.5"; - public static final String PCMinorVer = "5.25.5"; - - public static final String MACMajorVer = "1.2.24.3"; - public static final String MACMinorVer = "5.24.3"; - /* * LoginErrorMsg related */ diff --git a/src/engine/server/login/LoginServer.java b/src/engine/server/login/LoginServer.java index b7ad18e9..5a44bd09 100644 --- a/src/engine/server/login/LoginServer.java +++ b/src/engine/server/login/LoginServer.java @@ -169,8 +169,8 @@ public class LoginServer { // Configure the VersionInfoMsgs: - this.versionInfoMessage = new VersionInfoMsg(MBServerStatics.PCMajorVer, - MBServerStatics.PCMinorVer); + this.versionInfoMessage = new VersionInfoMsg(ConfigManager.MB_MAJOR_VER.getValue(), + ConfigManager.MB_MINOR_VER.getValue()); Logger.info("Initializing Database Pool"); initDatabasePool(); diff --git a/src/engine/server/login/LoginServerMsgHandler.java b/src/engine/server/login/LoginServerMsgHandler.java index 36f45917..3fd17ed5 100644 --- a/src/engine/server/login/LoginServerMsgHandler.java +++ b/src/engine/server/login/LoginServerMsgHandler.java @@ -180,7 +180,7 @@ public class LoginServerMsgHandler implements NetMsgHandler { if (account == null) { - if (ConfigManager.MB_LOGIN_AUTOREG.getValue().equals("FALSE")) { + if (ConfigManager.MB_LOGIN_AUTOREG.getValue().equalsIgnoreCase("false")) { this.KickToLogin(MBServerStatics.LOGINERROR_INVALID_USERNAME_PASSWORD, "Could not find account (" + uname + ')', clientConnection); Logger.info("Could not find account (" + uname + ')'); return; diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 371b44f5..c00c0315 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -53,7 +53,9 @@ import org.pmw.tinylog.labelers.TimestampLabeler; import org.pmw.tinylog.policies.StartupPolicy; import org.pmw.tinylog.writers.RollingFileWriter; -import java.io.*; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; import java.net.InetAddress; import java.nio.file.Files; import java.nio.file.Paths; diff --git a/src/engine/util/MiscUtils.java b/src/engine/util/MiscUtils.java index 550d21f5..03f79ed6 100644 --- a/src/engine/util/MiscUtils.java +++ b/src/engine/util/MiscUtils.java @@ -9,27 +9,19 @@ package engine.util; +import engine.gameManager.ConfigManager; import engine.server.MBServerStatics; -import java.util.regex.Pattern; - public class MiscUtils { - // no need to recompile these each call, put them in object scope and - // compile just once. - private static final Pattern lastNameRegex = Pattern - .compile("^[A-Za-z][-'A-Za-z\\x20]*$"); - private static final Pattern firstNameRegex = Pattern - .compile("^[A-Za-z]+$"); - public static boolean checkIfFirstNameInvalid(String firstName) { if ((firstName == null) || (firstName.length() == 0) || (firstName.length() > MBServerStatics.MAX_NAME_LENGTH) || (firstName.length() < MBServerStatics.MIN_NAME_LENGTH)) { return true; } - return (!firstNameRegex.matcher(firstName).matches()); + return (!ConfigManager.regex.get(ConfigManager.MB_LOGIN_FNAME_REGEX).matcher(firstName).matches()); } public static boolean checkIfLastNameInvalid(String lastName) { @@ -43,52 +35,4 @@ public class MiscUtils { // empty last names are fine, return false return false; } - - public static String getCallingMethodName() { - StackTraceElement e[] = Thread.currentThread().getStackTrace(); - int numElements = e.length; - - if (numElements < 1) { - return "NoStack"; - } - - if (numElements == 1) { - return e[0].getMethodName(); - } else if (numElements == 2) { - return e[1].getMethodName(); - } else if (numElements == 3) { - return e[2].getMethodName(); - } else { - return e[3].getMethodName(); - } - } - - public static String getCallStackAsString() { - String out = ""; - - StackTraceElement e[] = Thread.currentThread().getStackTrace(); - int numElements = e.length; - - for (int i = (numElements - 1); i > 1; --i) { - - String[] classStack = e[i].getClassName().split("\\."); - String methName = e[i].getMethodName(); - - String className = classStack[classStack.length - 1]; - - if (methName.equals("")) { - methName = className; - } - - out += className + '.' + methName + "()"; - - if (i > 2) { - out += " -> "; - } - - } - - return out; - } - }