168 lines
7.7 KiB
TypeScript
168 lines
7.7 KiB
TypeScript
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>>()
|
|
|
|
constructor(public data: any, public calc: M5CharacterCalculatedData) {
|
|
const characterString = (game as Game).i18n.localize("ACTOR.TypeCharacter")
|
|
|
|
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.STAT, id: M5Stats.DEFENSE, operation: M5ModOperation.SET, value: calc.stats.defense.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.movementBonus.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)
|
|
}
|
|
|
|
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
|
|
|
|
if (map) {
|
|
const pair: M5ModPair = {
|
|
mod: mod,
|
|
source: source
|
|
}
|
|
|
|
let key = mod.id
|
|
// if (mod.type === M5ModType.ATTRIBUTE) {
|
|
// key = M5Attributes[mod.id] as string
|
|
// console.log("M5ModType.ATTRIBUTE", mod.id, key)
|
|
// } else if (mod.type === M5ModType.STAT) {
|
|
// key = M5Stats[mod.id] as string
|
|
// console.log("M5ModType.STAT", mod.id, key)
|
|
// }
|
|
|
|
if (map.has(key))
|
|
map.get(key).push(pair)
|
|
else
|
|
map.set(key, [pair])
|
|
}
|
|
}
|
|
|
|
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.stats.forEach((pairs, id) => {
|
|
const res = M5ModAggregate.processPairs(pairs)
|
|
calc.stats[id] = res
|
|
})
|
|
|
|
const ret = {}
|
|
this.skills.forEach((pairs, id) => {
|
|
ret[id] = pairs
|
|
})
|
|
|
|
return ret
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
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 modToString(mod: M5ItemMod): string { }
|
|
|
|
}
|