Skip to content

Commit

Permalink
Merge pull request dmdorman#1429 from aeauseth/main
Browse files Browse the repository at this point in the history
Initial support for OIHID
  • Loading branch information
aeauseth authored Nov 11, 2024
2 parents b00e5b6 + 2a0d38e commit 0a5311d
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Version 4.0.6 (So far...) [Hero System 6e (Unofficial) v2](https://github.com/dmdorman/hero6e-foundryvtt)

- Migrations are no longer supported from versions before 3.0.76. Migrate through any version prior to 4.0.6 if you find your world in this situation.
- Initial support for Only In Heroic ID. There is a checkbox on the OTHER tab. Powers/skills with OIHID will be disabled when not in heroic ID. (#232)(https://github.com/dmdorman/hero6e-foundryvtt/issues/232)

## Version 4.0.5

Expand Down
65 changes: 19 additions & 46 deletions module/actor/actor-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class HeroSystemActorSheet extends ActorSheet {
/** @override */
async getData() {
const data = super.getData();
data.system = data.actor.system;

try {
// Show an unsupported actor warning when the sheet opens. An actor can be unsupported if:
Expand Down Expand Up @@ -267,14 +268,6 @@ export class HeroSystemActorSheet extends ActorSheet {
);
await pdAttack._postUpload();

let {
defenseValue: _defenseValuePD,
resistantValue: _resistantValuePD /*impenetrableValue*/,
//damageReductionValue: _damageReductionValuePD,
//damageNegationValue: _damageNegationValuePD /*knockbackResistance*/,
// defenseTags: defenseTagsP,
} = determineDefense(this.actor, pdAttack, { suppressDeprecationWarn: true });

// New PD
const {
defenseValue: defenseValuePD,
Expand All @@ -283,12 +276,6 @@ export class HeroSystemActorSheet extends ActorSheet {
damageNegationValue: damageNegationValuePD,
defenseTags: defenseTagsPD,
} = getActorDefensesVsAttack(this.actor, pdAttack);
if (_defenseValuePD != defenseValuePD) {
console.warn("PD Defense mismatch", _defenseValuePD, defenseValuePD);
}
if (_resistantValuePD != resistantValuePD) {
console.warn("rPD Defense mismatch", _resistantValuePD, resistantValuePD);
}
defense.PD = defenseValuePD;
for (const tag of defenseTagsPD.filter((o) => o.operation === "add" && !o.options?.resistant)) {
defense.PDtags = `${defense.PDtags || ""}${tag.value.signedString()} ${tag.name} ${tag.shortDesc}\n`;
Expand Down Expand Up @@ -317,14 +304,6 @@ export class HeroSystemActorSheet extends ActorSheet {
);
await edAttack._postUpload();

let {
defenseValue: _defenseValueED,
resistantValue: _resistantValueED /* impenetrableValueE */,
//damageReductionValue: _damageReductionValueED,
//damageNegationValue: _damageNegationValueED /* knockbackResistanceE */,
// defenseTags: _defenseTagsE,
} = determineDefense(this.actor, edAttack, { suppressDeprecationWarn: true });

// New ED
const {
defenseValue: defenseValueED,
Expand All @@ -333,12 +312,6 @@ export class HeroSystemActorSheet extends ActorSheet {
damageNegationValue: damageNegationValueED,
defenseTags: defenseTagsED,
} = getActorDefensesVsAttack(this.actor, edAttack);
if (_defenseValueED != defenseValueED) {
console.warn("ED Defense mismatch", _defenseValueED, defenseValueED);
}
if (_resistantValueED != resistantValueED) {
console.warn("rED Defense mismatch", _defenseValueED, defenseValueED);
}
defense.ED = defenseValueED;
for (const tag of defenseTagsED.filter((o) => o.operation === "add" && !o.options?.resistant)) {
defense.EDtags = `${defense.EDtags || ""}${tag.value.signedString()} ${tag.name} ${tag.shortDesc}\n`;
Expand Down Expand Up @@ -368,14 +341,6 @@ export class HeroSystemActorSheet extends ActorSheet {
);
await mdAttack._postUpload();

let {
defenseValue: _defenseValueMD,
//resistantValue: _resistantValueMD /*impenetrableValueM*/,
//damageReductionValue: _damageReductionValueMD,
//damageNegationValue: _damageNegationValueMD /*knockbackResistanceM*/,
defenseTags: _defenseTagsMD,
} = determineDefense(this.actor, mdAttack, { suppressDeprecationWarn: true });

// New MD
const {
defenseValue: defenseValueMD,
Expand All @@ -384,9 +349,6 @@ export class HeroSystemActorSheet extends ActorSheet {
damageNegationValue: damageNegationValueMD,
defenseTags: defenseTagsMD,
} = getActorDefensesVsAttack(this.actor, mdAttack);
if (_defenseValueMD != defenseValueMD) {
console.warn("MD Defense mismatch", _defenseValueMD, defenseValueMD, _defenseTagsMD);
}
defense.MD = defenseValueMD;
for (const tag of defenseTagsMD.filter((o) => o.operation === "add" && !o.options?.resistant)) {
defense.MDtags = `${defense.MDtags || ""}${tag.value.signedString()} ${tag.name} ${tag.shortDesc}\n`;
Expand Down Expand Up @@ -461,7 +423,7 @@ export class HeroSystemActorSheet extends ActorSheet {
(o) => (o.system.subType || o.type) === "defense" && !o.effects.size,
);
for (let d of defensePowers) {
d.disabled = !d.system.active;
d.disabled = !d.isActive;
switch (getPowerInfo({ xmlid: d.system.XMLID, actor: this.actor })?.duration) {
case "instant":
// Might Vary
Expand Down Expand Up @@ -849,9 +811,12 @@ export class HeroSystemActorSheet extends ActorSheet {
}

/** @override */
async _updateObject(_event, formData) {
async _updateObject(event, formData) {
event.preventDefault();

let expandedData = foundry.utils.expandObject(formData);

// Left Sidebar of actor sheet has Xsystem characteristics
const characteristics = getCharacteristicInfoArrayForActor(this.actor).filter((o) =>
["BODY", "STUN", "END"].includes(o.key),
);
Expand All @@ -867,28 +832,36 @@ export class HeroSystemActorSheet extends ActorSheet {
}
}

// EndReserve
// Left Sidebar may have EndReserve
if (expandedData.endReserve) {
const endReserveId = Object.keys(expandedData.endReserve)?.[0];
const endReserve = this.actor.items.find((o) => o.id === endReserveId);
if (endReserve) {
await endReserve.update({ "system.value": parseInt(expandedData.endReserve[endReserveId].value || 0) });
}
}
console.log(formData);

this.options.itemFilters.power = expandedData.itemFilters.power;
this.options.itemFilters.skill = expandedData.itemFilters.skill;
this.options.itemFilters.equipment = expandedData.itemFilters.equipment;

await this.actor.update(expandedData);
// If core characteristics changed the re-calculate costs
let recalculateCosts = false;
for (const char of Object.keys(expandedData.system.characteristics)) {
if (this.actor.system.characteristics[char].core !== expandedData.system.characteristics[char].core) {
recalculateCosts = true;
}
}

// Do all the standard things like updating item properties that match the name of input boxes
await super._updateObject(event, formData);

if (expandedData.system.characteristics) {
if (recalculateCosts) {
await this.actor.calcCharacteristicsCost();
await this.actor.CalcActorRealAndActivePoints();
}

this.render();
await this.render();
}

async _onItemRoll(event) {
Expand Down
53 changes: 48 additions & 5 deletions module/actor/actor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,42 @@ export class HeroSystem6eActor extends Actor {
await this.update(changes);
}

// Heroic ID
if (data.system?.heroicIdentity !== undefined) {
// Loop thru all the active effects, checking if source has OIHID
const allEffects = await this.allApplicableEffects();
for (const ae of allEffects) {
const item = ae.parent;
if (!item) continue;
if (item instanceof HeroSystem6eItem === false) continue;
if (item.findModsByXmlid("OIHID")) {
await ae.update({ disabled: !data.system.heroicIdentity });

// Modify characteristics as appropriate
for (const change of ae.changes) {
if (change.key.match(/max$/) && change.mode === 2 && change.value > 0) {
const valueKey = change.key.replace(/.max$/, ".value");
let max = this;
valueKey.split(".").forEach((subPath) => {
max = max[subPath] || null;
});
if (parseInt(max || 0) > 0) {
if (ae.disabled) {
await this.update({
[valueKey]: max - parseInt(change.value),
});
} else {
await this.update({
[valueKey]: max + parseInt(change.value),
});
}
}
}
}
}
}
}

// Display changes from _preUpdate
for (let d of options.displayScrollingChanges) {
this._displayScrollingChange(d.value, d.options);
Expand Down Expand Up @@ -804,7 +840,7 @@ export class HeroSystem6eActor extends Actor {
(o) =>
o.system.XMLID === "PENALTY_SKILL_LEVELS" &&
o.system.penalty === "encumbrance" &&
(o.type === "skill" || o.system.active),
(o.type === "skill" || o.isActive),
)) {
dcvDex = Math.min(0, dcvDex + parseInt(pslEncumbrance.system.LEVELS));
}
Expand Down Expand Up @@ -922,7 +958,7 @@ export class HeroSystem6eActor extends Actor {
// 0 on movement and DCV occur 5 points of STR
// sooner.
const massMultiplier = this.items
.filter((o) => o.system.XMLID === "DENSITYINCREASE" && o.system.active)
.filter((o) => o.system.XMLID === "DENSITYINCREASE" && o.isActive)
.reduce((p, a) => p + parseInt(a.system.LEVELS), 0);
const minStr = massMultiplier * 5;

Expand Down Expand Up @@ -1233,7 +1269,7 @@ export class HeroSystem6eActor extends Actor {

getActiveConstantItems() {
let results = [];
for (let item of this.items.filter((o) => o.system.active)) {
for (let item of this.items.filter((o) => o.isActive)) {
let duration = getPowerInfo({
xmlid: item.system.XMLID,
actor: this,
Expand Down Expand Up @@ -1999,6 +2035,13 @@ export class HeroSystem6eActor extends Actor {
await this.update({ [`system.is5e`]: this.system.is5e });
}

// ONLY IN ALTERNATE IDENTITY (OIAID)
// Assume we are in our super/heroic identity
if (this.system.heroicIdentity === undefined) {
this.system.heroicIdentity = false;
changes[`system.heroicIdentity`] = true;
}

// isHeroic
// Need to be a careful as there are custom templates ('Nekhbet Vulture Child Goddess')
// that we are unlikely able to decode heroic status.
Expand Down Expand Up @@ -2295,7 +2338,7 @@ export class HeroSystem6eActor extends Actor {

// Hero Designer appears to store WEIGHT as LBS instead of KG.
const equipment = this.items.filter(
(o) => o.type === "equipment" && (o.parentItem ? o.parentItem.system.active : o.system.active),
(o) => o.type === "equipment" && (o.parentItem ? o.parentItem.isActive : o.isActive),
);
const weightLbs = equipment.reduce((a, b) => a + parseFloat(b.system?.WEIGHT || 0), 0);
const weightKg = (weightLbs / 2.2046226218) * equipmentWeightPercentage;
Expand All @@ -2304,7 +2347,7 @@ export class HeroSystem6eActor extends Actor {
}

get netWorth() {
const equipment = this.items.filter((o) => o.type === "equipment" && o.system.active);
const equipment = this.items.filter((o) => o.type === "equipment" && o.isActive);
const price = equipment.reduce((a, b) => a + parseFloat(b.system.PRICE), 0);
return price.toFixed(2);
}
Expand Down
8 changes: 6 additions & 2 deletions module/combat.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ export class HeroSystem6eCombat extends Combat {

for (const powerUsingResourcesToContinue of combatant.actor.items.filter(
(item) =>
item.system.active === true && // Is the power active?
item.isActive === true && // Is the power active?
item.baseInfo.duration !== "instant" && // Is the power non instant
((parseInt(item.system.end || 0) > 0 && // Does the power use END?
!item.system.MODIFIER?.find((o) => o.XMLID === "COSTSEND" && o.OPTION === "ACTIVATE")) || // Does the power use END continuously?
Expand Down Expand Up @@ -541,7 +541,11 @@ export class HeroSystem6eCombat extends Combat {
if (content !== "" && (spentResources.totalEnd > 0 || spentResources.charges > 0)) {
const segment = this.combatant.flags.segment;

content = `Spent ${spentResources.end} END, ${spentResources.reserveEnd} reserve END, and ${spentResources.charges} charge${spentResources.charges > 1 ? "s" : ""} on turn ${this.round} segment ${segment}:<ul>${content}</ul>`;
content = `Spent ${spentResources.end} END, ${spentResources.reserveEnd} reserve END, and ${
spentResources.charges
} charge${spentResources.charges > 1 ? "s" : ""} on turn ${
this.round
} segment ${segment}:<ul>${content}</ul>`;

const token = combatant.token;
const speaker = ChatMessage.getSpeaker({
Expand Down
2 changes: 1 addition & 1 deletion module/herosystem6e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ Hooks.on("updateWorldTime", async (worldTime, options) => {
for (const aeWithCharges of actor.temporaryEffects.filter((o) =>
o.parent instanceof HeroSystem6eItem ? o.parent.findModsByXmlid("CONTINUING") : false,
)) {
if (!aeWithCharges.parent.system.active) {
if (!aeWithCharges.parent.isActive) {
console.error(`${aeWithCharges.name} is inactive and will not expire.`);
continue;
}
Expand Down
Loading

0 comments on commit 0a5311d

Please sign in to comment.