// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.powers; import engine.gameManager.DispatchManager; import engine.gameManager.PowersManager; import engine.job.JobContainer; import engine.jobs.AbstractEffectJob; import engine.jobs.DamageOverTimeJob; import engine.jobs.FinishSpireEffectJob; import engine.jobs.NoTimeJob; import engine.mbEnums; import engine.mbEnums.EffectSourceType; import engine.mbEnums.GameObjectType; import engine.mbEnums.PowerFailCondition; import engine.net.Dispatch; import engine.net.client.ClientConnection; import engine.net.client.msg.ApplyEffectMsg; import engine.objects.*; import engine.powers.effectmodifiers.*; import engine.server.MBServerStatics; import engine.util.Hasher; import engine.wpak.data.ConditionEntry; import engine.wpak.data.EffectEntry; import engine.wpak.data.EffectModifier; import org.pmw.tinylog.Logger; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap; public class EffectsBase { private static final ConcurrentHashMap itemEffectsByName = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); public static int NewID = 3000; public int UUID; public String IDString; // public String name; public int token; public float amount; public float amountRamp; // flags public boolean isItemEffect; public boolean isSpireEffect; public boolean ignoreNoMod; public boolean dontSave; public boolean cancelOnAttack = false; public boolean cancelOnAttackSwing = false; public boolean cancelOnCast = false; public boolean cancelOnCastSpell = false; public boolean cancelOnEquipChange = false; public boolean cancelOnLogout = false; public boolean cancelOnMove = false; public boolean cancelOnNewCharm = false; public boolean cancelOnSit = false; public boolean cancelOnTakeDamage = false; public boolean cancelOnTerritoryClaim = false; public boolean cancelOnUnEquip = false; public boolean useRampAdd; public boolean isPrefix = false; //used by items public boolean isSuffix = false; //used by items public String name = ""; public float value = 0; private ConcurrentHashMap resourceCosts = new ConcurrentHashMap<>(); //loaded values from parser public HashSet effectSources = new HashSet<>(); public HashSet effectModifiers = new HashSet<>(); public HashSet effectFailCondition = new HashSet<>(); public HashSet effectDamageTypes = new HashSet<>(); /** * No Table ID Constructor */ public EffectsBase() { } /** * EffectEntry Constructor */ public EffectsBase(EffectEntry 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; //load effect modifiers for (EffectModifier mod : entry.mods) this.effectModifiers.add(getCombinedModifiers(null, mod, this, mod.type)); //load sources for (String source : entry.sources) this.effectSources.add(EffectSourceType.GetEffectSourceType(source)); //load fail conditions for (ConditionEntry condition : entry.conditions) { PowerFailCondition failCondition = PowerFailCondition.valueOf(condition.condition); this.effectFailCondition.add(failCondition); loadFailConditions(failCondition, this, condition); //add all damage types if(!condition.damageTypes.isEmpty()) this.effectDamageTypes.addAll(condition.damageTypes); } } public static void loadFailConditions(PowerFailCondition failCondition, EffectsBase eb, ConditionEntry entry) { if (failCondition == null || eb == null) { return; } switch (failCondition) { case TakeDamage: eb.cancelOnTakeDamage = true; eb.amount = entry.arg; eb.amountRamp = (float) entry.curveType.getValue(); eb.useRampAdd = (float) entry.curveType.getValue() != 0; break; case Attack: eb.cancelOnAttack = true; break; case AttackSwing: eb.cancelOnAttackSwing = true; break; case Cast: eb.cancelOnCast = true; break; case CastSpell: eb.cancelOnCastSpell = true; break; case EquipChange: eb.cancelOnEquipChange = true; break; case Logout: eb.cancelOnLogout = true; break; case Move: eb.cancelOnMove = true; break; case NewCharm: eb.cancelOnNewCharm = true; break; case Sit: eb.cancelOnSit = true; break; case TerritoryClaim: eb.cancelOnTerritoryClaim = true; break; case UnEquip: eb.cancelOnUnEquip = true; break; } } public EffectsBase(EffectsBase copyEffect, int newToken, String IDString) { UUID = NewID++; this.IDString = IDString; this.token = newToken; //filll if (copyEffect == null) { 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.dontSave = ((flags & 8) != 0) ? true : false; if (this.IDString.startsWith("PRE-")) this.isPrefix = true; else if (this.IDString.startsWith("SUF-")) this.isSuffix = true; } this.amount = copyEffect.amount; this.amountRamp = copyEffect.amountRamp; this.isItemEffect = copyEffect.isItemEffect; this.isSpireEffect = copyEffect.isSpireEffect; this.ignoreNoMod = copyEffect.ignoreNoMod; this.dontSave = copyEffect.dontSave; this.cancelOnAttack = copyEffect.cancelOnAttack; this.cancelOnAttackSwing = copyEffect.cancelOnAttackSwing; this.cancelOnCast = copyEffect.cancelOnCast; this.cancelOnCastSpell = copyEffect.cancelOnCastSpell; this.cancelOnEquipChange = copyEffect.cancelOnEquipChange; this.cancelOnLogout = copyEffect.cancelOnLogout; this.cancelOnMove = copyEffect.cancelOnMove; this.cancelOnNewCharm = copyEffect.cancelOnNewCharm; this.cancelOnSit = copyEffect.cancelOnSit; this.cancelOnTakeDamage = copyEffect.cancelOnTakeDamage; this.cancelOnTerritoryClaim = copyEffect.cancelOnTerritoryClaim; this.cancelOnUnEquip = copyEffect.cancelOnUnEquip; this.useRampAdd = copyEffect.useRampAdd; this.isPrefix = copyEffect.isPrefix; this.isSuffix = copyEffect.isSuffix; this.name = copyEffect.name; this.value = copyEffect.value; this.resourceCosts = copyEffect.resourceCosts; } /** * ResultSet Constructor */ public EffectsBase(ResultSet rs) throws SQLException { this.UUID = rs.getInt("ID"); this.IDString = rs.getString("IDString"); this.name = rs.getString("name"); this.token = rs.getInt("Token"); //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; } 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.dontSave = ((flags & 8) != 0) ? true : false; if (this.IDString.startsWith("PRE-")) this.isPrefix = true; else if (this.IDString.startsWith("SUF-")) this.isSuffix = true; // getFailConditions(); } public static String getItemEffectsByName(String string) { if (EffectsBase.itemEffectsByName.containsKey(string)) return EffectsBase.itemEffectsByName.get(string); return ""; } public static void addItemEffectsByName(String name, String ID) { EffectsBase.itemEffectsByName.put(name, ID); } public float getDamageAmount(int trains) { if (useRampAdd) return (amount + (amountRamp * trains)); else return (amount * (1 + (amountRamp * trains))); } // public String getName() { // return this.name; // } public boolean damageTypeSpecific() { return !this.effectDamageTypes.isEmpty(); } public boolean containsDamageType(mbEnums.DamageType dt) { return this.effectDamageTypes.contains(dt); } public int getUUID() { return this.UUID; } public String getIDString() { return this.IDString; } public int getToken() { return this.token; } //For Debugging purposes. public void setToken(int token) { this.token = token; } public HashSet getModifiers() { return this.effectModifiers; } public boolean isPrefix() { return this.isPrefix; } public boolean isSuffix() { return this.isSuffix; } public void startEffect(AbstractCharacter source, AbstractWorldObject awo, int trains, AbstractEffectJob effect) { // Add SourceTypes for dispel if (this.token != 0) { if (effect == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing FinishEffectTimeJob"); return; } // AbstractWorldObject source = effect.getSource(); if (source == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing source"); return; } PowersBase pb = effect.getPower(); if (pb == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing power"); return; } ActionsBase ab = effect.getAction(); if (ab == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing action"); return; } //don't send effect if dead, except for death shroud if (!awo.isAlive()) { if (pb.getToken() != 1672601862) return; } if (!effect.skipSendEffect()) { // float duration = (pb.isChant()) ? pb.getChantDuration() * 1000 : ab.getDuration(trains); float duration = ab.getDurationInSeconds(trains); if (pb.getToken() == 1672601862) { Effect eff = awo.getEffects().get("DeathShroud"); if (eff != null) { JobContainer jc = eff.getJobContainer(); if (jc != null) { duration = jc.timeOfExection() - System.currentTimeMillis(); duration *= .001f; } } } if (duration > 0f) { int removeToken = this.token; ApplyEffectMsg pum = new ApplyEffectMsg(); if (effect.getAction() != null) if (effect.getAction().getPowerAction() != null && PowersManager.ActionTokenByIDString.containsKey(effect.getAction().getPowerAction().getIDString())) try { removeToken = PowersManager.ActionTokenByIDString.get(effect.getAction().getPowerAction().getIDString()); } catch (Exception e) { removeToken = this.token; } pum.setEffectID(removeToken); pum.setSourceType(source.getObjectType().ordinal()); pum.setSourceID(source.getObjectUUID()); pum.setTargetType(awo.getObjectType().ordinal()); pum.setTargetID(awo.getObjectUUID()); pum.setNumTrains(trains); pum.setDuration((int) duration); // pum.setDuration((pb.isChant()) ? (int)pb.getChantDuration() : ab.getDurationInSeconds(trains)); pum.setPowerUsedID(pb.getToken()); pum.setPowerUsedName(pb.getName()); DispatchManager.sendToAllInRange(awo, pum); } if (awo.getObjectType().equals(GameObjectType.Item)) { if (source.charItemManager != null) { source.charItemManager.updateInventory(); } } } // call modifiers to do their job if (!effect.skipApplyEffect()) { for (AbstractEffectModifier em : this.getModifiers()) em.applyEffectModifier(source, awo, trains, effect); } } } // Send end effect message to client public void endEffect(AbstractWorldObject source, AbstractWorldObject awo, int trains, PowersBase pb, AbstractEffectJob effect) { if (awo == null) { Logger.error("endEffect(): Null AWO object passed in."); return; } if (pb == null) { Logger.error("endEffect(): Null PowerBase object passed in."); return; } if (!effect.skipCancelEffect() && !effect.isNoOverwrite()) { int sendToken = this.token; if (effect.getAction() != null) if (effect.getAction().getPowerAction() != null && PowersManager.ActionTokenByIDString.containsKey(effect.getAction().getPowerAction().getIDString())) try { sendToken = PowersManager.ActionTokenByIDString.get(effect.getAction().getPowerAction().getIDString()); } catch (Exception e) { sendToken = this.token; } ApplyEffectMsg pum = new ApplyEffectMsg(); pum.setEffectID(sendToken); if (source != null) { pum.setSourceType(source.getObjectType().ordinal()); pum.setSourceID(source.getObjectUUID()); } else { pum.setSourceType(0); pum.setSourceID(0); } pum.setTargetType(awo.getObjectType().ordinal()); pum.setTargetID(awo.getObjectUUID()); pum.setUnknown02(2); pum.setNumTrains(0); pum.setDuration(-1); pum.setPowerUsedID(pb.getToken()); pum.setPowerUsedName(pb.getName()); DispatchManager.sendToAllInRange(awo, pum); } } public void endEffectNoPower(int trains, AbstractEffectJob effect) { AbstractWorldObject source = effect.getSource(); if (source == null) return; if (!effect.skipCancelEffect() && !effect.isNoOverwrite()) { ApplyEffectMsg pum = new ApplyEffectMsg(); pum.setEffectID(this.token); pum.setSourceType(source.getObjectType().ordinal()); pum.setSourceID(source.getObjectUUID()); pum.setTargetType(source.getObjectType().ordinal()); pum.setTargetID(source.getObjectUUID()); pum.setUnknown02(2); pum.setNumTrains(0); pum.setDuration(-1); pum.setUnknown06((byte) 1); pum.setEffectSourceType(effect.getEffectSourceType()); pum.setEffectSourceID(effect.getEffectSourceID()); pum.setPowerUsedID(0); pum.setPowerUsedName(this.name); if (source.getObjectType() == GameObjectType.PlayerCharacter) { Dispatch dispatch = Dispatch.borrow((PlayerCharacter) source, pum); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); } } } public void sendEffect(AbstractEffectJob effect, int duration, ClientConnection conn) { if (effect == null && conn != null) return; if (conn == null) return; AbstractWorldObject source = effect.getSource(); AbstractWorldObject awo = effect.getTarget(); int trains = effect.getTrains(); if (source == null || awo == null) return; if (this.token != 0) { PowersBase pb = effect.getPower(); if (pb == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing power"); return; } ActionsBase ab = effect.getAction(); if (ab == null) { Logger.error("AbstractEffectModifier.applyEffectModifier: missing action"); return; } //don't send effect if dead, except for death shroud if (!awo.isAlive()) { if (pb.getToken() != 1672601862) return; } //duration for damage over times is (total time - (number of ticks x 5 seconds per tick)) if (effect instanceof DamageOverTimeJob) duration = ((DamageOverTimeJob) effect).getTickLength(); // float dur = (pb.isChant()) ? pb.getChantDuration() * 1000 : ab.getDuration(trains); float dur = ab.getDuration(trains); if (dur > 0f) { ApplyEffectMsg pum = new ApplyEffectMsg(); pum.setEffectID(this.token); pum.setSourceType(source.getObjectType().ordinal()); pum.setSourceID(source.getObjectUUID()); pum.setTargetType(awo.getObjectType().ordinal()); pum.setTargetID(awo.getObjectUUID()); pum.setNumTrains(trains); pum.setDuration(duration); pum.setPowerUsedID(pb.getToken()); pum.setPowerUsedName(pb.getName()); Dispatch dispatch = Dispatch.borrow(conn.getPlayerCharacter(), pum); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); } } } public void sendEffectNoPower(AbstractEffectJob effect, int duration, ClientConnection conn) { if (effect == null && conn != null) return; if (conn == null) return; AbstractWorldObject source = effect.getSource(); AbstractWorldObject awo = effect.getTarget(); int trains = effect.getTrains(); if (source == null || awo == null) return; if (this.token != 0) { //don't send effect if dead, except for death shroud if (!awo.isAlive()) { return; } //duration for damage over times is (total time - (number of ticks x 5 seconds per tick)) if (effect instanceof DamageOverTimeJob) duration = ((DamageOverTimeJob) effect).getTickLength(); else if (effect instanceof FinishSpireEffectJob) duration = 45; else if (effect instanceof NoTimeJob) duration = -1; // float dur = (pb.isChant()) ? pb.getChantDuration() * 1000 : ab.getDuration(trains); ApplyEffectMsg pum = new ApplyEffectMsg(); pum.setEffectID(this.token); pum.setSourceType(source.getObjectType().ordinal()); pum.setSourceID(source.getObjectUUID()); pum.setTargetType(source.getObjectType().ordinal()); pum.setTargetID(source.getObjectUUID()); pum.setUnknown06((byte) 1); pum.setEffectSourceType(effect.getEffectSourceType()); pum.setEffectSourceID(effect.getEffectSourceID()); pum.setNumTrains(trains); pum.setDuration(duration); pum.setPowerUsedID(0); pum.setPowerUsedName(this.name); Dispatch dispatch = Dispatch.borrow(conn.getPlayerCharacter(), pum); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); } } public boolean cancelOnAttack() { return this.cancelOnAttack; } public boolean cancelOnAttackSwing() { return this.cancelOnAttackSwing; } public boolean cancelOnCast() { return this.cancelOnCast; } public boolean cancelOnCastSpell() { return this.cancelOnCastSpell; } public boolean cancelOnEquipChange() { return this.cancelOnEquipChange; } public boolean cancelOnLogout() { return this.cancelOnLogout; } public boolean cancelOnMove() { return this.cancelOnMove; } public boolean cancelOnNewCharm() { return this.cancelOnNewCharm; } public boolean cancelOnSit() { return this.cancelOnSit; } public boolean cancelOnTakeDamage() { return this.cancelOnTakeDamage; } public boolean cancelOnTerritoryClaim() { return this.cancelOnTerritoryClaim; } public boolean cancelOnUnEquip() { return this.cancelOnUnEquip; } public String getName() { return name; } public void setName(String name) { this.name = name; } public static AbstractEffectModifier getCombinedModifiers(AbstractEffectModifier abstractEffectModifier, EffectModifier rs, EffectsBase effectBase, mbEnums.ModType modifier){ switch (modifier) { case AdjustAboveDmgCap: abstractEffectModifier = new AdjustAboveDmgCapEffectModifier(rs); break; case Ambidexterity: abstractEffectModifier = new AmbidexterityEffectModifier(rs); break; case AnimOverride: break; case ArmorPiercing: abstractEffectModifier = new ArmorPiercingEffectModifier(rs); break; case AttackDelay: abstractEffectModifier = new AttackDelayEffectModifier(rs); break; case Attr: abstractEffectModifier = new AttributeEffectModifier(rs); break; case BlackMantle: abstractEffectModifier = new BlackMantleEffectModifier(rs); break; case BladeTrails: abstractEffectModifier = new BladeTrailsEffectModifier(rs); break; case Block: abstractEffectModifier = new BlockEffectModifier(rs); break; case BlockedPowerType: abstractEffectModifier = new BlockedPowerTypeEffectModifier(rs); break; case CannotAttack: abstractEffectModifier = new CannotAttackEffectModifier(rs); break; case CannotCast: abstractEffectModifier = new CannotCastEffectModifier(rs); break; case CannotMove: abstractEffectModifier = new CannotMoveEffectModifier(rs); break; case CannotTrack: abstractEffectModifier = new CannotTrackEffectModifier(rs); break; case Charmed: abstractEffectModifier = new CharmedEffectModifier(rs); break; case ConstrainedAmbidexterity: abstractEffectModifier = new ConstrainedAmbidexterityEffectModifier(rs); break; case DamageCap: abstractEffectModifier = new DamageCapEffectModifier(rs); break; case DamageShield: abstractEffectModifier = new DamageShieldEffectModifier(rs); break; case DCV: abstractEffectModifier = new DCVEffectModifier(rs); break; case Dodge: abstractEffectModifier = new DodgeEffectModifier(rs); break; case DR: abstractEffectModifier = new DREffectModifier(rs); break; case Durability: abstractEffectModifier = new DurabilityEffectModifier(rs); break; case ExclusiveDamageCap: abstractEffectModifier = new ExclusiveDamageCapEffectModifier(rs); break; case Fade: abstractEffectModifier = new FadeEffectModifier(rs); break; case Fly: abstractEffectModifier = new FlyEffectModifier(rs); break; case Health: abstractEffectModifier = new HealthEffectModifier(rs); break; case HealthFull: abstractEffectModifier = new HealthFullEffectModifier(rs); break; case HealthRecoverRate: abstractEffectModifier = new HealthRecoverRateEffectModifier(rs); break; case IgnoreDamageCap: abstractEffectModifier = new IgnoreDamageCapEffectModifier(rs); break; case IgnorePassiveDefense: abstractEffectModifier = new IgnorePassiveDefenseEffectModifier(rs); break; case ImmuneTo: abstractEffectModifier = new ImmuneToEffectModifier(rs); break; case ImmuneToAttack: abstractEffectModifier = new ImmuneToAttackEffectModifier(rs); break; case ImmuneToPowers: abstractEffectModifier = new ImmuneToPowersEffectModifier(rs); break; case Invisible: abstractEffectModifier = new InvisibleEffectModifier(rs); break; case ItemName: abstractEffectModifier = new ItemNameEffectModifier(rs); if (((ItemNameEffectModifier) abstractEffectModifier).name.isEmpty()) break; if (effectBase != null) effectBase.setName((((ItemNameEffectModifier) abstractEffectModifier).name)); break; case Mana: abstractEffectModifier = new ManaEffectModifier(rs); break; case ManaFull: abstractEffectModifier = new ManaFullEffectModifier(rs); break; case ManaRecoverRate: abstractEffectModifier = new ManaRecoverRateEffectModifier(rs); break; case MaxDamage: abstractEffectModifier = new MaxDamageEffectModifier(rs); break; case MeleeDamageModifier: abstractEffectModifier = new MeleeDamageEffectModifier(rs); break; case MinDamage: abstractEffectModifier = new MinDamageEffectModifier(rs); break; case NoMod: abstractEffectModifier = new NoModEffectModifier(rs); break; case OCV: abstractEffectModifier = new OCVEffectModifier(rs); break; case Parry: abstractEffectModifier = new ParryEffectModifier(rs); break; case PassiveDefense: abstractEffectModifier = new PassiveDefenseEffectModifier(rs); break; case PowerCost: abstractEffectModifier = new PowerCostEffectModifier(rs); break; case PowerCostHealth: abstractEffectModifier = new PowerCostHealthEffectModifier(rs); break; case PowerDamageModifier: abstractEffectModifier = new PowerDamageEffectModifier(rs); break; case ProtectionFrom: abstractEffectModifier = new ProtectionFromEffectModifier(rs); break; case Resistance: abstractEffectModifier = new ResistanceEffectModifier(rs); break; case ScaleHeight: abstractEffectModifier = new ScaleHeightEffectModifier(rs); break; case ScaleWidth: abstractEffectModifier = new ScaleWidthEffectModifier(rs); break; case ScanRange: abstractEffectModifier = new ScanRangeEffectModifier(rs); break; case SeeInvisible: abstractEffectModifier = new SeeInvisibleEffectModifier(rs); break; case Silenced: abstractEffectModifier = new SilencedEffectModifier(rs); break; case Skill: abstractEffectModifier = new SkillEffectModifier(rs); break; case Slay: abstractEffectModifier = new SlayEffectModifier(rs); break; case Speed: abstractEffectModifier = new SpeedEffectModifier(rs); break; case SpireBlock: abstractEffectModifier = new SpireBlockEffectModifier(rs); break; case Stamina: abstractEffectModifier = new StaminaEffectModifier(rs); break; case StaminaFull: abstractEffectModifier = new StaminaFullEffectModifier(rs); break; case StaminaRecoverRate: abstractEffectModifier = new StaminaRecoverRateEffectModifier(rs); break; case Stunned: abstractEffectModifier = new StunnedEffectModifier(rs); break; case Value: abstractEffectModifier = new ValueEffectModifier(rs); if (effectBase != null) { ValueEffectModifier valueEffect = (ValueEffectModifier) abstractEffectModifier; effectBase.value = valueEffect.minMod; Item.addEnchantValue(effectBase.getIDString(), (int)valueEffect.minMod); } break; case WeaponProc: abstractEffectModifier = new WeaponProcEffectModifier(rs); break; case WeaponRange: abstractEffectModifier = new WeaponRangeEffectModifier(rs); break; case WeaponSpeed: abstractEffectModifier = new WeaponSpeedEffectModifier(rs); break; } return abstractEffectModifier; } }