Load player rune effects from item_user_power_action instead of static_npc_mobbase_effects
MobBaseEffects.getEffectsForRune builds each rune's list from the RUNE JSON on first use and caches it: exact repeats are dropped (54 rune files list their effects twice), the action id resolves to its effect through PowerActions.cfg, token = SBStringHash(effect id), rank = arg 0, reqLvl = arg 1. Used by Race, BaseClass, PromotionClass and RuneBase; MobBase stays on GET_RUNEBASE_EFFECTS until Task 3.4. Parity (scripts/p210b.py, token level): 1074 runes match. Differences: - Tireless, Tough as Nails, Taint of Madness: JSON action TRT-* resolves to the same effect the DB stores; no change - CSR 2901-2904, 2906, 2908, 2910, 2911, Non-Aggro Rune 252624: DB token was the NoNPCAggro action (no effect found, skipped); now NONPCAGGRO, which has no mods; no gameplay change - Mob-only 12021/12022 NECROPETSTATS and 13236 PEACE are server rows on the MobBase path, untouched Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
098f5d2c38
commit
13e02707eb
5 files changed
+66
-9
No files matched your search
@@ -104,7 +104,7 @@ public class BaseClass extends AbstractGameObject {
|
||||
this.staminaMod = rs.getInt("staminaMod");
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public class BaseClass extends AbstractGameObject {
|
||||
this.staminaMod = rune.rune_stamina;
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
}
|
||||
|
||||
public static void LoadAllBaseClasses() {
|
||||
|
||||
@@ -9,12 +9,23 @@
|
||||
|
||||
package engine.objects;
|
||||
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.parsers.objects.UserPowerAction;
|
||||
import engine.parsers.objects.wpak.PowerActionTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class MobBaseEffects {
|
||||
|
||||
private static final ConcurrentHashMap<Integer, ArrayList<MobBaseEffects>> effectsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private int mobBaseID;
|
||||
private int token;
|
||||
private int rank;
|
||||
@@ -30,6 +41,52 @@ public class MobBaseEffects {
|
||||
this.reqLvl = rs.getInt("reqLvl");
|
||||
}
|
||||
|
||||
public MobBaseEffects(int token, int rank, int reqLvl) {
|
||||
this.token = token;
|
||||
this.rank = rank;
|
||||
this.reqLvl = reqLvl;
|
||||
}
|
||||
|
||||
public static ArrayList<MobBaseEffects> getEffectsForRune(int runeID) {
|
||||
return effectsByRune.computeIfAbsent(runeID, MobBaseEffects::loadEffectsForRune);
|
||||
}
|
||||
|
||||
// item_user_power_action entries are {action id, [rank, reqLvl]}; the action names the effect to apply
|
||||
private static ArrayList<MobBaseEffects> loadEffectsForRune(int runeID) {
|
||||
|
||||
ArrayList<MobBaseEffects> runeEffects = new ArrayList<>();
|
||||
HashSet<String> seenEntries = new HashSet<>();
|
||||
RuneTemplate rune = RuneTemplate._runes.get(runeID);
|
||||
PowerActionTemplate powerAction;
|
||||
String effectID;
|
||||
int rank;
|
||||
int reqLvl;
|
||||
|
||||
if (rune == null)
|
||||
return runeEffects;
|
||||
|
||||
for (UserPowerAction userPowerAction : rune.item_user_power_action) {
|
||||
|
||||
rank = userPowerAction.arguments.length > 0 ? userPowerAction.arguments[0] : 0;
|
||||
reqLvl = userPowerAction.arguments.length > 1 ? userPowerAction.arguments[1] : 0;
|
||||
|
||||
// 54 rune files repeat their whole list; the DB kept each entry once
|
||||
if (!seenEntries.add(userPowerAction.power + ":" + rank + ":" + reqLvl))
|
||||
continue;
|
||||
|
||||
powerAction = PowerActionTemplate._powerActions.get(userPowerAction.power);
|
||||
|
||||
if (powerAction != null && !powerAction.effect_ids.isEmpty())
|
||||
effectID = powerAction.effect_ids.get(0);
|
||||
else
|
||||
effectID = userPowerAction.power;
|
||||
|
||||
runeEffects.add(new MobBaseEffects(Hasher.SBStringHash(effectID), rank, reqLvl));
|
||||
}
|
||||
|
||||
return runeEffects;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the mobBaseID
|
||||
|
||||
@@ -103,7 +103,7 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.effectsGrantedHealer = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2501);
|
||||
this.effectsGrantedRogue = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2502);
|
||||
this.effectsGrantedMage = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2503);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
|
||||
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.effectsGrantedHealer = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2501);
|
||||
this.effectsGrantedRogue = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2502);
|
||||
this.effectsGrantedMage = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2503);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
}
|
||||
|
||||
// Promotions are the CLASS runes that require a base class; this skips the creation classes and Pet 2522.
|
||||
|
||||
@@ -110,7 +110,7 @@ public class Race {
|
||||
this.baseClasses = DbManager.BaseClassQueries.GET_BASECLASS_FOR_RACE(raceRuneID);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.raceRuneID);
|
||||
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ public class Race {
|
||||
this.baseClasses = getBaseClassesForRace(rune);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.raceRuneID);
|
||||
|
||||
// Races without hair styles (Aracoix, Shade) select style 0, which creation validates
|
||||
if (this.hairStyles.isEmpty())
|
||||
|
||||
@@ -93,13 +93,13 @@ public class RuneBase extends AbstractGameObject {
|
||||
// static_rune_runereq race/class rows are whitelists, its discipline rows prohibitions
|
||||
this.discRestrict = true;
|
||||
DbManager.RuneBaseQueries.GET_RUNE_REQS(this);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(this.getObjectUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rune Template Constructor
|
||||
* type and subtype are server enums that don't map cleanly from rune_type/rune_sub_type, so they
|
||||
* come from the static_rune_runebase row, as do the effects until 2.10.
|
||||
* come from the static_rune_runebase row.
|
||||
* Talents with the same sub type token replace each other by rank (client 0x4695D0), so no overwrite list.
|
||||
*/
|
||||
public RuneBase(RuneTemplate rune, RuneBase dbRuneBase) {
|
||||
@@ -114,7 +114,7 @@ public class RuneBase extends AbstractGameObject {
|
||||
this.description = rune.rune_dsc;
|
||||
this.type = dbRuneBase.type;
|
||||
this.subtype = dbRuneBase.subtype;
|
||||
this.effectsList = dbRuneBase.effectsList;
|
||||
this.effectsList = MobBaseEffects.getEffectsForRune(rune.template_id);
|
||||
this.runeType = rune.rune_type;
|
||||
this.rank = rune.rune_rank;
|
||||
this.levelRequired = rune.item_level_req;
|
||||
|
||||
Reference in new issue
Block a user