Replace talents by sub type and rank, cap talents at 8
Follows the client's ArcCharacter_AddRune (0x4695D0, specs/RuneRequirements.md): a talent replaces a held talent with the same non-zero rune_sub_type when its rank is 0 or higher than the held rank; otherwise the apply fails. With no talent to replace, a new talent needs fewer than 8 held talents. RuneBase gets runeType, a sub type token (SBStringHash(rune_sub_type), or the stored hash) and rank from the rune. It no longer copies the static_rune_runereq type 5 overwrite list, and ApplyRuneMsg no longer reads it. Value changes: - Stat chains (*MaxIncrease) replace the same ranks as before; the DB typos go away (250026 listed 250019 twice and missed 250018) - Talents in the same group now replace each other when applied from a runestone (e.g. Bloodline sub-race talents); before, both were added - Limit: 8 talents instead of more than 12 runes of any kind - Rank-0 downgrade (decided: follow the client) takes effect in the next commit, when the DB stat-chain blocks leave the discipline map Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
8f87778c43
commit
c3f1861cf7
2 files changed
+57
-12
No files matched your search
@@ -14,6 +14,7 @@ import engine.mbEnums;
|
||||
import engine.net.ByteBufferWriter;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import engine.util.Hasher;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
@@ -38,6 +39,9 @@ public class RuneBase extends AbstractGameObject {
|
||||
private final ArrayList<Integer> overwrite = new ArrayList<>();
|
||||
private int levelRequired = 1;
|
||||
private ArrayList<MobBaseEffects> effectsList = new ArrayList<>();
|
||||
private mbEnums.RuneType runeType;
|
||||
private int subTypeToken;
|
||||
private int rank;
|
||||
|
||||
/**
|
||||
* No Table ID Constructor
|
||||
@@ -84,6 +88,7 @@ public class RuneBase extends AbstractGameObject {
|
||||
* 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 requirement maps and effects until 2.5b/2.10.
|
||||
* Talents with the same sub type token replace each other by rank (client 0x4695D0), so no overwrite list.
|
||||
*/
|
||||
public RuneBase(RuneTemplate rune, RuneBase dbRuneBase) {
|
||||
super(rune.template_id);
|
||||
@@ -96,9 +101,16 @@ public class RuneBase extends AbstractGameObject {
|
||||
this.baseClass.putAll(dbRuneBase.baseClass);
|
||||
this.promotionClass.putAll(dbRuneBase.promotionClass);
|
||||
this.discipline.putAll(dbRuneBase.discipline);
|
||||
this.overwrite.addAll(dbRuneBase.overwrite);
|
||||
this.levelRequired = dbRuneBase.levelRequired;
|
||||
this.effectsList = dbRuneBase.effectsList;
|
||||
this.runeType = rune.rune_type;
|
||||
this.rank = rune.rune_rank;
|
||||
|
||||
// Same token as CObjectIndex: unresolved sub types are stored as their hash
|
||||
if (!rune.rune_sub_type.isEmpty())
|
||||
this.subTypeToken = Hasher.SBStringHash(rune.rune_sub_type);
|
||||
else
|
||||
this.subTypeToken = rune.rune_sub_type_hash;
|
||||
}
|
||||
|
||||
public static RuneBase getRuneBase(int tableId) {
|
||||
@@ -241,6 +253,19 @@ public class RuneBase extends AbstractGameObject {
|
||||
return this.overwrite;
|
||||
}
|
||||
|
||||
public mbEnums.RuneType getRuneType() {
|
||||
return this.runeType;
|
||||
}
|
||||
|
||||
// 0 when the rune has no sub type; talents sharing a non-zero token replace each other
|
||||
public int getSubTypeToken() {
|
||||
return this.subTypeToken;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return this.rank;
|
||||
}
|
||||
|
||||
/*
|
||||
* Serializing
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user