#Gestalt
1 messages · Page 1 of 1 (latest)
Makes sense
So, your actor has still double their level in hit dice?
Yup, for some reason
module.json has the new javascript in, it's in a separate file
Putting this in for future reference #dnd5e message
I’ll grab the whole thing and paste it in here in a few. When you say module.json, how exactly is your module set up?
{
"id": "gestalt-support",
"esmodules": [
"Experience.js",
"LevelOverride.js",
"HitDiceOverride.js"
],
"title": "Gestalt Support",
"version": "1.0.0",
"compatibility": {
"minimum": "13",
"verified": "13"
},
"flags": {
"canUpload": true
},
"packs": [
{
"name": "gestalt-classes-custom",
"label": "Gestalt Classes",
"path": "packs/gestalt-classes-custom",
"type": "Item",
"ownership": {
"PLAYER": "OBSERVER",
"ASSISTANT": "OWNER"
},
"system": "dnd5e",
"flags": {}
}
],
"relationships": {
"requires": [
{
"id": "alches-stuff",
"type": "module",
"compatibility": {}
}
]
},
"description": ""
}
Ah. And in HitDiceOverride do you have BOTH lines in the init hook? Because you shouldn't - I have them both because I have my level and hit dice thing in the same file
Oh, I was wondering if it was that
So I tried putting bits into the LevelOverride but it still didn't work, probably cause I pasted it in wrong
Yep - that new file isn't running because it's got an error. Walking the dog but in a few I’ll grab the full code and paste it here
🫡
In the meantime I'll take out the duplicate line and see if it works
Cool, it does
// GESTALT
Hooks.on("init", () => {
dnd5e.dataModels.actor.config.character = CharacterDataGestalt;
dnd5e.dataModels.item.config.class = ClassDataGestalt;
});
Hooks.on("dnd5e.computeLeveledProgression", (progression, actor, cls, spellcasting, count) => {
// Stop if already did this type of caster
if (count > 1 && progression.slot > 0) return false;
const allProgressions = Object.values(actor.spellcastingClasses).map(i => i.spellcasting?.progression).filter(i => i);
// Anything's better than third
if (spellcasting.progression === "third" && allProgressions.some(i => i !== "third")) return false;
// Otherwise go for it, unless "full" is out there
if (spellcasting.progression !== "full" && allProgressions.includes("full")) return false;
});
class CharacterDataGestalt extends dnd5e.dataModels.actor.CharacterData {
prepareBaseData() {
this.attributes.hd = new dnd5e.documents.HitDice(this.parent);
this.details.level = 0;
this.attributes.attunement.value = 0;
for ( const item of this.parent.items ) {
const canAttune = !item.system.validProperties?.has?.("mgc") || item.system.properties?.has?.("mgc");
if ( item.system.attuned && canAttune ) this.attributes.attunement.value += 1;
if ( item.type === "class" ) this.details.level += item.system.levels;
}
// THIS IS THE GESTALT LINE
this.details.level = Math.floor(this.details.level / 2);
this.attributes.prof = dnd5e.documents.Proficiency.calculateMod(this.details.level);
const { xp, level } = this.details;
xp.max = level >= CONFIG.DND5E.maxLevel ? Infinity : this.parent.getLevelExp(level || 1);
xp.min = level ? this.parent.getLevelExp(level - 1) : 0;
if ( Number.isFinite(xp.max) ) {
const required = xp.max - xp.min;
const pct = Math.round((xp.value - xp.min) * 100 / required);
xp.pct = Math.clamp(pct, 0, 100);
} else if ( game.settings.get("dnd5e", "levelingMode") === "xpBoons" ) {
const overflow = xp.value - this.parent.getLevelExp(CONFIG.DND5E.maxLevel);
xp.boonsEarned = Math.max(0, Math.floor(overflow / CONFIG.DND5E.epicBoonInterval));
const progress = overflow - (CONFIG.DND5E.epicBoonInterval * xp.boonsEarned);
xp.pct = Math.clamp(Math.round((progress / CONFIG.DND5E.epicBoonInterval) * 100), 0, 100);
} else {
xp.pct = 100;
}
dnd5e.dataModels.actor.AttributesFields.prepareBaseArmorClass.call(this);
dnd5e.dataModels.actor.AttributesFields.prepareBaseEncumbrance.call(this);
}
}
class ClassDataGestalt extends dnd5e.dataModels.item.ClassData {
prepareFinalData() {
super.prepareFinalData();
if (!this.parent.actor) return;
const maxHdSize = Math.max(...this.parent.actor.system.attributes.hd.sizes);
const bestClass = Object.values(this.parent.actor.classes).find(i => Number(i.system.hd.denomination.slice(1)) === maxHdSize);
if (bestClass === this.parent) return;
this.hd.max = Math.max(0, this.hd.additional);
this.hd.value = Math.max(this.hd.max - this.hd.spent, 0);
}
}
Awesome - yeah, I kept it this way because if for whatever reason something were to give "additional" hit dice to the rogue class, you'll get them. It's just the base "same-as-level" amount you don't get
Makes sense, good for compatibility
Wait, I think I did paste it in like that and it didn't work for me
Eh, if it works, it works
Confirmed it works
Might've been some letter duplicated or deleted or something
Probably
Right, so character level and proficiency bonus sorted out, hit dice and hit points sorted out, spellcaster progression sorted out
I don't think there's anything else that Gestalt changes innately
Yeah, the only thing to keep in mind is what I mentioned before about "on this overall level you get X" stuff, since you'll become level 3 twice for instance
Experience Gain is optional depending on what rule you use and can be done through an array (for someone reading, reference this #dnd5e message), what you get from which class is also dependent on the rule and can be modified inside the class itself, that should be it
Oh, true
That's as easy as just having them delete the second version of the granted advancement though
Exactly
So that's not much of a problem, just gotta remember to do it
Oh, one problem that's left but is kind of there because of my own implementation is with consumption
Nevermind, it does work as it should actually
I was worried that when dragging the whole class folder from one compendium to another, the class would reference items from the new one, but thankfully it doesn't, so nothing should break as long as the old compendium still exists
@cloud bear I think the proficiency bonus is broken
You get to +3 after reaching character level 3, then to +4 on reaching character level 11, and +5 on level 19
I tested on a world with only the gestalt module activated in case it was some sort of module conflict, but the issue's still there
Hmm. In my world it seems to be working. Level 3 (3 monk, 3 rogue) has +2 proficiency
something else is modifying proficiency
Yeah
ohhhh
Pfffft
You still had the old override Jeff mentioned didn't you
No worries
