Build EffectsBase from Effects.cfg

Effects, their fail conditions and source types come from
EffectTemplate. IDs are assigned at boot in file order. The power
actions that the server also keys as effects (item enchantment parents
and the action tokens sent in effect messages) are built from the
ApplyEffect/ApplyEffects/Invis actions with no Effects.cfg block: 776
keys, the 712 old registry rows plus 64 such as BRD-014A, which live
also sent.

Value changes (cfg wins): BRD-016A/PRS-031A lose the Chant source,
RUC-002A..004A lose Buff/Effect, and PRS-031A/RNG-037A no longer break
on Attack. Effect modifiers still load from the DB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-26 04:37:58 -04:00
1 parent f8d764b5f5
commit 27c59749fa
4 files changed
+189 -17

No files matched your search

+129
View File
@@ -28,8 +28,12 @@ import engine.objects.AbstractCharacter;
import engine.objects.AbstractWorldObject;
import engine.objects.Effect;
import engine.objects.PlayerCharacter;
import engine.parsers.objects.wpak.CurveRamp;
import engine.parsers.objects.wpak.EffectTemplate;
import engine.parsers.objects.wpak.PowerActionTemplate;
import engine.powers.effectmodifiers.AbstractEffectModifier;
import engine.server.MBServerStatics;
import engine.util.Hasher;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
@@ -123,6 +127,131 @@ public class EffectsBase {
// getFailConditions();
}
public EffectsBase(EffectTemplate effectTemplate, int id) {
this.UUID = id;
this.IDString = effectTemplate.effect_id;
this.name = effectTemplate.effect_name;
this.token = effectToken(this.IDString);
this.isItemEffect = effectTemplate.isitemeffect;
this.isSpireEffect = effectTemplate.isspireeffect;
this.ignoreMod = effectTemplate.ignorenomod;
this.dontSave = effectTemplate.dontsave;
this.isPrefix = this.IDString.startsWith("PRE-");
this.isSuffix = this.IDString.startsWith("SUF-");
loadFailConditions(effectTemplate.conditions);
loadSourceTypes(effectTemplate.sources);
}
// A power action with no Effects.cfg block that the server still keys as an effect:
// item enchantment parents (PRE-/SUF-/ARM-) and the action tokens sent in effect messages.
public EffectsBase(PowerActionTemplate powerActionTemplate, int id) {
this.UUID = id;
this.IDString = powerActionTemplate.action_id;
this.token = effectToken(this.IDString);
this.isPrefix = this.IDString.startsWith("PRE-");
this.isSuffix = this.IDString.startsWith("SUF-");
}
// INVIS-D and SafeMode show as the SafeModeB/A action tokens on the client
private static int effectToken(String IDString) {
switch (IDString) {
case "INVIS-D":
return Hasher.SBStringHash("SafeModeB");
case "SafeMode":
return Hasher.SBStringHash("SafeModeA");
default:
return Hasher.SBStringHash(IDString);
}
}
private void loadFailConditions(ArrayList<EffectTemplate.ConditionEntry> conditions) {
CurveRamp curveRamp;
if (conditions.isEmpty())
return;
if (!EffectsBase.EffectFailConditions.containsKey(this.IDString))
EffectsBase.EffectFailConditions.put(this.IDString, new HashSet<>());
for (EffectTemplate.ConditionEntry condition : conditions) {
EffectsBase.EffectFailConditions.get(this.IDString).add(condition.condition);
switch (condition.condition) {
case TakeDamage:
this.cancelOnTakeDamage = true;
this.amount = condition.amount;
curveRamp = (condition.curve == null) ? null : CurveRamp.fromCurve(condition.curve);
if (condition.curve != null && curveRamp == null)
Logger.warn("Effect " + this.IDString + " TakeDamage curve " + condition.curve + " has no ramp form");
this.amountRamp = (curveRamp == null) ? 0 : curveRamp.ramp;
this.useRampAdd = (curveRamp == null) || curveRamp.useAdd;
if (condition.damage_types.isEmpty())
break;
if (!EffectsBase.EffectDamageTypes.containsKey(this.token))
EffectsBase.EffectDamageTypes.put(this.token, new HashSet<>());
EffectsBase.EffectDamageTypes.get(this.token).addAll(condition.damage_types);
break;
case Attack:
this.cancelOnAttack = true;
break;
case AttackSwing:
this.cancelOnAttackSwing = true;
break;
case Cast:
this.cancelOnCast = true;
break;
case CastSpell:
this.cancelOnCastSpell = true;
break;
case EquipChange:
this.cancelOnEquipChange = true;
break;
case Logout:
this.cancelOnLogout = true;
break;
case Move:
this.cancelOnMove = true;
break;
case NewCharm:
this.cancelOnNewCharm = true;
break;
case Sit:
this.cancelOnSit = true;
break;
case TerritoryClaim:
this.cancelOnTerritoryClaim = true;
break;
case UnEquip:
this.cancelOnUnEquip = true;
break;
}
}
}
private void loadSourceTypes(ArrayList<String> sources) {
if (sources.isEmpty())
return;
if (!EffectsBase.effectSourceTypeMap.containsKey(this.token))
EffectsBase.effectSourceTypeMap.put(this.token, new HashSet<>());
for (String source : sources)
EffectsBase.effectSourceTypeMap.get(this.token).add(EffectSourceType.GetEffectSourceType(source));
}
public static void getFailConditions(HashMap<String, EffectsBase> effects) {
try (Connection connection = DbManager.getConnection();