import { Place, Choice, Direction, World } from '../world' import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '../language' import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '../combat' import * as Creatures from '../creatures' import * as Items from '../items' import { LogLine, nilLog, LogLines } from '../interface' import { Creature } from '../creature' import { DevourAction } from '../combat/actions' import { SurrenderEffect } from '../combat/effects' import moment from 'moment' import { RandomAI } from '../ai' function makeParty (): Creature[] { const fighter = new Creatures.Human(new ProperNoun("Redgar"), MalePronouns, { stats: { Toughness: 20, Power: 20, Speed: 15, Willpower: 15, Charm: 10 } }) fighter.title = "Lv. 6 Fighter" fighter.equipment.set(Items.EquipmentSlot.MainHand, new Items.Sword()) const rogue = new Creatures.Human(new ProperNoun('Lidda'), FemalePronouns, { stats: { Toughness: 10, Power: 15, Speed: 20, Willpower: 15, Charm: 20 } }) rogue.title = "Lv. 5 Rogue" rogue.equipment.set(Items.EquipmentSlot.MainHand, new Items.Dagger()) const wizard = new Creatures.Human(new ProperNoun('Mialee'), FemalePronouns, { stats: { Toughness: 10, Power: 10, Speed: 15, Willpower: 20, Charm: 25 } }) wizard.title = "Lv. 6 Wizard" wizard.equipment.set(Items.EquipmentSlot.MainHand, new Items.Wand()) const cleric = new Creatures.Human(new ProperNoun('Jozan'), MalePronouns, { stats: { Toughness: 15, Power: 15, Speed: 10, Willpower: 20, Charm: 15 } }) cleric.title = "Lv. 5 Cleric" cleric.equipment.set(Items.EquipmentSlot.MainHand, new Items.Mace()) return [fighter, cleric, rogue, wizard] } export const Town = (): Place => { const home = new Place( new ProperNoun('Your home'), "A very home-y place" ) const westAve = new Place( new ImproperNoun('West Avenue'), "Streets of Sim City" ) const westRoad = new Place( new ImproperNoun('road'), "West of town" ) const woods = new Place( new ImproperNoun('woods'), "Scary woods" ) const bosses = new Place( new ProperNoun("BOSS ZONE"), "Extra scary" ) const loop = new Place( new ProperNoun("Loop"), "This place is a loop" ) woods.choices.push( new Choice( "Fight a wolf", "yolo", (world, executor) => { world.encounter = new Encounter( { name: "You punched a wolf", intro: (world: World) => new LogLine(`You punched a wolf. The wolf is angry.`) }, [executor, new Creatures.Wolf()] ) return new LogLine(`FIGHT TIME`) } ) ) woods.choices.push( new Choice( "Fight a dragon", "yolo", (world, executor) => { world.encounter = new Encounter( { name: "You punched a dragon", intro: (world: World) => new LogLine(`You punched a dragon. The dragon is angry.`) }, [executor, new Creatures.Dragon()] ) return new LogLine(`FIGHT TIME`) } ) ) const bossEncounters = [ new Encounter( { name: "Withers & Kenzie", intro: (world: World) => nilLog }, makeParty().concat([new Creatures.Withers(), new Creatures.Kenzie()]) ), new Encounter( { name: "Goldeneye", intro: (world: World) => nilLog }, makeParty().concat([new Creatures.Goldeneye()]) ), new Encounter( { name: "Large Wah", intro: (world: World) => nilLog }, makeParty().concat([new Creatures.Shingo()]) ) ] home.choices.push( new Choice( "Nap", "Zzzzzz", (world, executor) => { return new LogLines( `You lie down for a nice nap...`, world.advance(moment.duration(1, "hour")) ) } ) ) home.choices.push( new Choice( "Boost stats", "Make your stats more good-er", (world, executor) => { Object.keys(Stat).forEach(stat => { executor.baseStats[stat as Stat] += 5 executor.takeDamage(new Damage( { amount: 5, target: (stat as Stat), type: DamageType.Heal } )) }) return new LogLine(`You're stronger now`) } ) ) home.choices.push( new Choice( "Heal", "Become not dead", (world, executor) => { Object.keys(Vigor).forEach(vigor => { executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor] }) return new LogLine(`You're stronger now`) } ) ) westAve.choices.push( new Choice( "Eat someone", "Slurp", (world, executor) => { const snack = new Creatures.Human(new ProperNoun(["Snack", "Treat", "Tasty", "Dinner", "Appetizer"][Math.floor(Math.random() * 5)]), TheyPronouns) snack.applyEffect(new SurrenderEffect()) const options = executor.validActions(snack).filter(action => action instanceof DevourAction) return options[Math.floor(options.length * Math.random())].execute(executor, snack) } ) ) westAve.choices.push( new Choice( "Fight someone", "Ow", (world, executor) => { const enemy = new Creatures.Human(new ProperNoun("Nerd"), TheyPronouns) enemy.side = Side.Monsters enemy.ai = new RandomAI() const encounter = new Encounter( { name: "Fight some nerd", intro: world => new LogLine(`You find some nerd to fight.`) }, [world.player, enemy] ) world.encounter = encounter return nilLog } ) ) bossEncounters.forEach(encounter => { bosses.choices.push( new Choice( encounter.desc.name, "Boss fight!", (world, executor) => { world.encounter = encounter return nilLog } ) ) }) for (let i = 0; i < 10; i++) { loop.choices.push( new Choice( "A choice", "This is a choice", (world, executor) => { return new LogLine(`This does not do anything.`) } ) ) } home.biconnect(Direction.North, westAve) westAve.biconnect(Direction.West, westRoad) westRoad.biconnect(Direction.South, woods) westRoad.biconnect(Direction.North, bosses) westAve.biconnect(Direction.East, loop) loop.connect(Direction.North, loop) loop.connect(Direction.South, loop) loop.connect(Direction.East, loop) loop.connect(Direction.Northwest, loop) loop.connect(Direction.Northeast, loop) loop.connect(Direction.Southwest, loop) loop.connect(Direction.Southeast, loop) return home }