#49 Ziehbare Items

Changes:
 + Items können jetzt zwischen Charakteren ausgetauscht werden (Nur Gegenstände, keine Zauber etc.)
 + Items können Sortiert werden durch verziehen und droppen

Sneak Change:
 + Löschen button für mods hinzugefügt
 + ESLint und Prettier hinzugefügt, sorry für all die changes :D
This commit is contained in:
2024-02-22 15:24:39 +01:00
parent 06ef797ef2
commit 023b924421
397 changed files with 21631 additions and 9145 deletions
+159 -157
View File
@@ -1,226 +1,228 @@
import { BooleanField } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/fields.mjs";
export interface M5Skill {
fw: number;
attribute: string;
pp: number;
fw: number;
attribute: string;
pp: number;
}
export interface M5SkillUnlearned extends M5Skill {
initial: number;
initial: number;
}
export interface M5SkillLearned extends M5Skill {
skill: string;
type: string;
skill: string;
type: string;
}
export interface M5SkillCalculated extends M5Skill {
label: string;
calc: any;
label: string;
calc: any;
}
export interface M5Attribute {
value: number;
bonus: number;
value: number;
bonus: number;
}
export interface M5RollData {
c: any;
i: any;
iType: string;
rolls: {};
res: {
label: string;
};
c: any;
i: any;
iType: string;
rolls: {};
res: {
label: string;
};
}
export interface M5RollTemplate {
formula: string;
label: string;
enabled: boolean;
formula: string;
label: string;
enabled: boolean;
}
export interface M5RollResult extends M5RollTemplate {
total: number;
totalStr: string;
result: string;
dice: {};
css: string;
total: number;
totalStr: string;
result: string;
dice: {};
css: string;
}
export enum M5ItemType {
SKILL = "skill",
ITEM = "item",
WEAPON = "weapon",
DEFENSIVE_WEAPON = "defensiveWeapon",
ARMOR = "armor",
CONTAINER = "container",
SPELL = "spell",
KAMPFKUNST = "kampfkunst",
EFFECT = "effect",
SKILL = "skill",
ITEM = "item",
WEAPON = "weapon",
DEFENSIVE_WEAPON = "defensiveWeapon",
ARMOR = "armor",
CONTAINER = "container",
SPELL = "spell",
KAMPFKUNST = "kampfkunst",
EFFECT = "effect",
}
export enum M5SkillType {
INNATE = "innate",
GENERAL = "general",
LANGUAGE = "language",
COMBAT = "combat",
INNATE = "innate",
GENERAL = "general",
LANGUAGE = "language",
COMBAT = "combat",
}
export enum M5EwResult {
TBD = "",
FUMBLE = "roll-ew-result-fumble",
CRITICAL = "roll-ew-result-critical",
HIGH = "roll-ew-result-high",
FAIL = "roll-ew-result-fail",
PASS = "roll-ew-result-pass",
TBD = "",
FUMBLE = "roll-ew-result-fumble",
CRITICAL = "roll-ew-result-critical",
HIGH = "roll-ew-result-high",
FAIL = "roll-ew-result-fail",
PASS = "roll-ew-result-pass",
}
export enum M5Attributes {
ST = "st",
GW = "gw",
GS = "gs",
KO = "ko",
IN = "in",
ZT = "zt",
AU = "au",
PA = "pa",
WK = "wk",
ST = "st",
GW = "gw",
GS = "gs",
KO = "ko",
IN = "in",
ZT = "zt",
AU = "au",
PA = "pa",
WK = "wk",
}
export enum M5Stats {
DEFENSE = "defenseBonus",
ATTACK = "attackBonus",
DAMAGE = "damageBonus",
MOVEMENT = "movement",
RESISTANCE_MIND = "resistanceMind",
RESISTANCE_BODY = "resistanceBody",
SPELL_CASTING = "spellCasting",
BRAWL = "brawl",
POISON_RESISTANCE = "poisonResistance",
LP = "lp",
AP = "ap",
PROTECTION_LP = "lpProtection",
PROTECTION_AP = "apProtection",
PERCEPTION = "perception",
DRINKING = "drinking",
HOARD = "hoard",
HOARD_NEXT = "hoardNext",
HOARD_MIN = "hoardMin",
WEALTH = "wealth",
DEFENSE = "defenseBonus",
ATTACK = "attackBonus",
DAMAGE = "damageBonus",
MOVEMENT = "movement",
RESISTANCE_MIND = "resistanceMind",
RESISTANCE_BODY = "resistanceBody",
SPELL_CASTING = "spellCasting",
BRAWL = "brawl",
POISON_RESISTANCE = "poisonResistance",
LP = "lp",
AP = "ap",
PROTECTION_LP = "lpProtection",
PROTECTION_AP = "apProtection",
PERCEPTION = "perception",
DRINKING = "drinking",
HOARD = "hoard",
HOARD_NEXT = "hoardNext",
HOARD_MIN = "hoardMin",
WEALTH = "wealth",
}
export enum M5ModType {
ATTRIBUTE = "attribute",
STAT = "stat",
SKILL = "skill",
ATTRIBUTE = "attribute",
STAT = "stat",
SKILL = "skill",
}
export enum M5ModOperation {
ADD_100 = "add100",
ROLL = "roll",
ADD = "add",
SET = "set",
FIXED = "fixed",
MULTIPLY = "multiply",
SUBTRACT = "subtract",
DIVISION = "division",
ADD_100 = "add100",
ROLL = "roll",
ADD = "add",
SET = "set",
FIXED = "fixed",
MULTIPLY = "multiply",
SUBTRACT = "subtract",
DIVISION = "division",
}
export enum M5TimeUnit {
ROUND = "round",
MINUTE = "minute",
HOUR = "hour",
LIMITLESS = "limitless",
ROUND = "round",
MINUTE = "minute",
HOUR = "hour",
LIMITLESS = "limitless",
}
export interface M5ItemMod {
type: M5ModType;
id: string;
operation: M5ModOperation;
value: number;
type: M5ModType;
id: string;
operation: M5ModOperation;
value: number;
}
export interface M5ModPair {
mod: M5ItemMod;
source: string;
mod: M5ItemMod;
source: string;
}
export interface M5ModSource {
item: string;
operation: M5ModOperation;
value: number;
item: string;
operation: M5ModOperation;
value: number;
}
export interface M5ModResult {
mods: Array<M5ModSource>;
value: number;
mods: Array<M5ModSource>;
value: number;
}
export interface M5AttributeCalculated extends M5ModResult {
bonus: number;
bonus: number;
}
export interface M5CharacterCalculatedData {
level: number;
attributes: {
st: M5AttributeCalculated;
gs: M5AttributeCalculated;
gw: M5AttributeCalculated;
ko: M5AttributeCalculated;
in: M5AttributeCalculated;
zt: M5AttributeCalculated;
au: M5AttributeCalculated;
pa: M5AttributeCalculated;
wk: M5AttributeCalculated;
};
stats: {
lp: M5ModResult;
ap: M5ModResult;
lpProtection: M5ModResult;
apProtection: M5ModResult;
defense: M5ModResult;
damageBonus: M5ModResult;
attackBonus: M5ModResult;
defenseBonus: M5ModResult;
movement: M5ModResult;
resistanceMind: M5ModResult;
resistanceBody: M5ModResult;
spellCasting: M5ModResult;
brawl: M5ModResult;
brawlFw: number;
poisonResistance: M5ModResult;
enduranceBonus: number;
perception: M5ModResult;
perceptionFW: number;
drinking: M5ModResult;
drinkingFW: number;
hoard: number;
hoardNext: number;
hoardMin: number;
wealth: number;
};
skillMods: {};
skills: {
innate: {};
general: {};
combat: {};
language: {};
custom: {};
};
gear: {
weapons: {};
defensiveWeapons: {};
armor: {};
items: {};
containers: {};
effects: {};
};
spells: {};
kampfkuenste: {};
level: number;
attributes: {
st: M5AttributeCalculated;
gs: M5AttributeCalculated;
gw: M5AttributeCalculated;
ko: M5AttributeCalculated;
in: M5AttributeCalculated;
zt: M5AttributeCalculated;
au: M5AttributeCalculated;
pa: M5AttributeCalculated;
wk: M5AttributeCalculated;
};
stats: {
lp: M5ModResult;
ap: M5ModResult;
lpProtection: M5ModResult;
apProtection: M5ModResult;
defense: M5ModResult;
damageBonus: M5ModResult;
attackBonus: M5ModResult;
defenseBonus: M5ModResult;
movement: M5ModResult;
resistanceMind: M5ModResult;
resistanceBody: M5ModResult;
spellCasting: M5ModResult;
brawl: M5ModResult;
brawlFw: number;
poisonResistance: M5ModResult;
enduranceBonus: number;
perception: M5ModResult;
perceptionFW: number;
drinking: M5ModResult;
drinkingFW: number;
hoard: number;
hoardNext: number;
hoardMin: number;
wealth: number;
};
skillMods: {};
skills: {
innate: {};
general: {};
combat: {};
language: {};
custom: {};
};
gear: {
weapons: {};
defensiveWeapons: {};
armor: {};
items: {};
containers: {};
effects: {};
};
spells: {};
kampfkuenste: {};
}
export function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
return Object.keys(obj).filter((k) => Number.isNaN(+k)) as K[];
export function enumKeys<O extends object, K extends keyof O = keyof O>(
obj: O,
): K[] {
return Object.keys(obj).filter((k) => Number.isNaN(+k)) as K[];
}
File diff suppressed because it is too large Load Diff
+424 -143
View File
@@ -1,172 +1,453 @@
import { M5Attribute, M5AttributeCalculated, M5Attributes, M5CharacterCalculatedData, M5ItemMod, M5ModOperation, M5ModResult, M5ModSource, M5ModType, M5Stats, M5ModPair } from "../M5Base";
import {
M5Attribute,
M5AttributeCalculated,
M5Attributes,
M5CharacterCalculatedData,
M5ItemMod,
M5ModOperation,
M5ModResult,
M5ModSource,
M5ModType,
M5Stats,
M5ModPair,
} from '../M5Base';
export default class M5ModAggregate {
private attributes = new Map<string, Array<M5ModPair>>();
private stats = new Map<string, Array<M5ModPair>>();
private skills = new Map<string, Array<M5ModPair>>();
private attributes = new Map<string, Array<M5ModPair>>();
private stats = new Map<string, Array<M5ModPair>>();
private skills = new Map<string, Array<M5ModPair>>();
constructor(public data: any, public calc: M5CharacterCalculatedData) {
const characterString = (game as Game).i18n.localize("TYPES.Actor.character");
constructor(
public data: any,
public calc: M5CharacterCalculatedData
) {
const characterString = (game as Game).i18n.localize('TYPES.Actor.character');
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.SET, value: data.attributes.st.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.SET, value: data.attributes.gs.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.SET, value: data.attributes.gw.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.SET, value: data.attributes.ko.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.SET, value: data.attributes.in.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.SET, value: data.attributes.zt.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.SET, value: data.attributes.au.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.SET, value: data.attributes.pa.value }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.SET, value: data.attributes.wk.value }, characterString);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ST,
operation: M5ModOperation.SET,
value: data.attributes.st.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.GS,
operation: M5ModOperation.SET,
value: data.attributes.gs.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.GW,
operation: M5ModOperation.SET,
value: data.attributes.gw.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.KO,
operation: M5ModOperation.SET,
value: data.attributes.ko.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.IN,
operation: M5ModOperation.SET,
value: data.attributes.in.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ZT,
operation: M5ModOperation.SET,
value: data.attributes.zt.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.AU,
operation: M5ModOperation.SET,
value: data.attributes.au.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.PA,
operation: M5ModOperation.SET,
value: data.attributes.pa.value,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.WK,
operation: M5ModOperation.SET,
value: data.attributes.wk.value,
},
characterString
);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ST, operation: M5ModOperation.ADD_100, value: data.attributes.st.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GS, operation: M5ModOperation.ADD_100, value: data.attributes.gs.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.GW, operation: M5ModOperation.ADD_100, value: data.attributes.gw.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.KO, operation: M5ModOperation.ADD_100, value: data.attributes.ko.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.IN, operation: M5ModOperation.ADD_100, value: data.attributes.in.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.ZT, operation: M5ModOperation.ADD_100, value: data.attributes.zt.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.AU, operation: M5ModOperation.ADD_100, value: data.attributes.au.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.PA, operation: M5ModOperation.ADD_100, value: data.attributes.pa.bonus }, characterString);
this.push({ type: M5ModType.ATTRIBUTE, id: M5Attributes.WK, operation: M5ModOperation.ADD_100, value: data.attributes.wk.bonus }, characterString);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ST,
operation: M5ModOperation.ADD_100,
value: data.attributes.st.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.GS,
operation: M5ModOperation.ADD_100,
value: data.attributes.gs.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.GW,
operation: M5ModOperation.ADD_100,
value: data.attributes.gw.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.KO,
operation: M5ModOperation.ADD_100,
value: data.attributes.ko.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.IN,
operation: M5ModOperation.ADD_100,
value: data.attributes.in.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ZT,
operation: M5ModOperation.ADD_100,
value: data.attributes.zt.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.AU,
operation: M5ModOperation.ADD_100,
value: data.attributes.au.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.PA,
operation: M5ModOperation.ADD_100,
value: data.attributes.pa.bonus,
},
characterString
);
this.push(
{
type: M5ModType.ATTRIBUTE,
id: M5Attributes.WK,
operation: M5ModOperation.ADD_100,
value: data.attributes.wk.bonus,
},
characterString
);
this.push({ type: M5ModType.STAT, id: M5Stats.DEFENSE, operation: M5ModOperation.SET, value: calc.stats.defenseBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.ATTACK, operation: M5ModOperation.SET, value: calc.stats.attackBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DAMAGE, operation: M5ModOperation.SET, value: calc.stats.damageBonus.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.MOVEMENT, operation: M5ModOperation.SET, value: calc.stats.movement.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_MIND, operation: M5ModOperation.SET, value: calc.stats.resistanceMind.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.RESISTANCE_BODY, operation: M5ModOperation.SET, value: calc.stats.resistanceBody.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.SPELL_CASTING, operation: M5ModOperation.SET, value: calc.stats.spellCasting.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.BRAWL, operation: M5ModOperation.SET, value: calc.stats.brawl.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.POISON_RESISTANCE, operation: M5ModOperation.SET, value: calc.stats.poisonResistance.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.LP, operation: M5ModOperation.SET, value: calc.stats.lp.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.AP, operation: M5ModOperation.SET, value: calc.stats.ap.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_LP, operation: M5ModOperation.SET, value: calc.stats.lpProtection.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.PROTECTION_AP, operation: M5ModOperation.SET, value: calc.stats.apProtection.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.PERCEPTION, operation: M5ModOperation.SET, value: calc.stats.perception.value }, characterString);
this.push({ type: M5ModType.STAT, id: M5Stats.DRINKING, operation: M5ModOperation.SET, value: calc.stats.drinking.value }, characterString);
}
this.push(
{
type: M5ModType.STAT,
id: M5Stats.DEFENSE,
operation: M5ModOperation.SET,
value: calc.stats.defenseBonus.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.ATTACK,
operation: M5ModOperation.SET,
value: calc.stats.attackBonus.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.DAMAGE,
operation: M5ModOperation.SET,
value: calc.stats.damageBonus.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.MOVEMENT,
operation: M5ModOperation.SET,
value: calc.stats.movement.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.RESISTANCE_MIND,
operation: M5ModOperation.SET,
value: calc.stats.resistanceMind.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.RESISTANCE_BODY,
operation: M5ModOperation.SET,
value: calc.stats.resistanceBody.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.SPELL_CASTING,
operation: M5ModOperation.SET,
value: calc.stats.spellCasting.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.BRAWL,
operation: M5ModOperation.SET,
value: calc.stats.brawl.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.POISON_RESISTANCE,
operation: M5ModOperation.SET,
value: calc.stats.poisonResistance.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.LP,
operation: M5ModOperation.SET,
value: calc.stats.lp.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.AP,
operation: M5ModOperation.SET,
value: calc.stats.ap.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.PROTECTION_LP,
operation: M5ModOperation.SET,
value: calc.stats.lpProtection.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.PROTECTION_AP,
operation: M5ModOperation.SET,
value: calc.stats.apProtection.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.PERCEPTION,
operation: M5ModOperation.SET,
value: calc.stats.perception.value,
},
characterString
);
this.push(
{
type: M5ModType.STAT,
id: M5Stats.DRINKING,
operation: M5ModOperation.SET,
value: calc.stats.drinking.value,
},
characterString
);
}
push(mod: M5ItemMod, source: string) {
if (!mod?.id || mod.id === "") return;
push(mod: M5ItemMod, source: string) {
if (!mod?.id || mod.id === '') return;
let map: Map<string, Array<M5ModPair>> = null;
if (mod.type === M5ModType.ATTRIBUTE) map = this.attributes;
else if (mod.type === M5ModType.STAT) map = this.stats;
else if (mod.type === M5ModType.SKILL) map = this.skills;
let map: Map<string, Array<M5ModPair>> = null;
if (mod.type === M5ModType.ATTRIBUTE) map = this.attributes;
else if (mod.type === M5ModType.STAT) map = this.stats;
else if (mod.type === M5ModType.SKILL) map = this.skills;
if (map) {
const pair: M5ModPair = {
mod: mod,
source: source,
};
if (map) {
const pair: M5ModPair = {
mod: mod,
source: source,
};
if (map.has(mod.id)) map.get(mod.id).push(pair);
else map.set(mod.id, [pair]);
}
}
if (map.has(mod.id)) map.get(mod.id).push(pair);
else map.set(mod.id, [pair]);
}
}
calculate() {
const calc = this.calc;
calculate() {
const calc = this.calc;
this.attributes.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs);
calc.attributes[id] = {
value: res.value,
bonus: M5ModAggregate.attributeBonus(res.value),
mods: res.mods,
} as M5AttributeCalculated;
//console.log("calc.attributes." + id, calc.attributes[id])
});
this.attributes.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs);
calc.attributes[id] = {
value: res.value,
bonus: M5ModAggregate.attributeBonus(res.value),
mods: res.mods,
} as M5AttributeCalculated;
//console.log("calc.attributes." + id, calc.attributes[id])
});
this.stats.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs);
calc.stats[id] = res;
});
this.stats.forEach((pairs, id) => {
const res = M5ModAggregate.processPairs(pairs);
calc.stats[id] = res;
});
const ret = {};
this.skills.forEach((pairs, id) => {
ret[id] = pairs;
});
const ret = {};
this.skills.forEach((pairs, id) => {
ret[id] = pairs;
});
return ret;
}
return ret;
}
static pairAsSource(pair: M5ModPair): M5ModSource {
return {
operation: pair.mod.operation,
value: pair.mod.value,
item: pair.source,
};
}
static pairAsSource(pair: M5ModPair): M5ModSource {
return {
operation: pair.mod.operation,
value: pair.mod.value,
item: pair.source,
};
}
static processPairs(arr: Array<M5ModPair>): M5ModResult {
let ret: M5ModResult = {
mods: [],
value: 0,
};
static processPairs(arr: Array<M5ModPair>): M5ModResult {
let ret: M5ModResult = {
mods: [],
value: 0,
};
let mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.FIXED).sort((a, b) => b.mod.value - a.mod.value);
let pair = mods.length === 0 ? null : mods[0];
let mods = arr
.filter(pair => pair.mod.operation === M5ModOperation.FIXED)
.sort((a, b) => b.mod.value - a.mod.value);
let pair = mods.length === 0 ? null : mods[0];
if (pair) {
ret.mods.push(this.pairAsSource(pair));
ret.value = pair.mod.value;
} else {
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.SET).sort((a, b) => b.mod.value - a.mod.value);
if (mods.length !== 0) {
ret.mods.push(this.pairAsSource(mods[0]));
ret.value = mods[0].mod.value;
}
if (pair) {
ret.mods.push(this.pairAsSource(pair));
ret.value = pair.mod.value;
} else {
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.SET).sort((a, b) => b.mod.value - a.mod.value);
if (mods.length !== 0) {
ret.mods.push(this.pairAsSource(mods[0]));
ret.value = mods[0].mod.value;
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.ADD_100);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.min(100, Math.max(0, ret.value + bonus));
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.ADD_100);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.min(100, Math.max(0, ret.value + bonus));
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.ADD);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.max(0, ret.value + bonus);
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.ADD);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = Math.max(0, ret.value + bonus);
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.SUBTRACT);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = ret.value - bonus;
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.SUBTRACT);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a + b, 0);
ret.value = ret.value - bonus;
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.MULTIPLY);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, ret.value * bonus);
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.MULTIPLY);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, ret.value * bonus);
}
mods = arr.filter((pair) => pair.mod.operation === M5ModOperation.DIVISION);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map((p) => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, Math.floor(ret.value / bonus));
}
}
mods = arr.filter(pair => pair.mod.operation === M5ModOperation.DIVISION);
if (mods.length !== 0) {
ret.mods = ret.mods.concat(mods.map(this.pairAsSource));
const bonus = mods.map(p => p.mod.value).reduce((a, b) => a * b, 1);
ret.value = Math.max(0, Math.floor(ret.value / bonus));
}
}
return ret;
}
return ret;
}
static attributeMinMax(attribute: M5Attribute) {
return Math.min(100, Math.max(0, attribute.value + attribute.bonus));
}
static attributeMinMax(attribute: M5Attribute) {
return Math.min(100, Math.max(0, attribute.value + attribute.bonus));
}
static attributeBonus(value: number) {
if (value > 95) return 2;
if (value > 80) return 1;
if (value > 20) return 0;
if (value > 5) return -1;
return -2;
}
static attributeBonus(value: number) {
if (value > 95) return 2;
if (value > 80) return 1;
if (value > 20) return 0;
if (value > 5) return -1;
return -2;
}
//static modToString(mod: M5ItemMod): string { }
//static modToString(mod: M5ItemMod): string { }
}
+405 -300
View File
@@ -1,335 +1,440 @@
import { M5Character } from "../actors/M5Character";
import M5ModAggregate from "../actors/M5ModAggregate";
import { enumKeys, M5Attributes, M5ModOperation, M5ModPair, M5ModType, M5RollData, M5RollResult, M5Stats } from "../M5Base";
import { M5Roll } from "../rolls/M5Roll";
import { M5Character } from '../actors/M5Character';
import M5ModAggregate from '../actors/M5ModAggregate';
import {
enumKeys,
M5Attributes,
M5ModOperation,
M5ModPair,
M5ModType,
M5RollData,
M5RollResult,
M5Stats,
} from '../M5Base';
import { M5Roll } from '../rolls/M5Roll';
export class M5Item extends Item {
static readonly SKILL = "skill";
static readonly SKILL = 'skill';
prepareDerivedData() {
const itemId: string = (this as any).id;
const itemType: string = (this as any).type;
const actor = this.actor as any;
const character = actor as M5Character;
const itemData = (this as any).system;
const calc = itemData.calc;
prepareDerivedData() {
const itemId: string = (this as any).id;
const itemType: string = (this as any).type;
const actor = this.actor as any;
const character = actor as M5Character;
const itemData = (this as any).system;
const calc = itemData.calc;
if (itemType === "item") {
calc.containers = null;
if (itemType === 'item') {
calc.containers = null;
if (actor) {
const actorCalc = actor.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === "skill") {
calc.fw = itemData.fw;
calc.bonus = 0;
if (actor) {
const actorCalc = actor.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === 'skill') {
calc.fw = itemData.fw;
calc.bonus = 0;
let pairs: Array<M5ModPair> = [
{
source: (this as any).name,
mod: {
type: M5ModType.SKILL,
id: itemId,
operation: M5ModOperation.SET,
value: itemData.fw,
},
},
];
let pairs: Array<M5ModPair> = [
{
source: (this as any).name,
mod: {
type: M5ModType.SKILL,
id: itemId,
operation: M5ModOperation.SET,
value: itemData.fw,
},
},
];
if (character) {
const actorCalc = character.derivedData({ skills: true, weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc?.skillMods && Object.keys(actorCalc.skillMods).indexOf(itemId) !== -1) {
pairs = pairs.concat(actorCalc.skillMods[itemId]);
}
if (character) {
const actorCalc = character.derivedData({
skills: true,
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc?.skillMods && Object.keys(actorCalc.skillMods).indexOf(itemId) !== -1) {
pairs = pairs.concat(actorCalc.skillMods[itemId]);
}
if (itemData?.attribute && itemData.attribute !== "") {
pairs.push({
source: (this as any).name,
mod: {
type: M5ModType.SKILL,
id: itemId,
operation: M5ModOperation.ADD,
value: actorCalc.attributes[itemData.attribute].bonus,
},
});
}
}
if (itemData?.attribute && itemData.attribute !== '') {
pairs.push({
source: (this as any).name,
mod: {
type: M5ModType.SKILL,
id: itemId,
operation: M5ModOperation.ADD,
value: actorCalc.attributes[itemData.attribute].bonus,
},
});
}
}
const res = M5ModAggregate.processPairs(pairs);
res.mods.forEach((mod) => {
if ([M5ModOperation.SET, M5ModOperation.FIXED].includes(mod.operation)) calc.fw = mod.value;
else if ([M5ModOperation.SUBTRACT].includes(mod.operation)) calc.bonus -= mod.value;
else if ([M5ModOperation.ADD].includes(mod.operation)) calc.bonus += mod.value;
});
const res = M5ModAggregate.processPairs(pairs);
res.mods.forEach(mod => {
if ([M5ModOperation.SET, M5ModOperation.FIXED].includes(mod.operation)) calc.fw = mod.value;
else if ([M5ModOperation.SUBTRACT].includes(mod.operation)) calc.bonus -= mod.value;
else if ([M5ModOperation.ADD].includes(mod.operation)) calc.bonus += mod.value;
});
calc.ew = calc.fw + calc.bonus;
calc.sources = res.mods;
} else if (itemType === "weapon") {
calc.fw = 0;
calc.bonus = 0;
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.attackBonus;
calc.combatSkills = null;
calc.containers = null;
calc.ew = calc.fw + calc.bonus;
calc.sources = res.mods;
} else if (itemType === 'weapon') {
calc.fw = 0;
calc.bonus = 0;
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.attackBonus;
calc.combatSkills = null;
calc.containers = null;
if (actor) {
const actorCalc = character.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.ew += actorCalc.stats.attackBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.ew += actorCalc.stats.attackBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
const skill = character.getItem(itemData.skillId);
//console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system)
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew += skillData.calc.ew;
calc.bonus += skillData.calc.bonus;
calc.fw += skillData.fw;
}
}
} else if (itemType === "defensiveWeapon") {
calc.fw = 0;
calc.bonus = 0;
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.defenseBonus;
calc.combatSkills = null;
calc.containers = null;
const skill = character.getItem(itemData.skillId);
//console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system)
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew += skillData.calc.ew;
calc.bonus += skillData.calc.bonus;
calc.fw += skillData.fw;
}
}
} else if (itemType === 'defensiveWeapon') {
calc.fw = 0;
calc.bonus = 0;
calc.special = itemData.special ? 2 : 0;
calc.ew = calc.special + itemData.stats.defenseBonus;
calc.combatSkills = null;
calc.containers = null;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.ew += actorCalc.stats.defense.value + actorCalc.stats.defenseBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
if (actor) {
const actorCalc = character.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.ew += actorCalc.stats.defense.value + actorCalc.stats.defenseBonus.value;
calc.combatSkills = actorCalc.skills.combat;
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
const skill = character.getItem(itemData.skillId);
//console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system)
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew += skillData.calc.ew;
calc.bonus += skillData.calc.bonus;
calc.fw += skillData.fw;
}
}
} else if (itemType === "armor") {
itemData.mods[0] = { type: "stat", id: "defenseBonus", operation: "add", value: itemData.stats.defenseBonus };
itemData.mods[1] = { type: "stat", id: "attackBonus", operation: "add", value: itemData.stats.attackBonus };
itemData.mods[2] = { type: "stat", id: "movement", operation: "add", value: itemData.stats.movementBonus };
itemData.mods[3] = { type: "attribute", id: "gw", operation: "add100", value: itemData.attributeMod.gw };
itemData.mods[4] = { type: "stat", id: "lpProtection", operation: "set", value: itemData.lpProtection };
itemData.mods[5] = { type: "stat", id: "apProtection", operation: "set", value: itemData.apProtection };
calc.containers = null;
if (actor) {
const actorCalc = actor.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === "spell") {
calc.fw = 0;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.ew = actorCalc.stats.spellCasting.value;
}
}
} else if (itemType === "kampfkunst") {
calc.fw = 0;
calc.bonus = 0;
calc.ew = 0;
calc.generalSkills = null;
const skill = character.getItem(itemData.skillId);
//console.log("M5Item.prepareDerivedData:weapon", itemData, skill?.system)
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew += skillData.calc.ew;
calc.bonus += skillData.calc.bonus;
calc.fw += skillData.fw;
}
}
} else if (itemType === 'armor') {
itemData.mods[0] = {
type: 'stat',
id: 'defenseBonus',
operation: 'add',
value: itemData.stats.defenseBonus,
};
itemData.mods[1] = {
type: 'stat',
id: 'attackBonus',
operation: 'add',
value: itemData.stats.attackBonus,
};
itemData.mods[2] = {
type: 'stat',
id: 'movement',
operation: 'add',
value: itemData.stats.movementBonus,
};
itemData.mods[3] = {
type: 'attribute',
id: 'gw',
operation: 'add100',
value: itemData.attributeMod.gw,
};
itemData.mods[4] = {
type: 'stat',
id: 'lpProtection',
operation: 'set',
value: itemData.lpProtection,
};
itemData.mods[5] = {
type: 'stat',
id: 'apProtection',
operation: 'set',
value: itemData.apProtection,
};
calc.containers = null;
if (actor) {
const actorCalc = actor.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.containers = actorCalc.gear.containers;
}
const container = character.getItem(itemData.containerId);
//console.log("M5Item.prepareDerivedData:containers", itemData, container?.system)
if (container) {
container.prepareDerivedData();
const containerData = container.system;
}
}
} else if (itemType === 'spell') {
calc.fw = 0;
if (actor) {
const actorCalc = character.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.ew = actorCalc.stats.spellCasting.value;
}
}
} else if (itemType === 'kampfkunst') {
calc.fw = 0;
calc.bonus = 0;
calc.ew = 0;
calc.generalSkills = null;
if (actor) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
calc.generalSkills = actorCalc.skills.general;
}
if (actor) {
const actorCalc = character.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
calc.generalSkills = actorCalc.skills.general;
}
const skill = character.getItem(itemData.skillId);
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew = skillData.calc.ew;
calc.fw = skillData.fw + calc.bonus;
itemData.rolls.formulas[0].label = skill.name;
}
}
}
if (itemData?.mods) {
calc.mods = {};
for (let modKey in itemData.mods) {
if (itemData.mods[modKey].type === M5ModType.SKILL && itemData.mods[modKey].id?.includes("midgard5")) {
itemData.mods[modKey].id = actor?.items.find((x) => x.name === game["i18n"].localize(itemData.mods[modKey].id))?.id;
}
}
const skill = character.getItem(itemData.skillId);
if (skill) {
skill.prepareDerivedData();
const skillData = skill.system;
calc.ew = skillData.calc.ew;
calc.fw = skillData.fw + calc.bonus;
itemData.rolls.formulas[0].label = skill.name;
}
}
}
if (itemData?.mods) {
calc.mods = {};
for (let modKey in itemData.mods) {
if (itemData.mods[modKey].type === M5ModType.SKILL && itemData.mods[modKey].id?.includes('midgard5')) {
itemData.mods[modKey].id = actor?.items.find(
x => x.name === game['i18n'].localize(itemData.mods[modKey].id)
)?.id;
}
}
Object.keys(itemData?.mods).forEach((key) => {
const mod = itemData.mods[key];
const modCalc = {};
switch (mod.type) {
case M5ModType.ATTRIBUTE: {
for (const key of enumKeys(M5Attributes)) {
const val: string = M5Attributes[key];
modCalc[val] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`);
}
break;
}
case M5ModType.STAT: {
for (const key of enumKeys(M5Stats)) {
const val: string = M5Stats[key];
modCalc[val] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`);
}
break;
}
case M5ModType.SKILL: {
if (character) {
const actorCalc = character.derivedData({ weapons: true, defensiveWeapons: true, armor: true, items: true, spells: true, effects: true, kampfkuenste: true });
if (actorCalc) {
let category = (game as Game).i18n.localize("midgard5.skill");
Object.keys(actorCalc.skills.general).forEach((skillId) => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
Object.keys(itemData?.mods).forEach(key => {
const mod = itemData.mods[key];
const modCalc = {};
switch (mod.type) {
case M5ModType.ATTRIBUTE: {
for (const key of enumKeys(M5Attributes)) {
const val: string = M5Attributes[key];
modCalc[val] = (game as Game).i18n.localize(`midgard5.actor-${val}-long`);
}
break;
}
case M5ModType.STAT: {
for (const key of enumKeys(M5Stats)) {
const val: string = M5Stats[key];
modCalc[val] = (game as Game).i18n.localize(`midgard5.mod-stat-${val}`);
}
break;
}
case M5ModType.SKILL: {
if (character) {
const actorCalc = character.derivedData({
weapons: true,
defensiveWeapons: true,
armor: true,
items: true,
spells: true,
effects: true,
kampfkuenste: true,
});
if (actorCalc) {
let category = (game as Game).i18n.localize('midgard5.skill');
Object.keys(actorCalc.skills.general).forEach(skillId => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
category = (game as Game).i18n.localize("midgard5.language");
Object.keys(actorCalc.skills.language).forEach((skillId) => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
category = (game as Game).i18n.localize('midgard5.language');
Object.keys(actorCalc.skills.language).forEach(skillId => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
category = (game as Game).i18n.localize("midgard5.weapon-skill");
Object.keys(actorCalc.skills.combat).forEach((skillId) => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
category = (game as Game).i18n.localize('midgard5.weapon-skill');
Object.keys(actorCalc.skills.combat).forEach(skillId => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
category = (game as Game).i18n.localize("midgard5.innate-ability");
Object.keys(actorCalc.skills.innate).forEach((skillId) => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
}
}
break;
}
}
category = (game as Game).i18n.localize('midgard5.innate-ability');
Object.keys(actorCalc.skills.innate).forEach(skillId => {
const skill = character.getItem(skillId);
if (skill) modCalc[skillId] = `${category}: ${skill.name}`;
});
}
}
break;
}
}
calc.mods[key] = modCalc;
});
}
}
calc.mods[key] = modCalc;
});
}
}
getRollData() {
const actor = this.actor as any;
const item = this as any;
getRollData() {
const actor = this.actor as any;
const item = this as any;
let ret: M5RollData = actor?.getRollData() ?? {
c: null,
i: null,
iType: null,
rolls: {},
res: {},
};
let ret: M5RollData = actor?.getRollData() ?? {
c: null,
i: null,
iType: null,
rolls: {},
res: {},
};
ret.i = item.system;
ret.iType = item.type;
return ret;
}
ret.i = item.system;
ret.iType = item.type;
return ret;
}
async roll() {
const item = this as any;
async roll() {
const item = this as any;
// Initialize chat data.
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = (game as Game).settings.get("core", "rollMode");
const label = `[${item.type}] ${item.name}`;
// Initialize chat data.
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = (game as Game).settings.get('core', 'rollMode');
const label = `[${item.type}] ${item.name}`;
// If there's no roll data, send a chat message.
const formulaNames = item.system.rolls?.formulas ? Object.keys(item.system.rolls.formulas) : [];
if (formulaNames.length > 0) {
const rollData = this.getRollData();
formulaNames.forEach((formulaName) => {
const formula = item.system.rolls.formulas[formulaName];
if (formula) {
rollData.rolls[formulaName] = {
formula: formula.formula,
label: formula.label,
enabled: formula.enabled,
result: "",
total: 0,
totalStr: "",
dice: {},
} as M5RollResult;
}
});
// If there's no roll data, send a chat message.
const formulaNames = item.system.rolls?.formulas ? Object.keys(item.system.rolls.formulas) : [];
if (formulaNames.length > 0) {
const rollData = this.getRollData();
formulaNames.forEach(formulaName => {
const formula = item.system.rolls.formulas[formulaName];
if (formula) {
rollData.rolls[formulaName] = {
formula: formula.formula,
label: formula.label,
enabled: formula.enabled,
result: '',
total: 0,
totalStr: '',
dice: {},
} as M5RollResult;
}
});
if (item.type === "spell" || item.type === "kampfkunst") {
if (this.actor["system"].ap.value >= item.system.ap) {
this.actor["system"].ap.value -= item.system.ap;
}
}
if (item.type === 'spell' || item.type === 'kampfkunst') {
if (this.actor['system'].ap.value >= item.system.ap) {
this.actor['system'].ap.value -= item.system.ap;
}
}
const roll = new M5Roll(rollData, this.actor, item.name);
return roll.toMessage();
} else {
ChatMessage.create({
speaker: speaker,
rollMode: rollMode,
flavor: label,
content: item.system.description ?? "",
});
return null;
}
}
const roll = new M5Roll(rollData, this.actor, item.name);
return roll.toMessage();
} else {
ChatMessage.create({
speaker: speaker,
rollMode: rollMode,
flavor: label,
content: item.system.description ?? '',
});
return null;
}
}
getItem(itemId: string): any {
return (this as any).getEmbeddedDocument("Item", itemId);
}
getItem(itemId: string): any {
return (this as any).getEmbeddedDocument('Item', itemId);
}
// migrateSystemData(): any {
// const item = (this as any)
// const data = item.system
// migrateSystemData(): any {
// const item = (this as any)
// const data = item.system
// if (item.type === "spell") {
// if (typeof data.ap !== "string") {
// data.ap = Number.isFinite(data.ap) ? "" + data.ap : ""
// }
// }
// if (item.type === "spell") {
// if (typeof data.ap !== "string") {
// data.ap = Number.isFinite(data.ap) ? "" + data.ap : ""
// }
// }
// return super.migrateSystemData()
// }
// return super.migrateSystemData()
// }
}
+276 -269
View File
@@ -1,322 +1,329 @@
import { Evaluated } from "@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/dice/roll";
import { M5Character } from "../actors/M5Character";
import { M5EwResult, M5ModOperation, M5ModType, M5RollData, M5RollResult, M5SkillUnlearned, M5Stats } from "../M5Base";
import { stat } from "fs";
import { Evaluated } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/client/dice/roll';
import { M5Character } from '../actors/M5Character';
import { M5EwResult, M5ModOperation, M5ModType, M5RollData, M5RollResult, M5SkillUnlearned, M5Stats } from '../M5Base';
import { stat } from 'fs';
export class M5Roll {
// extends Roll<M5RollData>
static readonly TEMPLATE_PATH = "systems/midgard5/templates/chat/roll-m5.hbs";
// extends Roll<M5RollData>
static readonly TEMPLATE_PATH = 'systems/midgard5/templates/chat/roll-m5.hbs';
public _evaluated: boolean = false;
public _total: number = 0;
public pool: PoolTerm = null;
public _evaluated: boolean = false;
public _total: number = 0;
public pool: PoolTerm = null;
constructor(public data: M5RollData, public actor: any, public label: string) {
//super(null)
//this.data = rollData
}
constructor(
public data: M5RollData,
public actor: any,
public label: string
) {
//super(null)
//this.data = rollData
}
// @ts-ignore
//override evaluate(options?: InexactPartial<RollTerm.EvaluationOptions>): Evaluated<Roll<M5RollData>> | Promise<Evaluated<Roll<M5RollData>>> {
evaluate() {
const indexMap = new Map<number, string>();
const rollNames = Object.keys(this.data.rolls);
const rolls = rollNames
.filter((rollName) => this.data.rolls[rollName].enabled)
.map((rollName, index) => {
indexMap.set(index, rollName);
const formula = this.data.rolls[rollName];
const roll = new Roll(formula.formula, this.data);
return roll;
});
// @ts-ignore
//override evaluate(options?: InexactPartial<RollTerm.EvaluationOptions>): Evaluated<Roll<M5RollData>> | Promise<Evaluated<Roll<M5RollData>>> {
evaluate() {
const indexMap = new Map<number, string>();
const rollNames = Object.keys(this.data.rolls);
const rolls = rollNames
.filter(rollName => this.data.rolls[rollName].enabled)
.map((rollName, index) => {
indexMap.set(index, rollName);
const formula = this.data.rolls[rollName];
const roll = new Roll(formula.formula, this.data);
return roll;
});
this.pool = PoolTerm.fromRolls(rolls);
console.log("evaluate", this._evaluated, this.pool);
return this.pool.evaluate({ async: true }).then((results) => {
this._total = 0;
this.pool = PoolTerm.fromRolls(rolls);
console.log('evaluate', this._evaluated, this.pool);
return this.pool.evaluate({ async: true }).then(results => {
this._total = 0;
results.rolls.forEach((roll, index) => {
const rollIndex = indexMap.get(index);
const rollResult = this.data.rolls[rollIndex] as M5RollResult;
results.rolls.forEach((roll, index) => {
const rollIndex = indexMap.get(index);
const rollResult = this.data.rolls[rollIndex] as M5RollResult;
rollResult.result = roll.result;
rollResult.total = roll.total;
rollResult.totalStr = roll.total.toString();
rollResult.result = roll.result;
rollResult.total = roll.total;
rollResult.totalStr = roll.total.toString();
this._total += roll.total;
this._total += roll.total;
let rowRes = M5EwResult.TBD;
let face100 = -1;
let rowRes = M5EwResult.TBD;
let face100 = -1;
roll.dice.forEach((d, dIndex) => {
rollResult.dice[dIndex.toString()] = d.total;
roll.dice.forEach((d, dIndex) => {
rollResult.dice[dIndex.toString()] = d.total;
if (rowRes === M5EwResult.TBD && dIndex === 0) {
if (d.faces === 20) {
//if (rollResult.type === "ew") {
if (d.total === 1) rowRes = M5EwResult.FUMBLE;
else if (d.total === 20) rowRes = M5EwResult.CRITICAL;
else if (d.total >= 16) rowRes = M5EwResult.HIGH;
} else if (d.faces === 100) {
face100 = d.total as number;
}
}
});
if (rowRes === M5EwResult.TBD && dIndex === 0) {
if (d.faces === 20) {
//if (rollResult.type === "ew") {
if (d.total === 1) rowRes = M5EwResult.FUMBLE;
else if (d.total === 20) rowRes = M5EwResult.CRITICAL;
else if (d.total >= 16) rowRes = M5EwResult.HIGH;
} else if (d.faces === 100) {
face100 = d.total as number;
}
}
});
const parseResult = M5Roll.parseDiceSides(rollResult.formula);
//console.log("evaluate roll", parseResult)
if (parseResult?.sides === 20) {
if (roll.total < 20) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH) rowRes = M5EwResult.FAIL;
} else {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
} else if (face100 >= 0) {
const threshold100 = roll.total + face100;
const threshold = Math.floor(threshold100 / 10);
if (face100 === 100) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FUMBLE;
} else if (roll.total < 0) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FAIL;
} else if (face100 <= threshold) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.CRITICAL;
} else {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
}
rollResult.css = rowRes;
});
const parseResult = M5Roll.parseDiceSides(rollResult.formula);
//console.log("evaluate roll", parseResult)
if (parseResult?.sides === 20) {
if (roll.total < 20) {
if (rowRes === M5EwResult.TBD || rowRes === M5EwResult.HIGH) rowRes = M5EwResult.FAIL;
} else {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
} else if (face100 >= 0) {
const threshold100 = roll.total + face100;
const threshold = Math.floor(threshold100 / 10);
if (face100 === 100) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FUMBLE;
} else if (roll.total < 0) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.FAIL;
} else if (face100 <= threshold) {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.CRITICAL;
} else {
if (rowRes === M5EwResult.TBD) rowRes = M5EwResult.PASS;
}
}
rollResult.css = rowRes;
});
this.data.res.label = this.label;
this.data.res.label = this.label;
this._evaluated = true;
return this;
});
}
this._evaluated = true;
return this;
});
}
async render(): Promise<string> {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data);
}
async render(): Promise<string> {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data);
}
async toMessage() {
if (!this._evaluated) await this.evaluate();
async toMessage() {
if (!this._evaluated) await this.evaluate();
const rMode = (game as Game).settings.get("core", "rollMode");
const rMode = (game as Game).settings.get('core', 'rollMode');
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([this.pool]),
};
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
speaker: ChatMessage.getSpeaker({ actor: this.actor }),
sound: CONFIG.sounds.dice,
roll: Roll.fromTerms([this.pool]),
};
ChatMessage.applyRollMode(chatData, rMode);
return ChatMessage.create(chatData);
}
ChatMessage.applyRollMode(chatData, rMode);
return ChatMessage.create(chatData);
}
static fromAttributeValue(actor: any, attributeKey: string, attributeValue: number) {
const rollData = actor.getRollData() as M5RollData;
const itemData = actor.items.filter((x) => x.type === "effect").map((y) => y.system.mods);
rollData.c = 0;
for (let effectKey in itemData) {
for (let modkey in itemData[effectKey])
if (itemData[effectKey][modkey].type === M5ModType.ATTRIBUTE && itemData[effectKey][modkey].operation === M5ModOperation.ROLL) {
rollData.c += itemData[effectKey][modkey].value;
}
}
static fromAttributeValue(actor: any, attributeKey: string, attributeValue: number) {
const rollData = actor.getRollData() as M5RollData;
const itemData = actor.items.filter(x => x.type === 'effect').map(y => y.system.mods);
rollData.c = 0;
for (let effectKey in itemData) {
for (let modkey in itemData[effectKey])
if (
itemData[effectKey][modkey].type === M5ModType.ATTRIBUTE &&
itemData[effectKey][modkey].operation === M5ModOperation.ROLL
) {
rollData.c += itemData[effectKey][modkey].value;
}
}
rollData.i = attributeValue;
rollData.rolls["0"] = {
formula: "@i - 1d100 - @c",
enabled: true,
label: (game as Game).i18n.localize("midgard5.pw"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.i = attributeValue;
rollData.rolls['0'] = {
formula: '@i - 1d100 - @c',
enabled: true,
label: (game as Game).i18n.localize('midgard5.pw'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.actor-${attributeKey}-long`));
}
static fromUnlearnedSkill(actor: any, skill: M5SkillUnlearned, skillName: string) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
fw: skill.fw,
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0,
};
rollData.iType = "skill";
static fromUnlearnedSkill(actor: any, skill: M5SkillUnlearned, skillName: string) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
fw: skill.fw,
bonus: actor.system.calc?.attributes[skill.attribute]?.bonus ?? 0,
};
rollData.iType = 'skill';
rollData.rolls["0"] = {
formula: "1d20 + @i.fw + @i.bonus",
enabled: true,
label: (game as Game).i18n.localize("midgard5.pw"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @i.fw + @i.bonus',
enabled: true,
label: (game as Game).i18n.localize('midgard5.pw'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize(`midgard5.${skillName}`));
}
static brawl(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
attackBonus: 0,
damageBonus: 0,
};
static brawl(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
attackBonus: 0,
damageBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.brawlFw",
enabled: true,
label: (game as Game).i18n.localize("midgard5.attack"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.brawlFw',
enabled: true,
label: (game as Game).i18n.localize('midgard5.attack'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
rollData.rolls["1"] = {
formula: "1d6 - 4 + @c.calc.stats.damageBonus.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.damage"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['1'] = {
formula: '1d6 - 4 + @c.calc.stats.damageBonus.value',
enabled: true,
label: (game as Game).i18n.localize('midgard5.damage'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.brawl"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.brawl'));
}
static perception(actor: any) {
const rollData = actor.getRollData() as M5RollData;
static perception(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.perception.value + @c.calc.stats.perceptionFW",
enabled: true,
label: (game as Game).i18n.localize("midgard5.perception"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.perception.value + @c.calc.stats.perceptionFW',
enabled: true,
label: (game as Game).i18n.localize('midgard5.perception'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.perception"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.perception'));
}
static drinking(actor: any) {
const rollData = actor.getRollData() as M5RollData;
static drinking(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.drinking.value + @c.calc.stats.drinkingFW",
enabled: true,
label: (game as Game).i18n.localize("midgard5.drinking"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.drinking.value + @c.calc.stats.drinkingFW',
enabled: true,
label: (game as Game).i18n.localize('midgard5.drinking'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.drinking"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.drinking'));
}
static defense(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
static defense(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.defense.value + @c.calc.stats.defenseBonus.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.defense"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.defense.value + @c.calc.stats.defenseBonus.value',
enabled: true,
label: (game as Game).i18n.localize('midgard5.defense'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.defense"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.defense'));
}
static resistanceMind(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
static resistanceMind(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceMind.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceMind"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.resistanceMind.value',
enabled: true,
label: (game as Game).i18n.localize('midgard5.resistanceMind'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceMind"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.resistanceMind'));
}
static resistanceBody(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
static resistanceBody(actor: any) {
const rollData = actor.getRollData() as M5RollData;
rollData.i = {
defenseBonus: 0,
};
rollData.rolls["0"] = {
formula: "1d20 + @c.calc.stats.resistanceBody.value",
enabled: true,
label: (game as Game).i18n.localize("midgard5.resistanceBody"),
result: "",
total: 0,
totalStr: "",
dice: {},
css: "",
} as M5RollResult;
rollData.rolls['0'] = {
formula: '1d20 + @c.calc.stats.resistanceBody.value',
enabled: true,
label: (game as Game).i18n.localize('midgard5.resistanceBody'),
result: '',
total: 0,
totalStr: '',
dice: {},
css: '',
} as M5RollResult;
return new M5Roll(rollData, actor, (game as Game).i18n.localize("midgard5.resistanceBody"));
}
return new M5Roll(rollData, actor, (game as Game).i18n.localize('midgard5.resistanceBody'));
}
static parseDiceSides(formula: string): FormulaParseResult {
const ewMatcher: RegExp = /\d*[dD]20/g;
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g;
static parseDiceSides(formula: string): FormulaParseResult {
const ewMatcher: RegExp = /\d*[dD]20/g;
const pwMatcher: RegExp = /(\d+)\s*\-\s*\d*[dD]100/g;
let res = formula.match(ewMatcher);
if (res && !!res[0]) {
return {
sides: 20,
type: "ew",
threshold: null,
};
}
let res = formula.match(ewMatcher);
if (res && !!res[0]) {
return {
sides: 20,
type: 'ew',
threshold: null,
};
}
res = formula.match(pwMatcher);
if (res && !!res[1]) {
return {
sides: 100,
type: "pw",
threshold: parseInt(res[1]),
};
}
res = formula.match(pwMatcher);
if (res && !!res[1]) {
return {
sides: 100,
type: 'pw',
threshold: parseInt(res[1]),
};
}
return null;
}
return null;
}
}
interface FormulaParseResult {
sides: number;
type: string;
threshold: number;
sides: number;
type: string;
threshold: number;
}
File diff suppressed because it is too large Load Diff
+192 -165
View File
@@ -1,195 +1,222 @@
import { M5Item } from "../items/M5Item"
import { M5Attributes, M5ItemMod, M5ModOperation, M5ModType, M5RollTemplate } from "../M5Base"
import { M5Item } from "../items/M5Item";
import {
M5Attributes,
M5ItemMod,
M5ModOperation,
M5ModType,
M5RollTemplate,
} from "../M5Base";
export class M5ItemSheet extends ItemSheet {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 640,
height: 480,
classes: ["midgard5", "sheet", "item"]
})
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
width: 640,
height: 480,
classes: ["midgard5", "sheet", "item"],
});
}
get template() {
//console.log("M5ItemSheet", this.item.data.type)
const path = "systems/midgard5/templates/sheets/item"
return `${path}/${this.item.type}.hbs`
}
get template() {
//console.log("M5ItemSheet", this.item.data.type)
const path = "systems/midgard5/templates/sheets/item";
return `${path}/${this.item.type}.hbs`;
}
override getData(options?: Partial<ItemSheet.Options>): ItemSheet.Data<ItemSheet.Options> | Promise<ItemSheet.Data<ItemSheet.Options>> {
const item = this.item as M5Item
return Promise.resolve(super.getData()).then(value => {
item.prepareDerivedData()
const context = value as any
override getData(
options?: Partial<ItemSheet.Options>,
):
| ItemSheet.Data<ItemSheet.Options>
| Promise<ItemSheet.Data<ItemSheet.Options>> {
const item = this.item as M5Item;
return Promise.resolve(super.getData()).then((value) => {
item.prepareDerivedData();
const context = value as any;
// Use a safe clone of the item data for further operations.
const itemData = context.item
// Use a safe clone of the item data for further operations.
const itemData = context.item;
// Retrieve the roll data for TinyMCE editors.
context.rollData = {}
let actor = this.object?.parent ?? null
if (actor) {
context.rollData = actor.getRollData()
}
context.data = itemData.system
context.flags = itemData.flags
return context
})
}
// Retrieve the roll data for TinyMCE editors.
context.rollData = {};
let actor = this.object?.parent ?? null;
if (actor) {
context.rollData = actor.getRollData();
}
override activateListeners(html: JQuery) {
super.activateListeners(html)
context.data = itemData.system;
context.flags = itemData.flags;
html.find(".add-mod").on("click", async (event) => {
const context = this.object
const mods = context.system.mods
const modIndex = Object.keys(mods).length
mods[modIndex.toString()] = {
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ST,
operation: M5ModOperation.ADD,
value: 0
} as M5ItemMod
this.object.update({
data: {
mods: mods
}
})
})
return context;
});
}
html.find(".item-delete").on("click", async (event) => {
let row = event.target.parentElement
let itemId = row.dataset["item"]
while (!itemId) {
row = row.parentElement
if (!row)
return
itemId = row.dataset["item"]
}
override activateListeners(html: JQuery) {
super.activateListeners(html);
const context = this.item
const item = context.items.get(itemId)
item.delete()
this.render(false)
})
html.find(".add-mod").on("click", async (event) => {
const context = this.object;
const mods = context.system.mods;
const modIndex = Object.keys(mods).length;
mods[modIndex.toString()] = {
type: M5ModType.ATTRIBUTE,
id: M5Attributes.ST,
operation: M5ModOperation.ADD,
value: 0,
} as M5ItemMod;
this.object.update({
data: {
mods: mods,
},
});
});
html.find(".roll-delete").on("click", async (event) => {
//console.log("roll-delete", this.item.data.data.rolls.formulas)
html.find(".item-delete").on("click", async (event) => {
let row = event.target.parentElement;
let itemId = row.dataset["item"];
while (!itemId) {
row = row.parentElement;
if (!row) return;
itemId = row.dataset["item"];
}
let row = event.target.parentElement
let rollIndex = row.dataset["roll"]
while (!rollIndex) {
row = row.parentElement
if (!row)
return
rollIndex = row.dataset["roll"]
}
const context = this.item;
const item = context.items.get(itemId);
item.delete();
this.render(false);
});
const rolls = this.item.system.rolls.formulas
rolls[rollIndex] = null
html.find(".mod-delete").on("click", async (event) => {
let row = event.target.parentElement;
let itemId = row.dataset["mod"];
while (!itemId) {
row = row.parentElement;
if (!row) return;
itemId = row.dataset["mod"];
}
const context = this.item;
delete context.system.mods[itemId];
this.render(false);
});
this.item.update({
data: {
rolls: {
formulas: rolls
}
}
})
this.render(false)
})
html.find(".roll-delete").on("click", async (event) => {
//console.log("roll-delete", this.item.data.data.rolls.formulas)
html.find(".roll-create").on("click", async (event) => {
const rolls = this.item.system.rolls.formulas
let row = event.target.parentElement;
let rollIndex = row.dataset["roll"];
while (!rollIndex) {
row = row.parentElement;
if (!row) return;
rollIndex = row.dataset["roll"];
}
const indeces = Object.keys(rolls).map(index => parseInt(index)).sort().reverse()
const index = (indeces.find(index => !!rolls[index.toString()]) ?? -1) + 1
console.log("roll-create", rolls, indeces, index)
const rolls = this.item.system.rolls.formulas;
rolls[rollIndex] = null;
rolls[index.toString()] = {
formula: "1d6",
label: (game as Game).i18n.localize("midgard5.roll"),
enabled: true
} as M5RollTemplate
this.item.update({
data: {
rolls: {
formulas: rolls,
},
},
});
this.render(false);
});
this.item.update({
data: {
rolls: {
formulas: rolls
}
}
})
this.render(false)
})
html.find(".roll-create").on("click", async (event) => {
const rolls = this.item.system.rolls.formulas;
// Drag & Drop
if (["item"].includes(this.object.type)) {
const itemToItemAssociation = new DragDrop({
dragSelector: ".item",
dropSelector: null,
permissions: { dragstart: this._canDragStart.bind(this), drop: this._canDragDrop.bind(this) },
callbacks: { drop: this._onDropItem.bind(this) },
})
itemToItemAssociation.bind(html[0])
}
}
const indeces = Object.keys(rolls)
.map((index) => parseInt(index))
.sort()
.reverse();
const index =
(indeces.find((index) => !!rolls[index.toString()]) ?? -1) + 1;
console.log("roll-create", rolls, indeces, index);
_canDragStart(selector) {
console.log("M5ItemSheet._canDragStart", selector)
return this.options.editable && this.object.isOwner
}
rolls[index.toString()] = {
formula: "1d6",
label: (game as Game).i18n.localize("midgard5.roll"),
enabled: true,
} as M5RollTemplate;
_canDragDrop(selector) {
console.log("M5ItemSheet._canDragDrop", selector)
return true
}
this.item.update({
data: {
rolls: {
formulas: rolls,
},
},
});
this.render(false);
});
async _onDropItem(event) {
let data
const obj = this.object
const li = event.currentTarget
// Drag & Drop
if (["item"].includes(this.object.type)) {
const itemToItemAssociation = new DragDrop({
dragSelector: ".item",
dropSelector: ".item-list",
permissions: {
dragstart: this._canDragStart.bind(this),
drop: this._canDragDrop.bind(this),
},
callbacks: { drop: this._onDropItem.bind(this) },
});
itemToItemAssociation.bind(html[0]);
}
}
try {
data = JSON.parse(event.dataTransfer.getData("text/plain"))
if (data.type !== "Item")
return false
} catch (err) {
return false
}
_canDragStart(selector) {
console.log("M5ItemSheet._canDragStart", selector);
return this.options.editable && this.object.isOwner;
}
// Case 1 - Import from a Compendium pack
let itemObject
if (data.pack) {
const compendiumObject = await (this as any).importItemFromCollection(data.pack, data.id)
itemObject = compendiumObject.data
}
_canDragDrop(selector) {
console.log("M5ItemSheet._canDragDrop", selector);
return true;
}
// Case 2 - Import from World entity
else {
const originalItem = await (game as Game).items.get(data.id)
itemObject = duplicate(originalItem)
if (!itemObject)
return
}
async _onDropItem(event) {
let data;
const obj = this.object;
const li = event.currentTarget;
if ((itemObject.type === "mod")) {
let mods = obj?.system?.mods
if (!mods)
mods = []
try {
data = JSON.parse(event.dataTransfer.getData("text/plain"));
if (data.type !== "Item") return false;
} catch (err) {
return false;
}
itemObject.id = randomID()
console.log("M5ItemSheet._onDropItem", itemObject)
mods.push(itemObject)
// Case 1 - Import from a Compendium pack
let itemObject;
if (data.pack) {
const compendiumObject = await (this as any).importItemFromCollection(
data.pack,
data.id,
);
itemObject = compendiumObject.data;
}
obj.update({
data: {
mods: mods
}
})
}
}
// Case 2 - Import from World entity
else {
const originalItem = await (game as Game).items.get(data.id);
itemObject = duplicate(originalItem);
if (!itemObject) return;
}
async _onDragItemStart(event) { }
if (itemObject.type === "mod") {
let mods = obj?.system?.mods;
if (!mods) mods = [];
itemObject.id = randomID();
console.log("M5ItemSheet._onDropItem", itemObject);
mods.push(itemObject);
obj.update({
data: {
mods: mods,
},
});
}
}
async _onDragItemStart(event) {}
}