diff --git a/src/engine/objects/CharacterSkill.java b/src/engine/objects/CharacterSkill.java index 126e0e89..41e31e56 100644 --- a/src/engine/objects/CharacterSkill.java +++ b/src/engine/objects/CharacterSkill.java @@ -1043,15 +1043,15 @@ public class CharacterSkill extends AbstractGameObject { if (this.skillsBase.getStrMod() > 0) - statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f; + statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Strength) / 100f; if (this.skillsBase.getDexMod() > 0) - statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseDex() / 100f; + statMod += (float) this.skillsBase.getDexMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Dexterity) / 100f; if (this.skillsBase.getConMod() > 0) - statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseCon() / 100f; + statMod += (float) this.skillsBase.getConMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Constitution) / 100f; if (this.skillsBase.getIntMod() > 0) - statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseInt() / 100f; + statMod += (float) this.skillsBase.getIntMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Intelligence) / 100f; if (this.skillsBase.getSpiMod() > 0) - statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseSpi() / 100f; + statMod += (float) this.skillsBase.getSpiMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getRuneAttribute(mbEnums.AttributeType.Spirit) / 100f; if (statMod < 1) statMod = 1f; else if (statMod > 600) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 3bc1fafb..94fff9e3 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -22,6 +22,7 @@ import engine.net.ByteBufferWriter; import engine.net.Dispatch; import engine.net.client.msg.PetMsg; import engine.net.client.msg.PlaceAssetMsg; +import engine.parsers.objects.RuneTemplate; import engine.server.MBServerStatics; import org.jetbrains.annotations.NotNull; import org.joda.time.DateTime; @@ -29,6 +30,7 @@ import org.pmw.tinylog.Logger; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.EnumSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Delayed; @@ -198,19 +200,19 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed { writer.putInt(mob.getObjectType().ordinal()); writer.putInt(mob.currentID); - //Send Stats + // Stats are the base (spent points, 0 for mobs); the client adds every sent rune's attr adj (0x470610) writer.putInt(5); writer.putInt(MBServerStatics.STAT_STR_ID); - writer.putInt(mob.statStrCurrent); + writer.putInt(0); writer.putInt(MBServerStatics.STAT_DEX_ID); - writer.putInt(mob.statDexCurrent); + writer.putInt(0); writer.putInt(MBServerStatics.STAT_CON_ID); - writer.putInt(mob.statConCurrent); + writer.putInt(0); writer.putInt(MBServerStatics.STAT_INT_ID); - writer.putInt(mob.statIntCurrent); + writer.putInt(0); writer.putInt(MBServerStatics.STAT_SPI_ID); - writer.putInt(mob.statSpiCurrent); + writer.putInt(0); writer.putString(mob.firstName); @@ -725,13 +727,50 @@ public class Mob extends AbstractIntelligenceAgent implements Delayed { return this.bindLoc; } + // The runes serializeForClientMsgOtherPlayer sends; the client derives the mob's attributes from all of them + public ArrayList getClientRuneIDs() { + + ArrayList runeIDs = new ArrayList<>(); + + if (this.isPet()) + runeIDs.add(2522); + else if (this.contract != null || this.isPlayerGuard()) { + runeIDs.add(2518); + runeIDs.add(252621); + } + + runeIDs.add((this.mobBase != null) ? this.mobBase.getObjectUUID() : this.loadID); + return runeIDs; + } + + // Client ArcCharacter_RecalcMaxAttributes 0x470440 + RecalcAttributes 0x470610 with no spent points + public int getRuneAttribute(AttributeType attributeType) { + + RuneTemplate rune; + int value = 0; + int max = 0; + + for (int runeID : this.getClientRuneIDs()) { + rune = RuneTemplate._runes.get(runeID); + + if (rune == null) + continue; + + value += rune.rune_attr_adj.getOrDefault(attributeType, 0); + max += rune.rune_max_attr_adj.getOrDefault(attributeType, 0); + } + + max = Math.max(max, 1); + return Math.min(Math.max(value, 1), max); + } + public void calculateModifiedStats() { - float strVal = this.mobBase.getMobBaseStats().getBaseStr(); - float dexVal = this.mobBase.getMobBaseStats().getBaseDex(); - float conVal = this.mobBase.getMobBaseStats().getBaseCon(); - float intVal = this.mobBase.getMobBaseStats().getBaseInt(); - float spiVal = this.mobBase.getMobBaseStats().getBaseSpi(); + float strVal = this.getRuneAttribute(AttributeType.Strength); + float dexVal = this.getRuneAttribute(AttributeType.Dexterity); + float conVal = this.getRuneAttribute(AttributeType.Constitution); + float intVal = this.getRuneAttribute(AttributeType.Intelligence); + float spiVal = this.getRuneAttribute(AttributeType.Spirit); // TODO modify for equipment if (this.bonuses != null) { diff --git a/src/engine/objects/MobBase.java b/src/engine/objects/MobBase.java index 244c00f5..64076bc2 100644 --- a/src/engine/objects/MobBase.java +++ b/src/engine/objects/MobBase.java @@ -50,7 +50,6 @@ public class MobBase extends AbstractGameObject { private int spawnTime = 0; private float attackRange; private boolean isNecroPet = false; - private MobBaseStats mobBaseStats; private float walk = 0; private float run = 0; private float walkCombat = 0; @@ -125,7 +124,6 @@ public class MobBase extends AbstractGameObject { if (this.flags.contains(mbEnums.MobFlagType.RAT)) this.mask += MBServerStatics.MASK_RAT; - this.mobBaseStats = (rune != null) ? new MobBaseStats(rune) : MobBaseStats.GetGenericStats(); this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID()); } @@ -229,10 +227,6 @@ public class MobBase extends AbstractGameObject { } } - public MobBaseStats getMobBaseStats() { - return mobBaseStats; - } - public float getAttackRange() { return attackRange; } diff --git a/src/engine/objects/MobBaseStats.java b/src/engine/objects/MobBaseStats.java deleted file mode 100644 index c7a827f0..00000000 --- a/src/engine/objects/MobBaseStats.java +++ /dev/null @@ -1,71 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2026 -// https://www.magicbane.com - - -package engine.objects; - -import engine.mbEnums; -import engine.parsers.objects.RuneTemplate; - -public class MobBaseStats { - - public static MobBaseStats mbs = null; - private final int baseStr; - private final int baseInt; - private final int baseCon; - private final int baseSpi; - private final int baseDex; - - public MobBaseStats(RuneTemplate rune) { - this.baseStr = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Strength, 0); - this.baseInt = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Intelligence, 0); - this.baseCon = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Constitution, 0); - this.baseSpi = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Spirit, 0); - this.baseDex = rune.rune_attr_adj.getOrDefault(mbEnums.AttributeType.Dexterity, 0); - } - - /** - * Generic Constructor - */ - - public MobBaseStats() { - this.baseStr = 0; - this.baseInt = 0; - this.baseCon = 0; - this.baseSpi = 0; - this.baseDex = 0; - } - - public static MobBaseStats GetGenericStats() { - if (mbs != null) - return mbs; - mbs = new MobBaseStats(); - return mbs; - } - - public int getBaseStr() { - return baseStr; - } - - public int getBaseInt() { - return baseInt; - } - - public int getBaseCon() { - return baseCon; - } - - public int getBaseSpi() { - return baseSpi; - } - - public int getBaseDex() { - return baseDex; - } - -}