Build power action lists from Powers.cfg ACTION= lines

ActionsBase(ActionEntry, powerID, id, powerAction) with the duration ramp
from CurveRamp; PowersManager.loadActionLists fills PowersBase.actions in
Powers.cfg order (ids 1..2278 + 10000), then the OPENGATE actions
(5001-5008, unchanged). StackType gains the 10 cfg stack types it lacked
and loses the DB-only ResistanceDebuff spelling.

Parity (JSON-Refactor-Plan/scripts/p49.py, dev export, every column):
2287 DB rows vs 2278 cfg lines; 1453/1455 powers have the same action
list; all curves have a ramp form, every action id exists.

Value changes (cfg wins):
- TRA-003..010 lose their DB OPENGATE row; the synthetic OPENGATE action
  was already added, so each gate power applied OPENGATE twice
- HFG-001 loses the DB-only third action HFG-001B (Str +25, attack
  delay -15, melee damage +15)
- SCT-004 applies SCT-004A (Speed SL0125Up, Buff/Effect) instead of
  RNG-033A (Speed SL0100Up, also Chant)
- durations: ALF-001A 180->60, COM-001A 60->30, FGM-002A/003A
  1800->900, RNG-033A 60->30
- stack priority: DEF/OFF/PRE/NOSTANCE A and B Always->GreaterThanOrEqualTo,
  BRD-016A and PRS-031A GreaterThan->GreaterThanOrEqualTo
- stack types: the 16 resist debuffs split from ResistanceDeBuff/
  ResistanceDebuff into Cold/Fire/Lightning/Holy/Unholy/Magic/Mental
  DeBuff (FUR-029A IgnoreStack->ElementalDeBuff), so debuffs of different
  elements now stack; HNT-023A..C StackableAttr*Buff->PersonalAttr*Buff
- IgnoreStack effect keys: action line ids follow cfg order (runtime only)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MagicBotandClaude Opus 5.5 committed 2026-10-26 10:20:34 -04:00
1 parent f44f1ca138
commit 2a19a85108
3 files changed
+84 -4

No files matched your search

+30 -3
View File
@@ -253,6 +253,35 @@ public enum PowersManager {
Logger.info("Loaded " + PowersManager.powersBaseByIDString.size() + " powers from Powers.cfg");
}
// ACTION= lines in Powers.cfg order, ids 1..n (offset in ActionsBase), then the OPENGATE actions
private static void loadActionLists() {
int actionID = 0;
PowersBase powersBase;
AbstractPowerAction powerAction;
for (PowerTemplate powerTemplate : PowerTemplate._powers.values()) {
powersBase = PowersManager.powersBaseByIDString.get(powerTemplate.power_id);
for (PowerTemplate.ActionEntry actionEntry : powerTemplate.actions) {
powerAction = PowersManager.powerActionsByIDString.get(actionEntry.action_id);
if (powerAction == null) {
Logger.error("Power " + powerTemplate.power_id + " lists unknown action " + actionEntry.action_id);
continue;
}
powersBase.getActions().add(new ActionsBase(actionEntry, powerTemplate.power_id, ++actionID, powerAction));
}
}
ActionsBase.addOpenGateActions(PowersManager.powersBaseByIDString);
Logger.info("Loaded " + actionID + " power action lines from Powers.cfg");
}
// The login server needs only the token map
public static void InitializeLoginPowers() {
loadPowers();
@@ -277,9 +306,7 @@ public enum PowersManager {
loadPowers();
// Add Actions Base
ActionsBase.getActionsBase(PowersManager.powersBaseByIDString,
PowersManager.powerActionsByIDString);
loadActionLists();
}
public static EffectsBase setEffectToken(int ID, int token) {
+10 -1
View File
@@ -1148,6 +1148,7 @@ public class mbEnums {
BMHealing,
Charm,
ClassBoon,
ColdDeBuff,
Confusion,
DamageAbsorber,
DamageDebuff,
@@ -1162,6 +1163,7 @@ public class mbEnums {
ElementalDeBuff,
EnchantWeapon,
Fear,
FireDeBuff,
Flight,
Frenzy,
GroupHeal,
@@ -1169,12 +1171,16 @@ public class mbEnums {
HealOverTime,
HealResBuff,
HealthPotion,
HolyDeBuff,
IgnoreStack,
Invisible,
LightningDeBuff,
MagicDeBuff,
ManaPotion,
MangonelFire,
MeleeDamageDeBuff,
MeleeDeBuff,
MentalDeBuff,
MoveBuff,
MoveDebuff,
NoFear,
@@ -1187,6 +1193,9 @@ public class mbEnums {
NoTrack,
PassiveDefense,
PersAttrSPRBuff,
PersonalAttrCONBuff,
PersonalAttrDEXBuff,
PersonalAttrSTRBuff,
PetBuff,
PierceResistanceDebuff,
PoisonBuchinine,
@@ -1209,7 +1218,6 @@ public class mbEnums {
RecoveryStaminaDeBuff,
ResistanceBuff,
ResistanceDeBuff,
ResistanceDebuff,
Root,
SafeMode,
SelfOneAttrBuff,
@@ -1233,6 +1241,7 @@ public class mbEnums {
Stun,
Track,
Transform,
UnholyDeBuff,
WeaponMove;
public static StackType GetStackType(String modName) {
+44
View File
@@ -16,6 +16,8 @@ import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.mbEnums.StackType;
import engine.objects.*;
import engine.parsers.objects.wpak.CurveRamp;
import engine.parsers.objects.wpak.PowerTemplate;
import engine.powers.poweractions.AbstractPowerAction;
import org.pmw.tinylog.Logger;
@@ -89,6 +91,43 @@ public class ActionsBase {
this.powerAction = apa.get(this.effectID);
}
public ActionsBase(PowerTemplate.ActionEntry actionEntry, String powerID, int id, AbstractPowerAction powerAction) {
CurveRamp durationRamp = CurveRamp.fromCurve(actionEntry.duration_curve);
if (durationRamp == null) {
Logger.warn("Power " + powerID + " action " + actionEntry.action_id + " duration curve "
+ actionEntry.duration_curve + " has no ramp form");
durationRamp = CurveRamp.NONE;
}
this.UUID = id + ACTION_ID_OFFSET;
this.IDString = powerID;
this.effectID = actionEntry.action_id;
this.minTrains = actionEntry.min_trains;
this.maxTrains = actionEntry.max_trains;
this.duration = actionEntry.duration;
this.ramp = durationRamp.ramp;
this.addFormula = durationRamp.useAdd;
this.stackType = actionEntry.stack_type;
this.stackTypeType = StackType.GetStackType(this.stackType);
this.stackOrder = actionEntry.stack_order;
this.stackPriority = actionEntry.stack_priority.name();
switch (actionEntry.stack_priority) {
case GreaterThanOrEqualTo:
this.greaterThanEqual = true;
break;
case Always:
this.always = true;
break;
case GreaterThan:
this.greaterThan = true;
break;
}
this.powerAction = powerAction;
}
protected ActionsBase(int uUID, String effectID, int minTrains, int maxTrains, float duration, float ramp,
boolean addFormula, String stackType, int stackOrder, boolean greaterThanEqual, boolean always,
boolean greaterThan, AbstractPowerAction powerAction) {
@@ -162,6 +201,11 @@ public class ActionsBase {
Logger.error(e.toString());
}
addOpenGateActions(powers);
}
public static void addOpenGateActions(HashMap<String, PowersBase> powers) {
int gateID = 5000;
for (String IDString : Runegate.GetAllOpenGateIDStrings()) {