-
-
Save DedaDev/dd76f6c1578b48976f32e80e4764beda to your computer and use it in GitHub Desktop.
Hordes.io Item hydration reverse-engineered, for use with items API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const itemJson = { | |
auction: '2020-01-02T04:27:51.501Z', | |
auctionprice: 62, | |
bound: false, | |
id: 7157356, | |
name: 'kickbuttowski', | |
rolls: [62, 76, 17, 11, 98, 80, 93, 75, 11, 67, 37, 49, 36, 47, 28, 71, 18, 83, 72, 37, 27], | |
slot: null, | |
stacks: null, | |
tier: 0, | |
type: 'boot', | |
upgrade: 0, | |
}; | |
const myItem = new Item(); | |
myItem.hydrate(itemJson); | |
// myItem.stats now contains a Map of the real stats of the item, and myItem's other properties are now filled out` | |
// Map of stat keys to stat names: | |
// Derived from debugging entire character screen stats ingame | |
const statMapping = { | |
0: 'Strength', | |
1: 'Stamina', | |
2: 'Dexterity', | |
3: 'Intelligence', | |
4: 'Wisdom', | |
5: 'Luck', | |
6: 'HP', | |
7: 'MP', | |
8: 'HP Reg./5s', // (MUST Divide by 10 to get HP Reg./5s) | |
9: 'MP Reg./5s', // (MUST Divide by 10 to get MP Reg./5s) | |
10: 'Min Dmg.', | |
11: 'Max Dmg.', | |
12: 'Defense', | |
13: 'Block', // (MUST Divide by 10 to get block %, e.g. 15 = 1.5%) | |
14: 'Critical', // (MUST Divide by 10 to get critical %, e.g. 149 = 14.9% crit) | |
15: 'Move Spd.' | |
16: 'Haste', // (MUST Divide by 10 to get haste %, e.g. 16 = 1.6%) | |
17: 'Attack Spd.', | |
18: 'Item Find', | |
19: 'Bag Slots', | |
20: 'Fame', | |
//21: ?, (This was set to 0 for me, but deosn't map to anything in character screen) | |
//22: ? (This was set to 1 for me, but doesn't map to anything in character screen) | |
} | |
// A hydrated item's `stats` property contains `keys` mapping to quality+base values of stats. Those `keys` map to these stats. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Lr = { | |
6: { | |
min: 0.2, | |
max: 0.8, | |
round: true, | |
}, | |
7: { | |
min: 0.2, | |
max: 0.5, | |
round: true, | |
}, | |
8: { | |
min: 0.1, | |
max: 0.5, | |
}, | |
9: { | |
min: 0.1, | |
max: 0.2, | |
}, | |
10: { | |
min: 0.03, | |
max: 0.13, | |
round: true, | |
}, | |
11: { | |
min: 0.1, | |
max: 0.2, | |
round: true, | |
}, | |
12: { | |
min: 0.1, | |
max: 1, | |
round: true, | |
}, | |
13: { | |
min: 0.1, | |
max: 0.3, | |
}, | |
14: { | |
min: 0.1, | |
max: 0.4, | |
}, | |
16: { | |
min: 0.1, | |
max: 0.5, | |
}, | |
2: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
0: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
3: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
4: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
1: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
5: { | |
min: 0.08, | |
max: 0.45, | |
round: true, | |
}, | |
18: { | |
min: 0.01, | |
max: 0.15, | |
round: true, | |
}, | |
}; | |
const Ur = { | |
6: 3, | |
7: 3, | |
8: 3, | |
9: 2, | |
10: 1, | |
11: 1, | |
12: 5, | |
13: 5, | |
14: 5, | |
15: 0.5, | |
16: 5, | |
17: 0, | |
2: 2, | |
0: 2, | |
3: 2, | |
4: 2, | |
1: 2, | |
5: 2, | |
19: 1, | |
18: 3, | |
}; | |
const Br = { | |
hammer: { | |
baselvl: 0, | |
slot: 101, | |
tiers: 17, | |
drop: 0.4, | |
weight: 1, | |
class: 3, | |
stats: { | |
10: { | |
base: 1, | |
min: 0.6, | |
max: 1, | |
}, | |
11: { | |
base: 3, | |
min: 0.8, | |
max: 1.7, | |
}, | |
17: { | |
base: 15, | |
min: 0.05, | |
max: 0.1, | |
}, | |
}, | |
}, | |
bow: { | |
baselvl: 0, | |
slot: 101, | |
tiers: 17, | |
drop: 0.4, | |
weight: 1, | |
class: 2, | |
stats: { | |
10: { | |
base: 1, | |
min: 0.6, | |
max: 1, | |
}, | |
11: { | |
base: 3, | |
min: 0.8, | |
max: 1.7, | |
}, | |
17: { | |
base: 10, | |
min: 0.05, | |
max: 0.1, | |
}, | |
}, | |
}, | |
staff: { | |
baselvl: 0, | |
slot: 101, | |
tiers: 17, | |
drop: 0.4, | |
weight: 1, | |
class: 1, | |
stats: { | |
10: { | |
base: 1, | |
min: 0.6, | |
max: 1, | |
}, | |
11: { | |
base: 3, | |
min: 0.8, | |
max: 1.7, | |
}, | |
17: { | |
base: 10, | |
min: 0.05, | |
max: 0.1, | |
}, | |
}, | |
}, | |
sword: { | |
baselvl: 0, | |
slot: 101, | |
tiers: 17, | |
drop: 0.4, | |
weight: 1, | |
class: 0, | |
stats: { | |
10: { | |
base: 1, | |
min: 0.6, | |
max: 1, | |
}, | |
11: { | |
base: 3, | |
min: 0.8, | |
max: 1.7, | |
}, | |
17: { | |
base: 20, | |
min: 0.05, | |
max: 0.1, | |
}, | |
}, | |
}, | |
armlet: { | |
baselvl: 1, | |
slot: 102, | |
tiers: 13, | |
drop: 1, | |
weight: 0.3, | |
stats: { | |
6: { | |
base: 10, | |
min: 0.5, | |
max: 0.9, | |
}, | |
12: { | |
base: 7, | |
min: 0.5, | |
max: 0.9, | |
}, | |
}, | |
}, | |
armor: { | |
baselvl: 2, | |
slot: 103, | |
tiers: 11, | |
drop: 1, | |
weight: 1, | |
stats: { | |
12: { | |
base: 10, | |
min: 1.5, | |
max: 3, | |
}, | |
6: { | |
base: 20, | |
min: 1, | |
max: 2, | |
}, | |
}, | |
}, | |
bag: { | |
baselvl: 5, | |
slot: 104, | |
tiers: 5, | |
drop: 1, | |
weight: 0.1, | |
stats: { | |
19: { | |
base: 1, | |
min: 0.1, | |
max: 0.3, | |
}, | |
}, | |
}, | |
boot: { | |
baselvl: 2, | |
slot: 105, | |
tiers: 13, | |
drop: 1, | |
weight: 0.4, | |
stats: { | |
6: { | |
base: 10, | |
min: 0.6, | |
max: 1, | |
}, | |
12: { | |
base: 8, | |
min: 0.6, | |
max: 1.2, | |
}, | |
15: { | |
base: 5, | |
min: 0.03, | |
max: 0.15, | |
}, | |
}, | |
}, | |
glove: { | |
baselvl: 2, | |
slot: 106, | |
tiers: 13, | |
drop: 1, | |
weight: 0.4, | |
stats: { | |
6: { | |
base: 10, | |
min: 0.6, | |
max: 1, | |
}, | |
12: { | |
base: 8, | |
min: 0.7, | |
max: 1.2, | |
}, | |
14: { | |
base: 1, | |
min: 0.1, | |
max: 1.5, | |
}, | |
}, | |
}, | |
ring: { | |
baselvl: 5, | |
slot: 107, | |
tiers: 12, | |
drop: 0.8, | |
weight: 0.2, | |
stats: { | |
6: { | |
base: 10, | |
min: 0.5, | |
max: 0.9, | |
}, | |
7: { | |
base: 5, | |
min: 0.6, | |
max: 1, | |
}, | |
}, | |
}, | |
amulet: { | |
baselvl: 7, | |
slot: 108, | |
tiers: 12, | |
drop: 0.8, | |
weight: 0.3, | |
stats: { | |
7: { | |
base: 10, | |
min: 1, | |
max: 1.8, | |
}, | |
9: { | |
base: 1, | |
min: 0.2, | |
max: 0.3, | |
}, | |
}, | |
}, | |
quiver: { | |
baselvl: 2, | |
slot: 109, | |
tiers: 10, | |
drop: 0.7, | |
weight: 0.5, | |
class: 2, | |
stats: { | |
14: { | |
base: 2, | |
min: 0.1, | |
max: 0.5, | |
}, | |
}, | |
}, | |
shield: { | |
baselvl: 2, | |
slot: 109, | |
tiers: 10, | |
drop: 0.7, | |
weight: 0.5, | |
class: 0, | |
stats: { | |
12: { | |
base: 20, | |
min: 0.9, | |
max: 1.5, | |
}, | |
13: { | |
base: 4, | |
min: 1, | |
max: 3, | |
}, | |
}, | |
}, | |
totem: { | |
baselvl: 2, | |
slot: 109, | |
tiers: 10, | |
drop: 0.7, | |
weight: 0.5, | |
class: 3, | |
stats: { | |
12: { | |
base: 10, | |
min: 0.3, | |
max: 0.8, | |
}, | |
9: { | |
base: 1, | |
min: 0.1, | |
max: 0.2, | |
}, | |
}, | |
}, | |
orb: { | |
baselvl: 2, | |
slot: 109, | |
tiers: 10, | |
drop: 0.7, | |
weight: 0.5, | |
class: 1, | |
stats: { | |
3: { | |
base: 10, | |
min: 0.3, | |
max: 0.8, | |
}, | |
9: { | |
base: 1, | |
min: 0.1, | |
max: 0.3, | |
}, | |
}, | |
}, | |
rune: { | |
baselvl: 1, | |
tiers: 11, | |
drop: 0.8, | |
quality: 70, | |
}, | |
misc: { | |
drop: 7, | |
weight: 0.1, | |
}, | |
book: { | |
drop: 1.5, | |
weight: 0.5, | |
}, | |
mount: { | |
noupgrade: true, | |
undroppable: true, | |
drop: 0, | |
stackable: false, | |
}, | |
box: { | |
noupgrade: true, | |
undroppable: true, | |
drop: 0, | |
stackable: false, | |
}, | |
gold: { | |
drop: 20, | |
}, | |
}; | |
// Setting up `df`, used to define item logic | |
const hf = (t, e) => { | |
const s = { | |
level: t.level, | |
type: t.type, | |
tier: t.tier, | |
stats: t.stats ? new Map() : void 0, | |
class: t.class, | |
quality: t.quality, | |
}; | |
t.stats && | |
Object.keys(t.stats) | |
.sort((t, e) => t - e) | |
.forEach(e => { | |
const i = t.stats[e]; | |
s.stats.set(parseInt(e), { | |
min: i.base + t.level * i.min, | |
max: i.base + (t.level + 10) * i.max, | |
}); | |
}), | |
(e[t.type + t.tier] = s); | |
}; | |
const cf = (t, e) => Br[t].baselvl + Math.floor((e / Br[t].tiers) * 100); | |
const ia = (t, e) => { | |
const s = [((t >> 16) & 255) / 255, ((t >> 8) & 255) / 255, (255 & t) / 255]; | |
return void 0 !== e && s.push(e), s; | |
}; | |
// Setting Sp to empty object because it's only related to the monster model | |
const Sp = {}; | |
const Su = { | |
black: ia(0, 0), | |
white: ia(16777215, 0), | |
deadgrey: ia(3355443, 0), | |
teal: ia(3384995, 0), | |
magicblue: ia(3362252, 0), | |
paleskin: ia(14267315, 0), | |
darkskin: ia(8411481, 0), | |
slimegreen: ia(2542694, 0), | |
mushgreen: ia(2077529, 0), | |
linen: ia(13408614, 0), | |
woodbrown: ia(4859433, 0), | |
woodbrown2: ia(10250315, 0), | |
tealsteel: ia(3358797, 0.5), | |
darksteel: ia(3355443, 0.5), | |
greysteel: ia(5066061, 0.5), | |
blacksteel: ia(988178, 0.5), | |
leather: ia(4337198, 0), | |
emerald: ia(22866, -0.1), | |
gold: ia(16751616, 1), | |
paper: ia(15129011, 0), | |
richpurple: ia(7484623, 0), | |
fireorange: ia(14715686, -0.7), | |
archergreen: ia(10471258, 0), | |
warbrown: ia(15172191, 0), | |
bronze: ia(9258571, 0.5), | |
silver: ia(11527136, 0.8), | |
shamanblue: ia(3687924, 0), | |
mageblue: ia(6607340, 0), | |
bone: ia(14535066, 0.2), | |
bone2: ia(11836267, 0.2), | |
ice: ia(14610164, -0.2), | |
vanguard: ia(2848511, 0), | |
bloodlust: ia(14289947, 0), | |
pink: ia(16711935, 0), | |
warden: ia(14755623, 0), | |
evilred: ia(13239043, 0), | |
ruby: ia(15733030, 1), | |
moss: ia(2925637, 0.2), | |
rock: ia(5006687, 0.4), | |
death: ia(3750201, 0.8), | |
}; | |
// Setting Vm/Mp to empty objects instead of their real values, because they appear to be related to the equipment model, which I don't care about for this | |
const Vm = {}; | |
const Mp = {}; | |
const Ep = [ | |
[30, 1e4, 50, Vm, {}], | |
[30, 2e4, 50, Mp, {}], | |
[ | |
30, | |
5e4, | |
80, | |
Mp, | |
{ | |
colEyes: ia(11332842, 0), | |
colPrim: ia(4772165, -0.2), | |
colSec: ia(1351204, -0.2), | |
}, | |
], | |
[ | |
30, | |
5e4, | |
80, | |
Mp, | |
{ | |
colEyes: ia(16751284, 0), | |
colPrim: ia(15737892, 0.5), | |
colSec: ia(15737892, 0.5), | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Mp, | |
{ | |
colEyes: ia(14292553, 0), | |
colPrim: ia(4075311, 0.1), | |
colSec: ia(1970198, 0.1), | |
legsize: 0.5, | |
post: t => { | |
oi(t.chest.scale, 0.8); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
90, | |
Mp, | |
{ | |
colEyes: ia(2029122, 0), | |
colPrim: ia(2565674, 0.3), | |
colSec: ia(2236197, 0.3), | |
legsize: 1.4, | |
post: t => { | |
ri(t.chest.scale, 0.6, 0.6, 1), t.chest2.rotation.set(0.5, 0, 0); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
80, | |
Vm, | |
{ | |
colEyes: ia(12825266, 0), | |
colPrim: ia(11313312, 0.1), | |
colSec: ia(8221555, 0.1), | |
meshHead: 'rocks/rock_02.ho', | |
post: t => ri(t.eyes.position, 0, 0, 0.75), | |
}, | |
], | |
[ | |
30, | |
5e4, | |
90, | |
Vm, | |
{ | |
colEyes: ia(15880973, 0), | |
colPrim: Su.fireorange, | |
colSec: Su.fireorange, | |
meshHead: 'rocks/rock_02.ho', | |
post: t => { | |
ri(t.eyes.position, 0, 0, 0.75); | |
const e = ic(Pu.burning, void 0, t); | |
e && t.effects.push(e); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Vm, | |
{ | |
colEyes: ia(12451327, 0), | |
colPrim: ia(3950066, -0.4), | |
colSec: ia(3525854, -0.4), | |
meshHead: 'monsterparts/wyrmhead.ho', | |
meshEyes: 'monsterparts/wyrmEyes.ho', | |
post: t => { | |
const e = ic(Pu.etherwyrm, void 0, t.blobs[0]); | |
e && t.effects.push(e); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Vm, | |
{ | |
colEyes: ia(2747996, 0), | |
colPrim: ia(1907231, 0.4), | |
colSec: ia(2293580, -0.8), | |
meshHead: 'monsterparts/wyrmhead.ho', | |
meshEyes: 'monsterparts/wyrmEyes.ho', | |
post: t => { | |
const e = ic(Pu.shadowwyrm, void 0, t.blobs[0]); | |
e && t.effects.push(e); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
80, | |
Mp, | |
{ | |
colEyes: ia(16758891, 0), | |
colPrim: ia(15448667, 0.1), | |
colSec: ia(11370036, 0.1), | |
legsize: 0.6, | |
meshHead: 'monsterparts/wyrmhead.ho', | |
meshBack: 'monsterparts/wyrmhead.ho', | |
meshEyes: 'monsterparts/wyrmEyes.ho', | |
chestOffset: 0.5, | |
post: Sp, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Mp, | |
{ | |
colEyes: ia(16777215, 0), | |
colPrim: Su.darksteel, | |
colSec: Su.gold, | |
legsize: 0.6, | |
meshHead: 'monsterparts/wyrmhead.ho', | |
meshBack: 'monsterparts/wyrmhead.ho', | |
meshEyes: 'monsterparts/wyrmEyes.ho', | |
chestOffset: 0.5, | |
post: Sp, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Mp, | |
{ | |
colEyes: ia(16750598, 0), | |
colPrim: ia(13177876, -0.6), | |
colSec: ia(16721931, -0.7), | |
legsize: 1.1, | |
meshHead: 'misc/misc_bones_skull.ho', | |
meshBack: 'monsterparts/wyrmhead.ho', | |
meshEyes: 'monsterparts/wyrmEyes.ho', | |
post: t => { | |
oi(t.chest2.scale, 0.7), ri(t.eyes.position, 0, -0.1, 0.55), oi(t.eyes.scale, 0.6); | |
const e = ic(Pu.burning, void 0, t); | |
e && t.effects.push(e); | |
}, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
85, | |
Vm, | |
{ | |
colEyes: Su.fireorange, | |
colPrim: Su.darksteel, | |
colSec: Su.fireorange, | |
}, | |
], | |
[ | |
30, | |
5e4, | |
95, | |
Vm, | |
{ | |
colEyes: Su.ice, | |
colPrim: ia(3980543, -0.6), | |
colSec: Su.ice, | |
post: t => { | |
const e = ic(Pu.arcticaura, void 0, t.blobs[1]); | |
e && (t.effects.push(e), (e.position[1] = -0.5)); | |
}, | |
}, | |
], | |
].map(t => ({ | |
level: t[0], | |
goldValue: t[1], | |
quality: t[2], | |
visual: t[3], | |
visualData: t[4], | |
})); | |
const lf = [ | |
{ | |
id: 0, | |
storeValue: 300, | |
quality: 90, | |
level: 1, | |
custom: ['Contains one random mount of rare or epic quality'], | |
}, | |
]; | |
const df = {}; | |
// initting df | |
(t => { | |
for (const e in Br) | |
if (Br[e].tiers) { | |
const s = Br[e]; | |
for (let i = 0; i < s.tiers; ++i) | |
hf( | |
{ | |
type: e, | |
tier: i, | |
stats: s.stats, | |
level: cf(e, i), | |
class: s.class, | |
quality: s.quality, | |
}, | |
t, | |
); | |
} | |
})(df); | |
(t => { | |
const e = [150, 100, 300, 200, 600, 300]; | |
for (let s = 0; s < 6; ++s) { | |
const i = Math.floor(s / 2), | |
n = s % 2 == 0; | |
t['misc' + s] = { | |
type: 'misc', | |
tier: s, | |
level: 1 + 20 * i, | |
goldvalue: 5 ** i, | |
quality: 15, | |
custom: [e[s] + (n ? ' HP recovered' : ' MP recovered')], | |
useSkill: 100, | |
use: (t, e, s, i) => {}, | |
}; | |
} | |
})(df); | |
// I left out this logic because it appears to be for skill books only, and | |
// requires us to include all the skills in this code | |
// (t => { | |
// Em.forEach(e => { | |
// if (!e.engineOnly) | |
// for (let s = 0; s < e.skilllevels; ++s) { | |
// const i = 5 * e.id + s; | |
// t[`book${i}`] = { | |
// type: 'book', | |
// tier: i, | |
// level: e.minlevel + 8 * s, | |
// skillid: e.id, | |
// skilllevel: s, | |
// class: e.class, | |
// noReward: e.noReward || false, | |
// goldValue: e.goldValue || (e.minlevel + 5 * s < 5 ? 4 : 0), | |
// quality: Math.round(Math.min(99, 30 + (s / 5) * 70)), | |
// art: au(i, e.class), | |
// useSkill: 101, | |
// use: (t, s, i, n) => { | |
// of(t, e.id); | |
// }, | |
// }; | |
// } | |
// }); | |
// })(df); | |
(t => { | |
Ep.forEach((e, s) => { | |
t['mount' + s] = { | |
...e, | |
type: 'mount', | |
tier: s, | |
requiredSkills: [39], | |
useSkill: 102, | |
use: (t, e, i, n, a) => ({ | |
id: 75, | |
mode: 4, | |
stacks: 1, | |
duration: 600, | |
caster: t.id, | |
target: t.id, | |
buffdata: [s], | |
sendBuffdata: true, | |
level: e, | |
}), | |
}; | |
}); | |
})(df); | |
(t => { | |
lf.forEach(e => { | |
t['box' + e.id] = { | |
...e, | |
type: 'box', | |
tier: e.id, | |
unsellable: true, | |
useSkill: 103, | |
use: (t, e, s, i) => {}, | |
}; | |
}); | |
})(df); | |
const Ir = (t, e) => t[Math.floor(e * t.length)]; | |
const rw = Object.keys(Lr); | |
class Item { | |
constructor(t) { | |
(this.dbid = t), (this.stats = new Map()), (this.dirty = true); | |
} | |
hydrate(t) { | |
if ( | |
((this.dirty = false), | |
(this.bound = t.bound), | |
(this.type = t.type), | |
(this.tier = t.tier), | |
(this.logic = df[this.type + this.tier]), | |
(this.auction = t.auction ? new Date(t.auction) : undefined), | |
(this.auctionprice = t.auctionprice), | |
(this.owner = t.name), | |
(this.stash = t.stash ? new Date(t.stash) : undefined), | |
undefined === this.logic) | |
) | |
throw 'Unknown item ' + t.type + t.tier; | |
if (((this.upgrade = t.upgrade), this.stats.clear(), t.rolls)) { | |
if ((this.setRolls(t.rolls), (this.quality = this.nextRoll()), this.logic.stats)) { | |
this.logic.stats.forEach((t, e) => { | |
this.stats.set(e, { | |
type: 'base', | |
qual: this.quality, | |
value: Math.floor( | |
t.min + | |
(t.max - t.min) * (this.quality / 100) ** 2 + | |
Ur[e] * this.upgrade, | |
), | |
}); | |
}); | |
const t = Math.round((this.quality / 100) ** 1.5 * 3.6); | |
for (let e = 0; e < t; ++e) { | |
let t = this.nextRoll(), | |
e = -1; | |
for (; -1 === e || this.stats.has(e); ) | |
(e = parseInt(Ir(rw, t / 101))), (t = (t + 5) % 100); | |
const s = (this.nextRoll() + this.quality) / 2; | |
this.stats.set(e, { | |
type: 'bonus', | |
qual: s, | |
value: Math.ceil( | |
Math.max( | |
(Lr[e].min + (Lr[e].max - Lr[e].min) * (s / 100) ** 2) * | |
this.logic.level * | |
Br[this.type].weight, | |
Ur[e], | |
) + | |
Ur[e] * this.upgrade, | |
), | |
}); | |
} | |
} | |
(this.quality = this.logic.quality || this.quality), (this.stacks = undefined); | |
} else (this.stacks = t.stacks), (this.quality = this.logic.quality || 0); | |
} | |
setRolls(t) { | |
(this.rolls = t), (this.currentRoll = 0); | |
} | |
nextRoll() { | |
if (this.currentRoll == this.rolls.length) throw 'roll maximum reached'; | |
return this.rolls[this.currentRoll++]; | |
} | |
use(t) { | |
this.logic.use && this.logic.use(t); | |
} | |
goldValue(t) { | |
if (!this.canBeSold()) throw 'Item cant have value because it cant be sold'; | |
return nw(this.logic, this.quality, this.stacks, t); | |
} | |
storeValue() { | |
return this.logic.storeValue || 0; | |
} | |
canEquip(t) { | |
return Gx(t.level, t.skills.skillIds, t.class, this.type, this.tier); | |
} | |
canEquipClass(t) { | |
return Kx(t.class, this.type, this.tier); | |
} | |
equipReasons(t) { | |
const e = []; | |
return this.logic.level && e.push(['Lv. ' + this.logic.level, true]), e; | |
} | |
canBeDropped() { | |
return !Br[this.type].undroppable && !this.bound; | |
} | |
canBeTraded() { | |
return !this.bound; | |
} | |
canBeSold() { | |
return !this.logic.unsellable; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment