From 4bdbda36fb9a2b9bae4f2c7c7b180c377cd30a3a Mon Sep 17 00:00:00 2001 From: Fen Dweller Date: Mon, 3 Aug 2020 11:14:28 -0400 Subject: [PATCH] Flesh out the item system a bit Weapons are a now kind of Equipment; Equipment goes into a specific slot. --- src/game/creature.ts | 17 +++--- src/game/items.ts | 131 ++++++++++++++++++++++++++++-------------- src/game/maps/town.ts | 23 ++++++-- 3 files changed, 114 insertions(+), 57 deletions(-) diff --git a/src/game/creature.ts b/src/game/creature.ts index e928a38..6458a8a 100644 --- a/src/game/creature.ts +++ b/src/game/creature.ts @@ -2,7 +2,7 @@ import { Damage, Combatant, Stats, Action, Vigor, Side, GroupAction, VisibleStat import { Noun, Pronoun } from './language' import { LogEntry, LogLines } from './interface' import { Vore, VoreContainer, VoreType } from './vore' -import { Item } from './items' +import { Item, EquipmentSlot, Equipment } from './items' import { PassAction } from './combat/actions' export class Creature extends Vore implements Combatant { @@ -15,6 +15,7 @@ export class Creature extends Vore implements Combatant { otherActions: Array = []; side: Side; title = "Lv. 1 Creature"; + equipment: Map = new Map() constructor (name: Noun, kind: Noun, pronouns: Pronoun, stats: Stats, preyPrefs: Set, predPrefs: Set, mass: number) { super(name, kind, pronouns, stats, preyPrefs, predPrefs, mass) @@ -85,14 +86,12 @@ export class Creature extends Vore implements Combatant { } validActions (target: Creature): Array { - let choices = this.actions.concat( - this.containers.flatMap(container => container.actions) - ).concat( - target.otherActions.concat( - this.otherContainers.flatMap(container => container.actions).concat( - this.items.flatMap(item => item.actions) - ) - ) + let choices = ([] as Action[]).concat( + this.actions, + this.containers.flatMap(container => container.actions), + target.otherActions, + this.otherContainers.flatMap(container => container.actions), + Array.from(this.equipment.values()).flatMap(item => item.actions) ) if (this.containedIn !== null) { diff --git a/src/game/items.ts b/src/game/items.ts index 891e4c2..18600fe 100644 --- a/src/game/items.ts +++ b/src/game/items.ts @@ -2,57 +2,100 @@ import { TextLike, LiveText, DynText, Word, ImproperNoun, Verb } from './languag import { Actionable, Action, DamageFormula, ConstantDamageFormula, Damage, DamageType, Vigor, StatDamageFormula, Stat } from './combat' import { AttackAction } from './combat/actions' -export interface Item extends Actionable { - name: Word; - desc: TextLike; +export enum ItemKind { + Key, + Consumable, + Equipment } -export class Weapon implements Actionable { +export abstract class Item implements Actionable { + abstract kind: ItemKind; + abstract actions: Array; + + constructor (public name: Word, public desc: TextLike) { + + } +} + +export enum EquipmentSlot { + Head, + Chest, + Legs, + Arms, + MainHand, + OffHand, + Feet +} + +export abstract class Equipment extends Item { + kind = ItemKind.Equipment + abstract slot: EquipmentSlot +} + +export abstract class Weapon extends Equipment { actions: Array = [] + slot = EquipmentSlot.MainHand - constructor (public name: Word, public desc: TextLike, damageFormula: DamageFormula, verb: Verb) { + constructor (name: Word, desc: TextLike, damageFormula: DamageFormula, verb: Verb) { + super(name, desc) const attack = new AttackAction(damageFormula, verb) attack.desc = new DynText(`Attack with your `, this.name.all) this.actions.push(attack) } } -export const Sword = new Weapon( - new ImproperNoun('sword', 'swords'), - 'An arming sword', - new StatDamageFormula([ - { fraction: 0.35, stat: Stat.Power, target: Vigor.Health, type: DamageType.Slash }, - { fraction: 0.25, stat: Stat.Power, target: Vigor.Health, type: DamageType.Pierce } - ]), - new Verb('slash', 'slashes') -) - -export const Dagger = new Weapon( - new ImproperNoun('dagger', 'daggers'), - 'A pointy dagger', - new StatDamageFormula([ - { fraction: 0.50, stat: Stat.Speed, target: Vigor.Health, type: DamageType.Pierce }, - { fraction: 0.05, stat: Stat.Speed, target: Vigor.Health, type: DamageType.Slash } - ]), - new Verb('stab', 'stabs', 'stabbing', 'stabbed') -) - -export const Wand = new Weapon( - new ImproperNoun('wand', 'wands'), - 'A magical wand', - new StatDamageFormula([ - { fraction: 0.25, stat: Stat.Charm, target: Vigor.Health, type: DamageType.Crush }, - { fraction: 0.25, stat: Stat.Willpower, target: Vigor.Health, type: DamageType.Crush } - ]), - new Verb('zap', 'zaps', 'zapping', 'zapped') -) - -export const Mace = new Weapon( - new ImproperNoun('mace', 'maces'), - 'A heavy mace', - new StatDamageFormula([ - { fraction: 0.4, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, - { fraction: 0.2, stat: Stat.Power, target: Vigor.Health, type: DamageType.Pierce } - ]), - new Verb('bash', 'bashes', 'bashing', 'bashed') -) +export class Sword extends Weapon { + constructor () { + super( + new ImproperNoun('sword', 'swords'), + 'An arming sword', + new StatDamageFormula([ + { fraction: 0.35, stat: Stat.Power, target: Vigor.Health, type: DamageType.Slash }, + { fraction: 0.25, stat: Stat.Power, target: Vigor.Health, type: DamageType.Pierce } + ]), + new Verb('slash', 'slashes') + ) + } +} + +export class Dagger extends Weapon { + constructor () { + super( + new ImproperNoun('dagger', 'daggers'), + 'A pointy dagger', + new StatDamageFormula([ + { fraction: 0.50, stat: Stat.Speed, target: Vigor.Health, type: DamageType.Pierce }, + { fraction: 0.05, stat: Stat.Speed, target: Vigor.Health, type: DamageType.Slash } + ]), + new Verb('stab', 'stabs', 'stabbing', 'stabbed') + ) + } +} + +export class Wand extends Weapon { + constructor () { + super( + new ImproperNoun('wand', 'wands'), + 'A magical wand', + new StatDamageFormula([ + { fraction: 0.25, stat: Stat.Charm, target: Vigor.Health, type: DamageType.Crush }, + { fraction: 0.25, stat: Stat.Willpower, target: Vigor.Health, type: DamageType.Crush } + ]), + new Verb('zap', 'zaps', 'zapping', 'zapped') + ) + } +} + +export class Mace extends Weapon { + constructor () { + super( + new ImproperNoun('mace', 'maces'), + 'A heavy mace', + new StatDamageFormula([ + { fraction: 0.4, stat: Stat.Power, target: Vigor.Health, type: DamageType.Crush }, + { fraction: 0.2, stat: Stat.Power, target: Vigor.Health, type: DamageType.Pierce } + ]), + new Verb('bash', 'bashes', 'bashing', 'bashed') + ) + } +} diff --git a/src/game/maps/town.ts b/src/game/maps/town.ts index 9732a37..984ce4e 100644 --- a/src/game/maps/town.ts +++ b/src/game/maps/town.ts @@ -17,7 +17,7 @@ function makeParty (): Creature[] { } }) fighter.title = "Lv. 6 Fighter" - fighter.items.push(Items.Sword) + fighter.equipment.set(Items.EquipmentSlot.MainHand, new Items.Sword()) const rogue = new Creatures.Human(new ProperNoun('Lidda'), FemalePronouns, { stats: { Toughness: 10, @@ -28,7 +28,7 @@ function makeParty (): Creature[] { } }) rogue.title = "Lv. 5 Rogue" - rogue.items.push(Items.Dagger) + rogue.equipment.set(Items.EquipmentSlot.MainHand, new Items.Dagger()) const wizard = new Creatures.Human(new ProperNoun('Mialee'), FemalePronouns, { stats: { Toughness: 10, @@ -39,7 +39,7 @@ function makeParty (): Creature[] { } }) wizard.title = "Lv. 6 Wizard" - wizard.items.push(Items.Wand) + wizard.equipment.set(Items.EquipmentSlot.MainHand, new Items.Wand()) const cleric = new Creatures.Human(new ProperNoun('Jozan'), MalePronouns, { stats: { Toughness: 15, @@ -50,7 +50,7 @@ function makeParty (): Creature[] { } }) cleric.title = "Lv. 5 Cleric" - cleric.items.push(Items.Mace) + cleric.equipment.set(Items.EquipmentSlot.MainHand, new Items.Mace()) return [fighter, cleric, rogue, wizard] } @@ -96,6 +96,21 @@ export const Town = (): Place => { ) ) + woods.choices.push( + new Choice( + "Fight a dragon", + "yolo", + (world, executor) => { + world.encounter = new Encounter( + { name: "You punched a dragon" }, + [executor, new Creatures.Dragon()] + ) + + return new LogLine(`FIGHT TIME`) + } + ) + ) + const bossEncounters = [ new Encounter( { name: "Withers & Kenzie" },