Build the creation talent maps from the runes
AllowedRaceRunesMap and AllowedBaseClassRunesMap now come from TALENT runes with rune_is_standard_character_creation, using item_race_req and item_class_req (restrict true = blacklist, false = whitelist) over the creation race runes (2000-2029) and class runes (2500-2503). Every creation race and class gets an explicit list, so the 111111 sentinel is no longer used. static_rune_racerune / baseclassrune loaders stay until 2.11. Eight flagged runes that are not in CharCreateRuneList.cfg ATTRRUNES are left out: 2910 Wolfpack Developer, 2911 QA Test Rune, the unused duplicates 250116/250117/250123/250124/250125, and 250081 Proficient with Bows (commented out in the cfg). Parity (offline, scripts/p26.py): 84 talents, the same as the DB apart from these value changes, all decided JSON (2026-10-22): - 250081 Proficient with Bows: no longer accepted at creation (DB: any race/class) - 250088 Raised by Barbarians: Elf, Irekei lose it - 250089 Raised by Centaurs: Elf loses it - 250092 Raised by Thieves' Guild: Dwarf loses it - 250093 Raised in the Woods: female Irekei loses it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
26aa8de86c
commit
85bc807260
1 file changed
+82
-2
@@ -22,6 +22,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
@@ -29,6 +30,9 @@ public class RuneBase extends AbstractGameObject {
|
||||
|
||||
public static HashMap<Integer, ArrayList<Integer>> AllowedBaseClassRunesMap = new HashMap<>();
|
||||
public static HashMap<Integer, ArrayList<Integer>> AllowedRaceRunesMap = new HashMap<>();
|
||||
// Flagged rune_is_standard_character_creation but missing from CharCreateRuneList.cfg ATTRRUNES:
|
||||
// admin runes 2910/2911, unused duplicates, and Proficient with Bows (commented out in the cfg).
|
||||
private static final Set<Integer> NON_CREATION_TALENTS = Set.of(2910, 2911, 250081, 250116, 250117, 250123, 250124, 250125);
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final int type;
|
||||
@@ -215,8 +219,84 @@ public class RuneBase extends AbstractGameObject {
|
||||
|
||||
Logger.info("Loaded " + loadedCount + " rune bases from runes");
|
||||
|
||||
RuneBase.AllowedBaseClassRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS();
|
||||
RuneBase.AllowedRaceRunesMap = DbManager.RuneBaseQueries.LOAD_ALLOWED_STARTING_RUNES_FOR_RACE();
|
||||
loadCreationTalents();
|
||||
}
|
||||
|
||||
// Every creation race and class gets a list, so the 111111 "any" sentinel of the DB tables is no longer used.
|
||||
|
||||
private static void loadCreationTalents() {
|
||||
|
||||
ArrayList<Integer> creationRaceIDs = new ArrayList<>();
|
||||
ArrayList<Integer> creationClassIDs = new ArrayList<>();
|
||||
ArrayList<Integer> listedRaceIDs;
|
||||
ArrayList<Integer> listedClassIDs;
|
||||
Integer classRuneID;
|
||||
boolean listed;
|
||||
boolean allowed;
|
||||
int talentCount = 0;
|
||||
|
||||
AllowedRaceRunesMap = new HashMap<>();
|
||||
AllowedBaseClassRunesMap = new HashMap<>();
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (!rune.rune_is_standard_character_creation)
|
||||
continue;
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.RACE) {
|
||||
creationRaceIDs.add(rune.template_id);
|
||||
AllowedRaceRunesMap.put(rune.template_id, new ArrayList<>());
|
||||
}
|
||||
|
||||
if (rune.rune_type == mbEnums.RuneType.CLASS) {
|
||||
creationClassIDs.add(rune.template_id);
|
||||
AllowedBaseClassRunesMap.put(rune.template_id, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
for (RuneTemplate rune : RuneTemplate._runes.values()) {
|
||||
|
||||
if (!rune.rune_is_standard_character_creation || rune.rune_type != mbEnums.RuneType.TALENT)
|
||||
continue;
|
||||
|
||||
if (NON_CREATION_TALENTS.contains(rune.template_id))
|
||||
continue;
|
||||
|
||||
listedRaceIDs = new ArrayList<>();
|
||||
listedClassIDs = new ArrayList<>();
|
||||
|
||||
for (mbEnums.MonsterType raceType : rune.item_race_req)
|
||||
listedRaceIDs.addAll(CObjectIndex.getRaceRuneIds(raceType));
|
||||
|
||||
for (mbEnums.ClassType classType : rune.item_class_req) {
|
||||
classRuneID = CObjectIndex.getClassRuneId(classType);
|
||||
|
||||
if (classRuneID != null)
|
||||
listedClassIDs.add(classRuneID);
|
||||
}
|
||||
|
||||
// restrict true = blacklist, false = whitelist (ArcItemRestrict_Check 0x4BAC60)
|
||||
for (int raceRuneID : creationRaceIDs) {
|
||||
listed = listedRaceIDs.contains(raceRuneID);
|
||||
allowed = rune.item_race_req_restrict ? !listed : listed;
|
||||
|
||||
if (allowed)
|
||||
AllowedRaceRunesMap.get(raceRuneID).add(rune.template_id);
|
||||
}
|
||||
|
||||
for (int baseClassID : creationClassIDs) {
|
||||
listed = listedClassIDs.contains(baseClassID);
|
||||
allowed = rune.item_class_req_restrict ? !listed : listed;
|
||||
|
||||
if (allowed)
|
||||
AllowedBaseClassRunesMap.get(baseClassID).add(rune.template_id);
|
||||
}
|
||||
|
||||
talentCount++;
|
||||
}
|
||||
|
||||
Logger.info("Loaded " + talentCount + " creation talents for " + creationRaceIDs.size() + " races and "
|
||||
+ creationClassIDs.size() + " classes from runes");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in new issue
Block a user