Files
Server/src/engine/parsers/objects/wpak/PowerTemplate.java
T
MagicBotandClaude Opus 5.5 bd145b1e55 Load Powers.cfg at world boot
PowerParser loads Powers.cfg into PowerTemplate._powers. The 22 header
fields are named after the client loader's error messages (0x56E410);
ACTION= lines keep trains, duration, curve and stack fields; prereqs,
curves, flags, messages and CONDITION blocks are kept. Keys compare
case-insensitively, as in the client. Four keys the client ignores
(APPLYDAMAGESELF=, APPLYEFFECTCASTER=, APPLYEFFECTTARGET= and a
POWEREND= typo) are skipped; any other unknown key fails the load.

Numbers are read like the client's atoi/atof with a warning when a
token isn't clean: PRL-033 init time "2.9.0" -> 2.9 and SGE-001
precision "10.0" -> 10, which matches the DB. Ten EQPREREQ lines end
without a required flag, which the client reads as 0.

Needs the fixed Powers.cfg (SRDX-DB header had "SPELL 15 Unknown"
pasted twice; fixed in MBDATA, findings section 6).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:19:14 -04:00

133 lines
4.9 KiB
Java

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.parsers.objects.wpak;
import engine.mbEnums;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
// One POWERBEGIN block of Powers.cfg (client loader 0x56E410).
// Header field names follow the client's "<field> Error with line" messages.
// KEY= lines map to the lower-case fields named after them.
//
// Read only once loaded.
public class PowerTemplate {
public static HashMap<String, PowerTemplate> _powers = new HashMap<>();
// Header: 22 tokens
public String power_id;
public String power_name;
public mbEnums.PowerType power_type;
public int icon_number;
public String focus;
public mbEnums.PowerTargetType target_type;
public float range;
public mbEnums.AreaType area_type;
public float area_range;
public mbEnums.ExcludeType exclude_type;
public mbEnums.CostType cost_type;
public float cost_amt;
public int difficulty;
public int precision;
public float init_time;
public float release_time;
public float recycle_time;
public boolean hit_roll_yn;
public mbEnums.CastingModeType casting_mode;
public int init_anim;
public int release_anim;
public mbEnums.TargetSelectType target_sel;
// Keys
public final ArrayList<ActionEntry> actions = new ArrayList<>();
public int maxlevel;
public float hatevalue;
public String hatevalue_curve;
public String grantoverridevar;
public mbEnums.PowerCategoryType category;
public final ArrayList<EquipPrereq> eqprereqs = new ArrayList<>();
public final ArrayList<mbEnums.MonsterType> monstertypeprereqs = new ArrayList<>();
public final ArrayList<mbEnums.MonsterType> monstertyperestricts = new ArrayList<>();
public final ArrayList<EffectPrereq> targeteffectprereqs_anded = new ArrayList<>();
public final ArrayList<EffectPrereq> targeteffectprereqs_ored = new ArrayList<>();
public final ArrayList<EffectPrereq> effectprereqs = new ArrayList<>();
// CURVE= <COSTAMT|INITTIME|RECYCLETIME> <curve>: the curve applied to that header value
public final LinkedHashMap<String, String> curves = new LinkedHashMap<>();
public final ArrayList<String> descriptions = new ArrayList<>();
public int loopanimid;
public boolean bladetrails;
public boolean cancastwhilemoving;
public boolean cancastwhileflying;
public boolean shouldcheckpath;
public boolean isadminpower;
public boolean cantargetadmin;
public boolean isprojectile;
public boolean sticky;
public int maxnummobtargets;
public int maxnumplayertargets;
public float pulseinfo_duration;
public int pulseinfo_iterations;
public final ArrayList<Integer> sounds = new ArrayList<>();
public int casterspulseparticle;
public final ArrayList<EffectTemplate.ConditionEntry> conditions = new ArrayList<>();
public String initstring;
public String successself;
public String successother;
public String fizzleself;
public String fizzleother;
public String applyeffectself;
public String applyeffectother;
public String wearoffeffectself;
public String wearoffeffectother;
public String applydamagecaster;
public String applydamagetarget;
public String applydamageother;
// ACTION= <action_id> <min_trains> <max_trains> <duration> <duration_curve> <stack_type>
// <stack_order> <stack_priority>, then up to four optional pairs kept only in args
public static class ActionEntry {
public String action_id;
public int min_trains;
public int max_trains;
public float duration;
public String duration_curve;
public String stack_type;
public int stack_order;
public mbEnums.CategoryToPowerType stack_priority;
public final ArrayList<String> args = new ArrayList<>();
}
// EQPREREQ= repeats <slot> <skill> <required>
public static class EquipPrereq {
public mbEnums.EquipSlotType slot;
public String skill;
public boolean required;
}
public static class EffectPrereq {
public String effect_id;
public int value;
public String message;
}
}