import { giveItem, type Item, isDefaultItem } from './items'; import { Either, Left } from '../util'; import { ItemBehavior, db } from '../db'; import { BLOOD_ITEM, dealDamage } from './pvp'; export interface Behavior { name: string, description: string, itemType: 'plain' | 'weapon' | 'consumable', // make it look fancy format?: (value: number) => string, // triggers upon use // for 'weapons', this is on attack // for 'consumable' and `plain`, this is on use // returns Left upon success, the reason for failure otherwise (Right) onUse?: (value: number, item: Item, user: string) => Promise>, // triggers upon `weapons` attack // returns the new damage value upon success (Left), the reason for failure otherwise (Right) onAttack?: (value: number, item: Item, user: string, target: string, damage: number) => Promise>, } export const behaviors: Behavior[] = [ { name: 'heal', description: 'Heals the user by `value`', itemType: 'consumable', async onUse(value, item, user) { await dealDamage(user, -Math.floor(value)); return new Left(null); }, }, { name: 'damage', description: 'Damages the user by `value', itemType: 'consumable', async onUse(value, item, user) { await dealDamage(user, Math.floor(value)); return new Left(null); }, }, { name: 'random_up', description: 'Randomizes the attack value up by a maximum of `value`', itemType: 'weapon', format: (value) => `random +${value}`, async onAttack(value, item, user, target, damage) { return new Left(damage + Math.round(Math.random() * value)); }, }, { name: 'random_down', description: 'Randomizes the attack value down by a maximum of `value`', itemType: 'weapon', format: (value) => `random -${value}`, async onAttack(value, item, user, target, damage) { return new Left(damage - Math.round(Math.random() * value)); }, }, { name: 'lifesteal', description: 'Gain blood by stabbing your foes, scaled by `value`x', itemType: 'weapon', format: (value) => `lifesteal: ${value}x`, async onAttack(value, item, user, target, damage) { giveItem(user, BLOOD_ITEM, Math.floor(damage * value)); return new Left(damage); }, } ]; export async function getBehaviors(item: Item) { if (isDefaultItem(item)) { return item.behaviors || []; } else { return await db('itemBehaviors') .where('item', item.id); } }