Compare commits

..

23 Commits

Author SHA1 Message Date
MagicBot c77e7a6190 Check removed 2026-04-26 14:26:18 -04:00
MagicBot 4fde07969b Check removed 2026-04-26 14:06:41 -04:00
MagicBot 2bc7662ccf Handler updated to support fix. 2026-04-26 13:49:37 -04:00
MagicBot ec37634b6a Protocol update. 2026-04-26 13:35:10 -04:00
FatBoy b2bd3b7a92 cancel on take mele damage 2026-02-03 11:51:29 -06:00
FatBoy 461e4e1c3d roollback extra effect cancel on damage 2026-02-03 11:45:47 -06:00
FatBoy 0d1d00e2d1 cancel on take damage for mele dnont flip damage t negatove 2026-02-03 11:33:13 -06:00
FatBoy ec6825d651 cancel on take damage for mele 2026-02-03 11:31:42 -06:00
FatBoy cb561c3b6b validity check for not looking up damage type that doesn't exist 2026-02-03 11:15:24 -06:00
MagicBot cf0f0cf022 Enumeration for server configs. 2026-01-23 11:45:28 -05:00
MagicBot f85673e661 Enumeration for server configs. 2026-01-18 10:08:53 -05:00
MagicBot 84347f8290 statAlt used as offset to terrain. 2026-01-13 14:56:06 -05:00
MagicBot fd2fe92714 Unused methods 2026-01-10 08:45:18 -05:00
MagicBot 955b94eb08 Minor method ordering change 2026-01-10 08:39:13 -05:00
MagicBot a9aa6e9660 Reminder to add power collections later 2026-01-09 13:40:10 -05:00
MagicBot afc080074f Enums needed to support parser. 2026-01-09 13:32:37 -05:00
MagicBot 1039fb1d0b Bonus code added to ConfigManager 2026-01-09 13:26:07 -05:00
MagicBot a955778eed Merge remote-tracking branch 'origin/magicbox-1.5.2.1' into magicbox-1.5.2.1 2026-01-09 13:16:26 -05:00
MagicBot 7717707518 wpak parser added to project 2026-01-09 13:12:40 -05:00
FatBoy 28836a7a4f log null blueprint in destroy city thread 2026-01-08 12:38:42 -06:00
FatBoy 5511dc7899 update lumber hash in mbEnums 2026-01-08 11:53:54 -06:00
FatBoy e5b2247204 disable teleports to cities that are destroyed or errant 2026-01-08 11:52:52 -06:00
FatBoy 0404ca1a94 Allow management of guild mines that are still active 2026-01-08 11:51:12 -06:00
26 changed files with 356 additions and 330 deletions
@@ -58,6 +58,9 @@ public abstract class dbHandlerBase {
int id = rs.getInt(1);
if (id == 39052)
Logger.info(id);
if (DbManager.inCache(localObjectType, id)) {
objectList.add((T) DbManager.getFromCache(localObjectType, id));
} else {
+1 -1
View File
@@ -798,7 +798,7 @@ public enum BuildingManager {
// Attempt to write to database or delete the building
// if we are destroying it.
if (rank < 0)
if (rank == -1)
success = DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
else
success = DbManager.BuildingQueries.updateBuildingRank(building, rank);
+4 -3
View File
@@ -462,11 +462,12 @@ public enum CombatManager {
if (damage > 0) {
if (AbstractCharacter.IsAbstractCharacter(target))
if (AbstractCharacter.IsAbstractCharacter(target)) {
((AbstractCharacter) target).modifyHealth(-damage, attacker, true);
else
((AbstractCharacter) target).cancelOnTakeDamage();
}else {
((Building) target).modifyHealth(-damage, attacker);
}
int attackAnim = getSwingAnimation(null, null, slot);
if (attacker.charItemManager.getEquipped().get(slot) != null) {
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
+5 -6
View File
@@ -11,9 +11,6 @@ package engine.gameManager;
import engine.mbEnums;
import engine.server.login.LoginServer;
import engine.server.world.WorldServer;
import engine.wpak.EffectsParser;
import engine.wpak.PowerActionParser;
import engine.wpak.PowersParser;
import org.pmw.tinylog.Logger;
import java.io.BufferedReader;
@@ -170,9 +167,11 @@ public enum ConfigManager {
Logger.info("Loading WPAK data");
//EffectsParser.parseWpakFile();
//PowersParser.parseWpakFile();
//PowerActionParser.parseWpakFile();
// *** Needs powermanager collection
// defined before activation.
// EffectsParser.parseWpakFile();
// PowersParser.parseWpakFile();
// PowerActionParser.parseWpakFile();
return true;
}
+8 -9
View File
@@ -49,8 +49,15 @@ public enum ForgeManager implements Runnable {
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
@Override
public static void start() {
Thread forgeManager;
forgeManager = new Thread(FORGE_MANAGER);
forgeManager.setName("Forge Manager");
forgeManager.start();
}
@Override
public void run() {
WorkOrder workOrder;
@@ -112,14 +119,6 @@ public enum ForgeManager implements Runnable {
}
}
public static void start() {
Thread forgeManager;
forgeManager = new Thread(FORGE_MANAGER);
forgeManager.setName("Forge Manager");
forgeManager.start();
}
public static int submit(WorkOrder workOrder) {
// Must have a city to roll anything
+5 -29
View File
@@ -31,10 +31,6 @@ import engine.objects.*;
import engine.powers.*;
import engine.powers.poweractions.AbstractPowerAction;
import engine.server.MBServerStatics;
import engine.wpak.EffectsParser;
import engine.wpak.PowerActionParser;
import engine.wpak.PowersParser;
import engine.wpak.data.Effect;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
@@ -116,30 +112,10 @@ public enum PowersManager {
return powerEntries;
}
public static void InitializeEffects(){
// Add EffectsBase
ArrayList<EffectsBase> effectList = new ArrayList<>();
for (Effect entry : EffectsParser.effect_data.values()) {
EffectsBase effectBase = new EffectsBase(entry);
effectList.add(effectBase);
PowersManager.effectsBaseByToken.put(effectBase.getToken(), effectBase);
PowersManager.effectsBaseByIDString.put(effectBase.getIDString(), effectBase);
}
// Add Fail Conditions
EffectsBase.getFailConditions(PowersManager.effectsBaseByIDString);
}
// This pre-loads all powers and effects
public static void InitializePowers() {
EffectsParser.parseWpakFile();
PowersParser.parseWpakFile();
PowerActionParser.parseWpakFile();
//InitializeEffects();
// Add EffectsBase
ArrayList<EffectsBase> ebList = dbEffectsBaseHandler.getAllEffectsBase();
for (EffectsBase eb : ebList) {
@@ -981,7 +957,7 @@ public enum PowersManager {
// if (!stackType.equals("IgnoreStack")) {
if (target.getEffects().containsKey(stackType)) {
// remove any existing power that overrides
engine.objects.Effect ef = target.getEffects().get(stackType);
Effect ef = target.getEffects().get(stackType);
AbstractEffectJob effect = null;
if (ef != null) {
JobContainer jc = ef.getJobContainer();
@@ -1153,7 +1129,7 @@ public enum PowersManager {
// if (!stackType.equals("IgnoreStack")) {
if (target.getEffects().containsKey(stackType)) {
// remove any existing power that overrides
engine.objects.Effect ef = target.getEffects().get(stackType);
Effect ef = target.getEffects().get(stackType);
AbstractEffectJob effect = null;
if (ef != null) {
JobContainer jc = ef.getJobContainer();
@@ -1467,7 +1443,7 @@ public enum PowersManager {
stackType = (stackType.equals("IgnoreStack")) ? Integer.toString(ab.getUUID()) : stackType;
if (target.getEffects().containsKey(stackType)) {
// remove any existing power that overrides
engine.objects.Effect ef = target.getEffects().get(stackType);
Effect ef = target.getEffects().get(stackType);
AbstractEffectJob effect = null;
if (ef != null) {
JobContainer jc = ef.getJobContainer();
@@ -1914,7 +1890,7 @@ public enum PowersManager {
stackType = (stackType.equals("IgnoreStack")) ? Integer
.toString(toRemove.getUUID()) : stackType;
if (fromChant) {
engine.objects.Effect eff = awo.getEffects().get(stackType);
Effect eff = awo.getEffects().get(stackType);
if (eff != null)
eff.cancelJob(true);
} else
+44 -8
View File
@@ -841,16 +841,28 @@ public class mbEnums {
DRAIN;
public static DamageType getDamageType(String modName) {
if (modName.isEmpty())
return DamageType.NONE;
if(modName.toLowerCase().equals("blind"))
modName = "BLINDNESS";
if(modName.toLowerCase().equals("powerblock"))
modName = "POWERINHIBITOR";
DamageType damageType;
if (modName.isEmpty())
//validity check for not looking up damage type that doesn't exist
boolean valid = false;
for(DamageType type : DamageType.values()){
if(type.name().equals(modName))
valid = true;
}
if(!valid)
return DamageType.NONE;
DamageType damageType;
try {
damageType = DamageType.valueOf(modName.replace(",", "").toUpperCase());
} catch (Exception e) {
@@ -3026,14 +3038,14 @@ public class mbEnums {
public enum PowerType {
None,
SPELL,
SKILL;
SKILL
}
public enum CostType {
NONE,
HEALTH,
MANA,
STAMINA;
STAMINA
}
public enum AreaType {
@@ -3042,7 +3054,7 @@ public class mbEnums {
POINTBLANK,
LINE,
CONE,
WALL;
WALL
}
public enum ExcludeType {
@@ -3053,14 +3065,14 @@ public class mbEnums {
NATION,
PLAYERS,
ALLBUTGROUP,
ALLBUTPETS;
ALLBUTPETS
}
public enum CastingModeType {
NONE,
COMBAT,
NONCOMBAT,
BOTH;
BOTH
}
public enum TargetSelectType {
@@ -3069,7 +3081,7 @@ public class mbEnums {
GROUP,
GUILD,
NEARBYMOBS,
NAME;
NAME
}
public enum CategoryToPowerType {
@@ -3079,5 +3091,29 @@ public class mbEnums {
Always
}
public enum ModificationType {
ADD,
MULTIPLY
}
public enum ServerConfig {
MBDB_108("AERYNTH", "ARAC", "MOURNING", 300000),
MBDB_192("DALGOTH", "ARAC", "GOOK", 300001),
MBDB_162("VORGINA", "LORE", "SAEDRON", 300002),
MBDB_164("VORGINA", "ARAC", "THURIN", 300002);
public final String mapType;
public final String ruleType;
public final String serverName;
public final int realmMap;
ServerConfig(String mapType, String ruleType, String serverName, int realmMap) {
this.mapType = mapType;
this.ruleType = ruleType;
this.serverName = serverName;
this.realmMap = realmMap;
}
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ public enum Protocol {
ITEMPRODUCTION(0x3CCE8E30, ItemProductionMsg.class, ItemProductionMsgHandler.class),
ITEMTOVAULT(0x3ABE4927, ItemToVaultMsg.class, ItemToVaultMsgHandler.class), // Transfer Item to Vault
ITEMFROMVAULT(0x0119A64D, ItemFromVaultMsg.class, ItemFromVaultMsgHandler.class), // Transfer Item from Vault to Inventory
JOINFORPROVINCE(0x1FB369CD, AcceptSubInviteMsg.class, AcceptSubInviteHandler.class), //Response to invite to swear?
JOINFORPROVINCE(0x1FB369CD, AcceptSubInviteMsg.class, SwearInGuildHandler.class), //Response to invite to swear?
JOINFORSWORN(0xF6A4170F, null, null),
JOINGROUP(0x7EC5E636, GroupInviteResponseMsg.class, GroupInviteResponseHandler.class), // Accept Group Invite
JOINGUILD(0xF0C5F2FF, AcceptInviteToGuildMsg.class, AcceptInviteToGuildHandler.class), // Accept guild invite
@@ -17,8 +17,8 @@ import engine.net.Dispatch;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.guild.AcceptSubInviteMsg;
import engine.net.client.msg.guild.SendGuildEntryMsg;
import engine.net.client.msg.guild.SwearInGuildMsg;
import engine.objects.City;
import engine.objects.Guild;
import engine.objects.GuildStatusController;
@@ -36,18 +36,18 @@ public class SwearInGuildHandler extends AbstractClientMsgHandler {
@Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter player;
SwearInGuildMsg swearInMsg;
AcceptSubInviteMsg swearInMsg;
Guild targetGuild;
Guild nation;
Dispatch dispatch;
swearInMsg = (SwearInGuildMsg) baseMsg;
swearInMsg = (AcceptSubInviteMsg) baseMsg;
player = SessionManager.getPlayerCharacter(origin);
if (player == null)
return true;
targetGuild = (Guild) DbManager.getObject(GameObjectType.Guild, swearInMsg.getGuildUUID());
targetGuild = (Guild) DbManager.getObject(GameObjectType.Guild, swearInMsg.guildUUID());
if (targetGuild == null) {
ErrorPopupMsg.sendErrorMsg(player, "A Serious error has occured. Please post details for to ensure transaction integrity");
@@ -66,15 +66,6 @@ public class SwearInGuildHandler extends AbstractClientMsgHandler {
ErrorPopupMsg.sendErrorMsg(player, "Your guild is not a nation!");
return true;
}
if (!nation.getSubGuildList().contains(targetGuild)) {
ErrorPopupMsg.sendErrorMsg(player, "Your do not have such authority!");
return true;
}
if (!Guild.canSwearIn(targetGuild)) {
ErrorPopupMsg.sendErrorMsg(player, targetGuild.getGuildState().name() + "cannot be sworn in");
return true;
}
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false) {
ErrorPopupMsg.sendErrorMsg(player, "Your do not have such authority!");
@@ -86,16 +77,8 @@ public class SwearInGuildHandler extends AbstractClientMsgHandler {
return true;
}
switch (targetGuild.getGuildState()) {
case Petitioner:
GuildManager.updateAllGuildBinds(targetGuild, nation.getOwnedCity());
break;
case Protectorate:
break;
default:
//shouldn't get here.
break;
}
if (targetGuild.getGuildState().equals(GuildState.Errant))
GuildManager.updateAllGuildBinds(targetGuild, nation.getOwnedCity());
//update Guild state.
targetGuild.setNation(nation);
+2 -2
View File
@@ -561,7 +561,7 @@ public class Building extends AbstractWorldObject {
BuildingManager.setRank(barracksBuilding, -1);
}
// If the tree is R8 and deranking, we need to update the
// If the tree is R8 and deranking, we need to update it's
// mesh along with buildings losing their health bonus
if (this.rank == 8) {
@@ -959,7 +959,7 @@ public class Building extends AbstractWorldObject {
// Altitude of this building is derived from the heightmap engine.
Vector3fImmutable tempLoc = new Vector3fImmutable(this.statLat + this.parentZone.absX, 0, this.statLon + this.parentZone.absZ);
tempLoc = new Vector3fImmutable(tempLoc.x, Terrain.getWorldHeight(tempLoc), tempLoc.z);
tempLoc = new Vector3fImmutable(tempLoc.x, Terrain.getWorldHeight(tempLoc) + this.statAlt, tempLoc.z);
this.setLoc(tempLoc);
}
}
+4 -11
View File
@@ -41,7 +41,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class City extends AbstractWorldObject {
@@ -81,7 +80,6 @@ public class City extends AbstractWorldObject {
private String hash;
public Warehouse warehouse;
public Realm realm;
public AtomicBoolean isDestroyed = new AtomicBoolean(false);
/**
* ResultSet Constructor
@@ -324,7 +322,6 @@ public class City extends AbstractWorldObject {
continue;
//can't repledge to a guild you're already part of
if (repledge && city.getGuild().equals(playerCharacter.guild))
continue;
@@ -1119,21 +1116,17 @@ public class City extends AbstractWorldObject {
public final void destroy() {
if (this.isDestroyed.compareAndSet(false, true)) {
Thread destroyCityThread = new Thread(new DestroyCityThread(this));
Thread destroyCityThread = new Thread(new DestroyCityThread(this));
destroyCityThread.setName("destroyCity:" + this.getParent().zoneName);
destroyCityThread.start();
} else
Logger.error("Attempt to destroy destroyed city");
destroyCityThread.setName("destroyCity:" + this.getName());
destroyCityThread.start();
}
public final void transfer(AbstractCharacter newOwner) {
Thread transferCityThread = new Thread(new TransferCityThread(this, newOwner));
transferCityThread.setName("TransferCity:" + this.getParent().zoneName);
transferCityThread.setName("TransferCity:" + this.getName());
transferCityThread.start();
}
-23
View File
@@ -512,29 +512,6 @@ public class NPC extends AbstractCharacter {
return MinionType.ContractToMinionMap.containsKey(contractID);
}
public static boolean UpdateEquipSetID(NPC npc, int equipSetID) {
if (!LootManager._bootySetMap.containsKey(equipSetID))
return false;
if (!DbManager.NPCQueries.UPDATE_EQUIPSET(npc, equipSetID))
return false;
npc.equipmentSetID = equipSetID;
return true;
}
public static boolean UpdateRaceID(NPC npc, int raceID) {
if (!DbManager.NPCQueries.UPDATE_MOBBASE(npc, raceID))
return false;
npc.loadID = raceID;
npc.mobBase = MobBase.getMobBase(npc.loadID);
return true;
}
public static NPCProfits GetNPCProfits(NPC npc) {
return NPCProfits.ProfitCache.get(npc.currentID);
}
+7 -35
View File
@@ -26,11 +26,10 @@ import engine.net.client.ClientConnection;
import engine.net.client.msg.ApplyEffectMsg;
import engine.objects.AbstractCharacter;
import engine.objects.AbstractWorldObject;
import engine.objects.Effect;
import engine.objects.PlayerCharacter;
import engine.powers.effectmodifiers.AbstractEffectModifier;
import engine.server.MBServerStatics;
import engine.util.Hasher;
import engine.wpak.data.Effect;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
@@ -63,7 +62,7 @@ public class EffectsBase {
// flags
private boolean isItemEffect;
private boolean isSpireEffect;
private boolean ignoreNoMod;
private boolean ignoreMod;
private boolean dontSave;
private boolean cancelOnAttack = false;
private boolean cancelOnAttackSwing = false;
@@ -92,33 +91,6 @@ public class EffectsBase {
}
//EffectEntry constructor
public EffectsBase(Effect entry) {
this.IDString = entry.effect_id;
this.name = entry.effect_name;
this.token = Hasher.SBStringHash(entry.effect_name);
//override tokens for some effects like Safemode that use the Action Token instead of the effect Token,
switch (this.IDString) {
case "INVIS-D":
this.token = -1661751254;
break;
case "SafeMode":
this.token = -1661750486;
break;
}
this.isItemEffect = entry.isItemEffect;
this.isSpireEffect = entry.isSpireEffect;
this.ignoreNoMod = entry.ignoreNoMod;
this.dontSave = entry.dontSave;
if (this.IDString.startsWith("PRE-"))
this.isPrefix = true;
else if (this.IDString.startsWith("SUF-"))
this.isSuffix = true;
}
public EffectsBase(EffectsBase copyEffect, int newToken, String IDString) {
UUID = NewID++;
@@ -130,7 +102,7 @@ public class EffectsBase {
int flags = 0;
this.isItemEffect = ((flags & 1) != 0) ? true : false;
this.isSpireEffect = ((flags & 2) != 0) ? true : false;
this.ignoreNoMod = ((flags & 4) != 0) ? true : false;
this.ignoreMod = ((flags & 4) != 0) ? true : false;
this.dontSave = ((flags & 8) != 0) ? true : false;
if (this.IDString.startsWith("PRE-"))
@@ -145,7 +117,7 @@ public class EffectsBase {
this.amountRamp = copyEffect.amountRamp;
this.isItemEffect = copyEffect.isItemEffect;
this.isSpireEffect = copyEffect.isSpireEffect;
this.ignoreNoMod = copyEffect.ignoreNoMod;
this.ignoreMod = copyEffect.ignoreMod;
this.dontSave = copyEffect.dontSave;
this.cancelOnAttack = copyEffect.cancelOnAttack;
this.cancelOnAttackSwing = copyEffect.cancelOnAttackSwing;
@@ -191,7 +163,7 @@ public class EffectsBase {
int flags = rs.getInt("flags");
this.isItemEffect = ((flags & 1) != 0) ? true : false;
this.isSpireEffect = ((flags & 2) != 0) ? true : false;
this.ignoreNoMod = ((flags & 4) != 0) ? true : false;
this.ignoreMod = ((flags & 4) != 0) ? true : false;
this.dontSave = ((flags & 8) != 0) ? true : false;
if (this.IDString.startsWith("PRE-"))
@@ -379,7 +351,7 @@ public class EffectsBase {
}
public boolean ignoreMod() {
return this.ignoreNoMod;
return this.ignoreMod;
}
public boolean dontSave() {
@@ -432,7 +404,7 @@ public class EffectsBase {
float duration = ab.getDurationInSeconds(trains);
if (pb.getToken() == 1672601862) {
engine.objects.Effect eff = awo.getEffects().get("DeathShroud");
Effect eff = awo.getEffects().get("DeathShroud");
if (eff != null) {
+1 -1
View File
@@ -76,7 +76,7 @@ public class WorldServer {
super();
}
public static void main(String[] args) throws IOException {
public static void main(String[] args) {
WorldServer worldServer;
+115 -103
View File
@@ -53,117 +53,129 @@ public class DestroyCityThread implements Runnable {
// Member variable assignment
try {
cityZone = city.getParent();
newParent = cityZone.parent;
formerGuild = city.getTOL().getGuild();
cityZone = city.getParent();
newParent = cityZone.parent;
formerGuild = city.getTOL().getGuild();
Logger.info("Destroy city thread started for: " + cityZone.zoneName);
// Former guild loses it's tree!
// Former guild loses tree!
if (DbManager.GuildQueries.SET_GUILD_OWNED_CITY(formerGuild.getObjectUUID(), 0)) {
if (DbManager.GuildQueries.SET_GUILD_OWNED_CITY(formerGuild.getObjectUUID(), 0)) {
//Successful Update of guild
//Successful Update of guild
formerGuild.setGuildState(mbEnums.GuildState.Errant);
formerGuild.setNation(null);
formerGuild.setCityUUID(0);
GuildManager.updateAllGuildTags(formerGuild);
GuildManager.updateAllGuildBinds(formerGuild, null);
}
// By losing the tree, the former owners lose all of their subguilds.
if (!formerGuild.getSubGuildList().isEmpty()) {
subGuildList = new ArrayList<>();
subGuildList.addAll(formerGuild.getSubGuildList());
for (Guild subGuild : subGuildList) {
formerGuild.removeSubGuild(subGuild);
}
}
// Build list of buildings within this parent zone
ArrayList<Building> destroySet = new ArrayList<>();
for (Building cityBuilding : cityZone.zoneBuildingSet) {
// Sanity Check in case player deletes the building
// before this thread can get to it
if (cityBuilding == null)
continue;
// Do nothing with the banestone. It will be removed elsewhere
if (cityBuilding.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.BANESTONE))
continue;
// All buildings are moved to a location relative
// to their new parent zone
localCoords = ZoneManager.worldToLocal(cityBuilding.getLoc(), newParent);
DbManager.BuildingQueries.MOVE_BUILDING(cityBuilding.getObjectUUID(), newParent.getObjectUUID(), localCoords.x, localCoords.y, localCoords.z);
// All buildings are re-parented to a zone one node
// higher in the tree (continent) as we will be
// deleting the city zone very shortly.
if (cityBuilding.getParentZoneID() != newParent.getParentZoneID())
cityBuilding.setParentZone(newParent);
// No longer a tree, no longer any protection contract!
cityBuilding.setProtectionState(mbEnums.ProtectionState.NONE);
// Remove warehouse entry if one exists.
if (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.WAREHOUSE) {
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
city.warehouse = null;
}
// Mark all auto protected buildings for destruction
if ((cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.BARRACK) || (cityBuilding.getBlueprint().isWallPiece()) || (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.SHRINE) || (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.TOL) || (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.SPIRE) || (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.WAREHOUSE))
destroySet.add(cityBuilding);
}
// Destroy set of auto-protected buildings
for (Building building : destroySet)
if (building.getRank() != -1)
BuildingManager.setRank(building, -1);
if (city.realm != null) {
city.realm.removeCity(city.getObjectUUID());
city.realm = null;
}
// It's now safe to delete the city zone from the database
// which will cause a cascade delete of everything else
if (!DbManager.ZoneQueries.DELETE_ZONE(cityZone)) {
Logger.error("DestroyCityThread", "Database error when deleting city zone: " + cityZone.getObjectUUID());
return;
}
// Refresh the city for map requests
City.lastCityUpdate = System.currentTimeMillis();
} catch (Exception e) {
Logger.error(e);
formerGuild.setGuildState(mbEnums.GuildState.Errant);
formerGuild.setNation(null);
formerGuild.setCityUUID(0);
GuildManager.updateAllGuildTags(formerGuild);
GuildManager.updateAllGuildBinds(formerGuild, null);
}
// By losing the tree, the former owners lose all of their subguilds.
if (!formerGuild.getSubGuildList().isEmpty()) {
subGuildList = new ArrayList<>();
subGuildList.addAll(formerGuild.getSubGuildList());
for (Guild subGuild : subGuildList) {
formerGuild.removeSubGuild(subGuild);
}
}
Building tol = null;
// Build list of buildings within this parent zone
for (Building cityBuilding : cityZone.zoneBuildingSet) {
// Sanity Check in case player deletes the building
// before this thread can get to it
if (cityBuilding == null)
continue;
// check null bluepritn and log error
if (cityBuilding.getBlueprint() == null){
Logger.error("Null Blueprint for building ID: " + cityBuilding.getObjectUUID());
continue;
}
// Do nothing with the banestone. It will be removed elsewhere
if (cityBuilding.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.BANESTONE))
continue;
// TOL is processed after all other structures in the city zone
if (cityBuilding.getBlueprint().getBuildingGroup().equals(mbEnums.BuildingGroup.TOL)) {
tol = cityBuilding;
continue;
}
// All buildings are moved to a location relative
// to their new parent zone
localCoords = ZoneManager.worldToLocal(cityBuilding.getLoc(), newParent);
DbManager.BuildingQueries.MOVE_BUILDING(cityBuilding.getObjectUUID(), newParent.getObjectUUID(), localCoords.x, localCoords.y, localCoords.z);
// All buildings are re-parented to a zone one node
// higher in the tree (continent) as we will be
// deleting the city zone very shortly.
if (cityBuilding.getParentZoneID() != newParent.getParentZoneID())
cityBuilding.setParentZone(newParent);
// No longer a tree, no longer any protection contract!
cityBuilding.setProtectionState(mbEnums.ProtectionState.NONE);
// Remove warehouse entry if one exists.
if (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.WAREHOUSE) {
DbManager.WarehouseQueries.DELETE_WAREHOUSE(city.warehouse);
city.warehouse = null;
}
// Destroy all remaining city assets
if ((cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.BARRACK)
|| (cityBuilding.getBlueprint().isWallPiece())
|| (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.SHRINE)
|| (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.TOL)
|| (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.SPIRE)
|| (cityBuilding.getBlueprint().getBuildingGroup() == mbEnums.BuildingGroup.WAREHOUSE)) {
if (cityBuilding.getRank() != -1)
BuildingManager.setRank(cityBuilding, -1);
}
}
// Destroy the tol
if (tol != null)
BuildingManager.setRank(tol, -1);
if (city.realm != null)
city.realm.removeCity(city.getObjectUUID());
// It's now safe to delete the city zone from the database
// which will cause a cascade delete of everything else
if (DbManager.ZoneQueries.DELETE_ZONE(cityZone) == false) {
Logger.error("DestroyCityThread", "Database error when deleting city zone: " + cityZone.getObjectUUID());
return;
}
// Refresh the city for map requests
City.lastCityUpdate = System.currentTimeMillis();
// Zone and city should vanish upon next reboot
// if the codebase reaches here.
Logger.info(city.getParent().zoneName + " uuid: " + city.getObjectUUID() + " has been destroyed!");
Logger.info(city.getParent().zoneName + " uuid:" + city.getObjectUUID() + "has been destroyed!");
}
}
+12 -6
View File
@@ -18,14 +18,16 @@ import org.pmw.tinylog.Logger;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EffectsParser {
public static String effectsPath = ConfigManager.DEFAULT_DATA_DIR + "wpak/Effects.cfg";
public static HashMap<String, Effect> effect_data = new HashMap<>();
private static final Pattern EFFECT_REGEX = Pattern.compile("(?<=EFFECTBEGIN)(.+?)(?=EFFECTEND)", Pattern.DOTALL);
private static final Pattern SOURCE_REGEX = Pattern.compile("(?<=SOURCEBEGIN)(.+?)(?=SOURCEEND)", Pattern.DOTALL);
private static final Pattern MODS_REGEX = Pattern.compile("(?<=MODSBEGIN)(.+?)(?=MODSEND)", Pattern.DOTALL);
@@ -51,8 +53,12 @@ public class EffectsParser {
Matcher matcher = EFFECT_REGEX.matcher(fileContents);
while (matcher.find()) {
Effect effect = parseEffectEntry(matcher.group());
effect_data.put(effect.effect_id, effect);
try {
Effect effect = parseEffectEntry(matcher.group());
// WpakPowerManager._effectsLookup.put(effect.effect_id, effect);
} catch (Exception e) {
Logger.error("EFFECT PARSE FAILED: " + e);
}
}
}
@@ -174,8 +180,8 @@ public class EffectsParser {
case Stamina:
modifierEntry.min = Float.parseFloat(modValues.get(1).trim());
modifierEntry.max = Float.parseFloat(modValues.get(2).trim());
modifierEntry.value = Float.parseFloat(modValues.get(3).trim());
// Parameter 4 is always 0.
modifierEntry.percentage = Float.parseFloat(modValues.get(3).trim());
modifierEntry.value = Float.parseFloat(modValues.get(4).trim()); // Always zero
modifierEntry.compoundCurveType = mbEnums.CompoundCurveType.valueOf(modValues.get(5).trim());
modifierEntry.arg1 = modValues.get(6).trim();
break;
+50 -47
View File
@@ -52,7 +52,7 @@ public class PowerActionParser {
while (matcher.find()) {
PowerAction powerAction = parsePowerActionEntry(matcher.group().trim());
// WpakPowerManager._powerActionLookup.put(Hasher.SBStringHash(powerAction.action_id), powerAction);
}
}
@@ -82,26 +82,26 @@ public class PowerActionParser {
Iterator<String> headerIterator = headerData.iterator();
powerAction.action_id = headerIterator.next();
powerAction.action_type = headerIterator.next();
powerAction.action_type = mbEnums.PowerActionType.valueOf(headerIterator.next());
switch (powerAction.action_type) {
case "RemoveEffect":
case RemoveEffect:
effect = new Effect();
effect.effect_id = headerIterator.next();
powerAction.effects.add(effect);
break;
case "CreateMob":
powerAction.petLevel = Integer.parseInt(headerIterator.next());
case CreateMob:
powerAction.petRace = Integer.parseInt(headerIterator.next());
powerAction.petLevel = Integer.parseInt(headerIterator.next());
break;
case "DamageOverTime":
case DamageOverTime:
effect = new Effect();
effect.effect_id = headerIterator.next();
effect.cycleDuration = Integer.parseInt(headerIterator.next());
effect.cycleDelay = Integer.parseInt(headerIterator.next());
powerAction.effects.add(effect);
break;
case "ApplyEffects":
case ApplyEffects:
int level = Integer.parseInt(headerIterator.next());
while (headerIterator.hasNext()) {
@@ -111,12 +111,12 @@ public class PowerActionParser {
powerAction.effects.add(effect);
}
break;
case "Transform":
case "Invis":
case "ApplyEffect":
case "DeferredPower":
case "DirectDamage":
case "SpireDisable":
case Transform:
case Invis:
case ApplyEffect:
case DeferredPower:
case DirectDamage:
case SpireDisable:
while (headerIterator.hasNext()) {
effect = new Effect();
effect.effect_id = headerIterator.next();
@@ -129,73 +129,76 @@ public class PowerActionParser {
powerAction.effects.add(effect);
}
break;
case "TransferStat":
case TransferStat:
statTransfer = new StatTransfer();
statTransfer.fromStat = mbEnums.CostType.valueOf(headerIterator.next());
statTransfer.toStat = mbEnums.CostType.valueOf(headerIterator.next());
statTransfer.fromStatValue = Float.parseFloat(headerIterator.next());
statTransfer.fromCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.toStatValue = Float.parseFloat(headerIterator.next());
statTransfer.toCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.ramp = Float.parseFloat(headerIterator.next());
statTransfer.rampCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.efficiency = Float.parseFloat(headerIterator.next());
statTransfer.efficiencyCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.fromStatBool = Boolean.parseBoolean(headerIterator.next());
statTransfer.toStatBool = Boolean.parseBoolean(headerIterator.next());
statTransfer.isDrain = Boolean.parseBoolean(headerIterator.next());
powerAction.statTransfer = statTransfer;
break;
case "TransferStatOT":
case TransferStatOT:
statTransfer = new StatTransfer();
statTransfer.fromStat = mbEnums.CostType.valueOf(headerIterator.next());
statTransfer.toStat = mbEnums.CostType.valueOf(headerIterator.next());
statTransfer.fromStatValue = Float.parseFloat(headerIterator.next());
statTransfer.fromCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.toStatValue = Float.parseFloat(headerIterator.next());
statTransfer.toCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.ramp = Float.parseFloat(headerIterator.next());
statTransfer.rampCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.efficiency = Float.parseFloat(headerIterator.next());
statTransfer.efficiencyCurve = mbEnums.CompoundCurveType.valueOf(headerIterator.next());
statTransfer.fromStatBool = Boolean.parseBoolean(headerIterator.next());
statTransfer.toStatBool = Boolean.parseBoolean(headerIterator.next());
statTransfer.isDrain = Boolean.parseBoolean(headerIterator.next());
statTransfer.transfer_action = headerIterator.next();
statTransfer.transfer_ticks = Integer.parseInt(headerIterator.next());
powerAction.statTransfer = statTransfer;
break;
case "Charm":
case Charm:
effect = new Effect();
effect.effect_id = headerIterator.next();
effect.level = Integer.parseInt(headerIterator.next());
effect.type = headerIterator.next();
powerAction.effects.add(effect);
break;
case "Block":
case Block:
effect = new Effect();
effect.effect_id = headerIterator.next();
effect.level = Integer.parseInt(headerIterator.next());
powerAction.effects.add(effect);
break;
case "Resurrect":
case Resurrect:
powerAction.levelCap = Integer.parseInt(headerIterator.next());
break;
case "SetItemFlag":
case SetItemFlag:
powerAction.itemFlag = mbEnums.ItemFlags.valueOf(headerIterator.next());
break;
case "Track":
case Track:
trackEntry = new TrackEntry();
trackEntry.action_id = headerIterator.next();
trackEntry.unknown1 = Boolean.parseBoolean(headerIterator.next());
trackEntry.unknown2 = Boolean.parseBoolean(headerIterator.next());
trackEntry.type = headerIterator.next();
trackEntry.trackPlayer = Boolean.parseBoolean(headerIterator.next());
trackEntry.trackCorpse = Boolean.parseBoolean(headerIterator.next());
trackEntry.filter = mbEnums.MonsterType.valueOf(headerIterator.next());
trackEntry.min = Integer.parseInt(headerIterator.next());
trackEntry.max = Integer.parseInt(headerIterator.next());
powerAction.trackEntry = trackEntry;
break;
case "Recall": // No arguments for these tags or not parsed
case "Summon":
case "Teleport":
case "TreeChoke":
case "SimpleDamage":
case "MobRecall": // One argument always zero
case "ClearAggro":
case "ClearNearbyAggro":
case "Peek":
case "ClaimMine":
case "RunegateTeleport":
case "Steal":
case Teleport:
if (headerIterator.hasNext())
powerAction.ignoreNoTeleSpire = Boolean.parseBoolean(headerIterator.next());
break;
case Recall: // No arguments for these tags or not parsed
case Summon:
case TreeChoke:
case SimpleDamage:
case MobRecall: // One argument always zero
case ClearAggro:
case ClearNearbyAggro:
case Peek:
case ClaimMine:
case RunegateTeleport:
case Steal:
break;
default:
Logger.error("Unhandled type " + powerAction.action_type + " for Pow4erAction: " + powerAction.action_id);
@@ -215,7 +218,7 @@ public class PowerActionParser {
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
for (String bodyPart : arguments)
powerAction.bodyparts.add(Integer.parseInt(bodyPart));
powerAction.bodyParts.add(Integer.parseInt(bodyPart));
break;
case "FEMALEBODYPARTS":
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
@@ -269,7 +272,7 @@ public class PowerActionParser {
powerAction.levelCap = Integer.parseInt(arguments.get(0));
if (arguments.size() > 1) // Not all level caps have a curve
powerAction.levelCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
powerAction.levelCapCurve = mbEnums.CompoundCurveType.valueOf(arguments.get(1));
break;
case "CLEARAGGRO":
powerAction.clearAggro = Boolean.parseBoolean(lineValues.get(1).trim());
+13 -8
View File
@@ -50,7 +50,7 @@ public class PowersParser {
while (matcher.find()) {
Power power = parsePowerEntry(matcher.group().trim());
// @TODO WpakPowerManager._powersLookup.put(Hasher.SBStringHash(power.power_id), power);
}
}
@@ -104,7 +104,7 @@ public class PowersParser {
PowerEntry power = new PowerEntry();
power.power_type = mbEnums.PowerType.valueOf(iterator.next());
power.icon = Integer.parseInt(iterator.next());
power.powerBase = iterator.next().replaceAll("\"", "");
power.focusLine = iterator.next().replaceAll("\"", "");
powerEntry.powers.add(power);
String nextValue = iterator.next();
@@ -115,7 +115,7 @@ public class PowersParser {
power = new PowerEntry();
power.power_type = mbEnums.PowerType.valueOf(nextValue);
power.icon = Integer.parseInt(iterator.next());
power.powerBase = iterator.next().replaceAll("\"", "");
power.focusLine = iterator.next().replaceAll("\"", "");
powerEntry.powers.add(power);
powerEntry.target_type = mbEnums.PowerTargetType.valueOf(iterator.next());
} else
@@ -157,7 +157,7 @@ public class PowersParser {
case "ACTION":
actionEntry = new ActionEntry();
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
actionEntry.effect_id = arguments.get(0);
actionEntry.action_id = arguments.get(0);
actionEntry.minTrains = Integer.parseInt(arguments.get(1));
actionEntry.maxTrains = Integer.parseInt(arguments.get(2));
actionEntry.duration = Float.parseFloat(arguments.get(3));
@@ -189,7 +189,7 @@ public class PowersParser {
powerEntry.description.add(lineValues.get(1).trim());
break;
case "CATEGORY":
powerEntry.category = lineValues.get(1).trim();
powerEntry.category = mbEnums.PowerCategoryType.valueOf(lineValues.get(1).trim());
break;
case "CURVE":
arguments = Arrays.asList(lineValues.get(1).trim().split("\\s+"));
@@ -206,9 +206,14 @@ public class PowersParser {
while (argumentIterator.hasNext()) {
EquipmentPreReq equipmentPreReq = new EquipmentPreReq();
equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(arguments.get(0));
equipmentPreReq.skill = arguments.get(1).replaceAll("\"", "");
equipmentPreReq.required = Integer.parseInt(arguments.get(2));
equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(argumentIterator.next());
equipmentPreReq.skill = argumentIterator.next().replaceAll("\"", "");
if (argumentIterator.hasNext())
equipmentPreReq.required = Integer.parseInt(argumentIterator.next());
else
equipmentPreReq.required = 0;
powerEntry.equipmentPreReq.add(equipmentPreReq);
}
break;
+1 -1
View File
@@ -12,7 +12,7 @@ import engine.mbEnums;
public class ActionEntry {
public String effect_id;
public String action_id;
public int minTrains;
public int maxTrains;
public float duration;
+16
View File
@@ -10,6 +10,7 @@ package engine.wpak.data;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
public class Effect {
public String effect_id;
@@ -32,4 +33,19 @@ public class Effect {
public String message;
public int cycleDuration;
public int cycleDelay;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Effect effect = (Effect) o;
return Objects.equals(effect_id, effect.effect_id);
}
@Override
public int hashCode() {
return effect_id.hashCode(); // Use only the id field for hashCode
}
}
+1
View File
@@ -14,6 +14,7 @@ public class ModifierEntry {
public mbEnums.ModType type;
public float min;
public float max;
public float percentage;
public float value;
public mbEnums.CompoundCurveType compoundCurveType;
public String arg1; // ItemName "Masterwork" ""
+28 -1
View File
@@ -13,6 +13,7 @@ import engine.mbEnums;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Objects;
public class Power {
public String power_id;
@@ -46,7 +47,7 @@ public class Power {
public String grantOverrideVar;
public ArrayList<String> description = new ArrayList<>();
public HashMap<String, mbEnums.CompoundCurveType> curves = new HashMap<>();
public String category;
public mbEnums.PowerCategoryType category;
public boolean canCastWhileMoving = false;
public boolean bladeTrails = false;
public ArrayList<Effect> effectPreReqs = new ArrayList<>();
@@ -66,4 +67,30 @@ public class Power {
public boolean isProjectile = false;
public HashMap<String, Float> conditions = new HashMap<>();
public boolean isSpell() {
return true;
}
public boolean isSkill() {
return true;
}
public boolean isChant() {
return true;
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
Power power = (Power) o;
return Objects.equals(power_id, power.power_id);
}
@Override
public int hashCode() {
return power_id.hashCode(); // Use only the id field for hashCode
}
}
+18 -3
View File
@@ -11,24 +11,25 @@ package engine.wpak.data;
import engine.mbEnums;
import java.util.ArrayList;
import java.util.Objects;
public class PowerAction {
// Header values
public String action_id;
public String action_type;
public mbEnums.PowerActionType action_type;
public ArrayList<Effect> effects = new ArrayList<>();
public int petLevel;
public int petRace;
public StatTransfer statTransfer;
public int levelCap;
public mbEnums.CompoundCurveType levelCurve;
public mbEnums.CompoundCurveType levelCapCurve;
public TrackEntry trackEntry;
// Additional variables after header go here.
public ArrayList<Integer> bodyparts = new ArrayList<>();
public ArrayList<Integer> bodyParts = new ArrayList<>();
public ArrayList<Integer> femaleBodyParts = new ArrayList<>();
public boolean shouldShowWeapons = false;
public boolean shouldShowArmor = false;
@@ -48,6 +49,20 @@ public class PowerAction {
public mbEnums.MobBehaviourType rootFsmID;
public int splashDamageMin;
public int splashDamageMax;
public boolean ignoreNoTeleSpire = false;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
PowerAction powerAction = (PowerAction) o;
return Objects.equals(action_id, powerAction.action_id);
}
@Override
public int hashCode() {
return action_id.hashCode(); // Use only the id field for hashCode
}
}
+1 -1
View File
@@ -13,5 +13,5 @@ import engine.mbEnums;
public class PowerEntry {
public mbEnums.PowerType power_type;
public int icon;
public String powerBase;
public String focusLine;
}
+5 -5
View File
@@ -12,13 +12,13 @@ import engine.mbEnums;
public class StatTransfer {
public mbEnums.CostType fromStat;
public float fromStatValue;
public mbEnums.CompoundCurveType fromCurve;
public float ramp;
public mbEnums.CompoundCurveType rampCurve;
public mbEnums.CostType toStat;
public float toStatValue;
public mbEnums.CompoundCurveType toCurve;
public float efficiency;
public mbEnums.CompoundCurveType efficiencyCurve;
public boolean fromStatBool;
public boolean toStatBool;
public boolean isDrain;
public String transfer_action;
public int transfer_ticks;
}
+5 -3
View File
@@ -8,12 +8,14 @@
package engine.wpak.data;
import engine.mbEnums;
public class TrackEntry {
public String action_id;
public Boolean unknown1;
public Boolean unknown2;
public String type;
public Boolean trackPlayer;
public Boolean trackCorpse;
public mbEnums.MonsterType filter;
public int min;
public int max;
}