Made a new map that is a little bigger. New enemy - Samuel The boss, Inazuma, is now fightable. Updated old constructors for connecting places to allow for naming the walk direction(Instead of "Travel, go there lol")master
| @@ -16,7 +16,7 @@ module.exports = { | |||||
| 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', | ||||
| 'no-useless-constructor': 'off', | 'no-useless-constructor': 'off', | ||||
| '@typescript-eslint/no-unused-vars': 'off', | '@typescript-eslint/no-unused-vars': 'off', | ||||
| 'quotes': 'off', | |||||
| quotes: 'off', | |||||
| 'function-paren-newline': ['error', 'multiline-arguments'], | 'function-paren-newline': ['error', 'multiline-arguments'], | ||||
| '@typescript-eslint/member-ordering': ['warn'] | '@typescript-eslint/member-ordering': ['warn'] | ||||
| } | } | ||||
| @@ -29,10 +29,10 @@ import { Creature } from '@/game/creature' | |||||
| import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun, POV } from '@/game/language' | import { ProperNoun, TheyPronouns, FemalePronouns, MalePronouns, ImproperNoun, POV } from '@/game/language' | ||||
| import { Place, Direction, World, Choice } from '@/game/world' | import { Place, Direction, World, Choice } from '@/game/world' | ||||
| import { Encounter, Side } from '@/game/combat' | import { Encounter, Side } from '@/game/combat' | ||||
| import { LogLine, nilLog } from '@/game/interface' | |||||
| import { LogLine, Newline, nilLog } from '@/game/interface' | |||||
| import { InstantKillEffect } from '@/game/combat/effects' | import { InstantKillEffect } from '@/game/combat/effects' | ||||
| import moment from 'moment' | import moment from 'moment' | ||||
| import { Town } from '@/game/maps/town' | |||||
| import { Newtown } from '@/game/maps/Newtown' | |||||
| import Player from './game/creatures/player' | import Player from './game/creatures/player' | ||||
| @Component({ | @Component({ | ||||
| @@ -84,7 +84,7 @@ export default class App extends Vue { | |||||
| player.items.push(new Items.Mace()) | player.items.push(new Items.Mace()) | ||||
| player.items.push(new Items.Dagger()) | player.items.push(new Items.Dagger()) | ||||
| this.$data.world = new World(player) | this.$data.world = new World(player) | ||||
| this.$data.home = Town() | |||||
| this.$data.home = Newtown() | |||||
| player.location = this.$data.home | player.location = this.$data.home | ||||
| } | } | ||||
| @@ -2,7 +2,7 @@ | |||||
| <div class="character-layout"> | <div class="character-layout"> | ||||
| <button @click="$emit('exit')" class="profile-exit">Exit</button> | <button @click="$emit('exit')" class="profile-exit">Exit</button> | ||||
| <div class="character-items"> | <div class="character-items"> | ||||
| <ItemView @click.native="useItem(item)" :item="item" v-for="(item, index) in subject.items" :key="'item-' + index" /> | |||||
| <ItemView @click.native="useItem(item)" :item="item" v-for="(item, index) in subject.items" :key="'item-' + index" /> | |||||
| </div> | </div> | ||||
| <div class="character-containers"> | <div class="character-containers"> | ||||
| <ContainerView :container="container" v-for="(container, index) in subject.containers" :key="'explore-container-' + index" /> | <ContainerView :container="container" v-for="(container, index) in subject.containers" :key="'explore-container-' + index" /> | ||||
| @@ -36,7 +36,7 @@ import EquipmentView from '@/components/EquipmentView.vue' | |||||
| import { Creature } from '@/game/creature' | import { Creature } from '@/game/creature' | ||||
| import { World } from '@/game/world' | import { World } from '@/game/world' | ||||
| import { LogEntry } from '@/game/interface' | import { LogEntry } from '@/game/interface' | ||||
| import { Item, ItemKind, Equipment } from '@/game/items' | |||||
| import { Item, ItemKind, Equipment, KeyItem } from '@/game/items' | |||||
| @Component({ | @Component({ | ||||
| components: { | components: { | ||||
| Statblock, ContainerView, ItemView, EquipmentView | Statblock, ContainerView, ItemView, EquipmentView | ||||
| @@ -0,0 +1,38 @@ | |||||
| import { NoPassDecider, AI } from '@/game/ai' | |||||
| import { CompositionAction, UniformRandomDamageFormula, Damage, DamageType, FractionDamageFormula, Side, Stat, StatDamageFormula, Vigor } from '@/game/combat' | |||||
| import { AttackAction } from '@/game/combat/actions' | |||||
| import { PairCondition, TogetherCondition } from '@/game/combat/conditions' | |||||
| import { ConsumeConsequence, DamageConsequence, DrainConsequence, StatusConsequence } from '@/game/combat/consequences' | |||||
| import { LogGroupConsequence } from '@/game/combat/groupConsequences' | |||||
| import { PreyTargeter, SideTargeter, SoloTargeter } from '@/game/combat/targeters' | |||||
| import { CompositionTest, OpposedStatScorer, TestCategory } from '@/game/combat/tests' | |||||
| import { Creature } from '@/game/creature' | |||||
| import { LogLine, nilLog } from '@/game/interface' | |||||
| import { ImproperNoun, MalePronouns, ProperNoun, Verb } from '@/game/language' | |||||
| import { anyVore, Stomach } from '@/game/vore' | |||||
| export default class Samuel extends Creature { | |||||
| constructor () { | |||||
| super( | |||||
| new ProperNoun("Samuel"), | |||||
| new ImproperNoun("wolf"), | |||||
| MalePronouns, | |||||
| { | |||||
| Power: 20, | |||||
| Toughness: 10, | |||||
| Agility: 30, | |||||
| Reflexes: 10, | |||||
| Charm: 30, | |||||
| Willpower: 15 | |||||
| }, | |||||
| anyVore, | |||||
| new Set(), | |||||
| 10 | |||||
| ) | |||||
| this.side = Side.Monsters | |||||
| this.ai = (new AI([new NoPassDecider()], this)) | |||||
| this.actions.push(new AttackAction(new UniformRandomDamageFormula(new Damage({ type: DamageType.Slash, amount: 10, target: Vigor.Health }), 0.5), new Verb("claw", "claws", "claws", "clawed"))) | |||||
| } | |||||
| } | |||||
| @@ -23,7 +23,7 @@ export default class Player extends Creature { | |||||
| const stomach = new Stomach(this, 2, new ConstantDamageFormula(new Damage({ amount: 20, type: DamageType.Acid, target: Vigor.Health }, { amount: 10, type: DamageType.Crush, target: Vigor.Health }))) | const stomach = new Stomach(this, 2, new ConstantDamageFormula(new Damage({ amount: 20, type: DamageType.Acid, target: Vigor.Health }, { amount: 10, type: DamageType.Crush, target: Vigor.Health }))) | ||||
| this.addVoreContainer(stomach) | this.addVoreContainer(stomach) | ||||
| this.perspective = POV.First | |||||
| this.perspective = POV.Second | |||||
| this.ai = new VoreAI(this) | this.ai = new VoreAI(this) | ||||
| } | } | ||||
| @@ -37,7 +37,6 @@ export abstract class Item implements Actionable { | |||||
| abstract kind: ItemKind | abstract kind: ItemKind | ||||
| constructor (public name: Word, public desc: TextLike) { | constructor (public name: Word, public desc: TextLike) { | ||||
| } | } | ||||
| } | } | ||||
| @@ -169,7 +168,11 @@ export class ItemAction extends Action { | |||||
| } | } | ||||
| execute (user: Creature, target: Creature): LogEntry { | execute (user: Creature, target: Creature): LogEntry { | ||||
| if (this.item.consumed) { | |||||
| return new LogLine(`You have already consumed this `.concat(this.item.name.toString())) // Keeps the [[Consumable]] from being used twice, even if the element still exists | |||||
| } | |||||
| this.item.consumed = true | this.item.consumed = true | ||||
| delete user.items[user.items.indexOf(this.item)] // Removes [[Consumable]], but does not remove the element till the next gui draw (Not keen in html) | |||||
| return this.action.execute(user, target) | return this.action.execute(user, target) | ||||
| } | } | ||||
| @@ -195,7 +198,7 @@ export class Consumable extends Item { | |||||
| export abstract class Potion extends Consumable { | export abstract class Potion extends Consumable { | ||||
| constructor (name: ImproperNoun, desc: string, consequences: Array<Consequence>) { | constructor (name: ImproperNoun, desc: string, consequences: Array<Consequence>) { | ||||
| super( | super( | ||||
| new ImproperNoun("health potion"), | |||||
| name, | |||||
| desc, | desc, | ||||
| new CompositionAction( | new CompositionAction( | ||||
| "Drink " + name, | "Drink " + name, | ||||
| @@ -537,14 +537,14 @@ export const SecondPersonPronouns = new Pronoun({ | |||||
| objective: 'you', | objective: 'you', | ||||
| possessive: 'your', | possessive: 'your', | ||||
| reflexive: 'yourself' | reflexive: 'yourself' | ||||
| }, false, true) | |||||
| }) | |||||
| export const FirstPersonPronouns = new Pronoun({ | export const FirstPersonPronouns = new Pronoun({ | ||||
| subjective: 'I', | subjective: 'I', | ||||
| objective: 'me', | objective: 'me', | ||||
| possessive: 'my', | possessive: 'my', | ||||
| reflexive: 'myself' | reflexive: 'myself' | ||||
| }, false, true) | |||||
| }) | |||||
| export class PronounAsNoun extends Noun { | export class PronounAsNoun extends Noun { | ||||
| constructor (private pronouns: Pronoun, opt: WordOptions = emptyConfig) { | constructor (private pronouns: Pronoun, opt: WordOptions = emptyConfig) { | ||||
| @@ -0,0 +1,349 @@ | |||||
| import { Place, Choice, Direction, World } from '@/game/world' | |||||
| import { ProperNoun, ImproperNoun, MalePronouns, FemalePronouns, TheyPronouns } from '@/game/language' | |||||
| import { Encounter, Stat, Damage, DamageType, Vigor, Side } from '@/game/combat' | |||||
| import * as Items from '@/game/items' | |||||
| import { LogLine, nilLog, LogLines } from '@/game/interface' | |||||
| import { Creature } from '@/game/creature' | |||||
| import { DevourAction } from '@/game/combat/actions' | |||||
| import { InstantDigestionEffect, SurrenderEffect } from '@/game/combat/effects' | |||||
| import moment from 'moment' | |||||
| import { VoreAI } from '@/game/ai' | |||||
| import { DeliciousPerk } from '@/game/combat/perks' | |||||
| import Inazuma from '../creatures/characters/inazuma' | |||||
| import Samuel from '../creatures/characters/Samuel' | |||||
| import Human from '../creatures/human' | |||||
| import Slime from '../creatures/monsters/slime' | |||||
| function makeParty (): Creature[] { | |||||
| const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, { | |||||
| stats: { | |||||
| Toughness: 20, | |||||
| Power: 20, | |||||
| Reflexes: 15, | |||||
| Agility: 15, | |||||
| Willpower: 15, | |||||
| Charm: 10 | |||||
| } | |||||
| }) | |||||
| fighter.title = "Lv. 6 Fighter" | |||||
| fighter.equip(new Items.Sword(), Items.EquipmentSlot.MainHand) | |||||
| const rogue = new Human(new ProperNoun('Lidda'), FemalePronouns, { | |||||
| stats: { | |||||
| Toughness: 10, | |||||
| Power: 15, | |||||
| Reflexes: 20, | |||||
| Agility: 20, | |||||
| Willpower: 15, | |||||
| Charm: 20 | |||||
| } | |||||
| }) | |||||
| rogue.title = "Lv. 5 Rogue" | |||||
| rogue.equip(new Items.Dagger(), Items.EquipmentSlot.MainHand) | |||||
| const wizard = new Human(new ProperNoun('Mialee'), FemalePronouns, { | |||||
| stats: { | |||||
| Toughness: 10, | |||||
| Power: 10, | |||||
| Reflexes: 15, | |||||
| Agility: 15, | |||||
| Willpower: 20, | |||||
| Charm: 25 | |||||
| } | |||||
| }) | |||||
| wizard.title = "Lv. 6 Wizard" | |||||
| wizard.equip(new Items.Wand(), Items.EquipmentSlot.MainHand) | |||||
| const cleric = new Human(new ProperNoun('Jozan'), MalePronouns, { | |||||
| stats: { | |||||
| Toughness: 15, | |||||
| Power: 15, | |||||
| Reflexes: 10, | |||||
| Agility: 10, | |||||
| Willpower: 20, | |||||
| Charm: 15 | |||||
| } | |||||
| }) | |||||
| cleric.title = "Lv. 5 Cleric" | |||||
| cleric.equip(new Items.Mace(), Items.EquipmentSlot.MainHand) | |||||
| return [fighter, cleric, rogue, wizard] | |||||
| } | |||||
| export const Newtown = (): Place => { | |||||
| const home = new Place( | |||||
| new ProperNoun("Home"), | |||||
| "A place you can rest after long adventures" | |||||
| ) | |||||
| const debug = new Place( | |||||
| new ProperNoun("Debug Room"), | |||||
| "Where weird stuff happens" | |||||
| ) | |||||
| const southTownStreet = new Place( | |||||
| new ProperNoun("South Town Street"), | |||||
| "Town street south of the Town square" | |||||
| ) | |||||
| const northTownStreet = new Place( | |||||
| new ProperNoun("North Town Street"), | |||||
| "Town street north of the Town square" | |||||
| ) | |||||
| const eastTownStreet = new Place( | |||||
| new ProperNoun("East Town Street"), | |||||
| "Town street east of the Town square" | |||||
| ) | |||||
| const westTownStreet = new Place( | |||||
| new ProperNoun("West Town Street"), | |||||
| "Town street west of the Town square" | |||||
| ) | |||||
| const townSquare = new Place( | |||||
| new ProperNoun("Town Square"), | |||||
| "The central-most part of town, and a hub of bustling activity" | |||||
| ) | |||||
| const eastGate = new Place( | |||||
| new ProperNoun("East Gate"), | |||||
| "The towns gate, leading out into the wilderness" | |||||
| ) | |||||
| const woods = new Place( | |||||
| new ProperNoun("The Woods"), | |||||
| "A scary part of the forest where monsters hide" | |||||
| ) | |||||
| const deepwoods = new Place( | |||||
| new ProperNoun("Deep Woods"), | |||||
| "Extra scary" | |||||
| ) | |||||
| deepwoods.choices.push( | |||||
| new Choice( | |||||
| "Fight Inazuma", | |||||
| "Go fight Inazuma!", | |||||
| (world, executor) => { | |||||
| const enemy = new Inazuma() | |||||
| const encounter = new Encounter( | |||||
| { | |||||
| name: "Fight some tough nerd", | |||||
| intro: () => new LogLine(`Inazuma Approaches!`) | |||||
| }, | |||||
| [world.player, enemy].concat(world.party) | |||||
| ) | |||||
| world.encounter = encounter | |||||
| return nilLog | |||||
| } | |||||
| ) | |||||
| ) | |||||
| const bossEncounters = [ | |||||
| new Encounter( | |||||
| { name: "Inazuma", intro: () => nilLog }, | |||||
| makeParty().concat([new Inazuma()]) | |||||
| ) | |||||
| ] | |||||
| home.choices.push( | |||||
| new Choice( | |||||
| "Nap", | |||||
| "Zzzzzz", | |||||
| (world) => { | |||||
| return new LogLines( | |||||
| `You lie down for a nice nap...`, | |||||
| world.advance(moment.duration(1, "hour")) | |||||
| ) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| home.choices.push( | |||||
| new Choice( | |||||
| "Heal", | |||||
| "Become not dead and/or eaten", | |||||
| (world, executor) => { | |||||
| Object.keys(Vigor).forEach(vigor => { | |||||
| executor.vigors[vigor as Vigor] = executor.maxVigors[vigor as Vigor] | |||||
| }) | |||||
| if (executor.containedIn !== null) { | |||||
| executor.containedIn.release(executor) | |||||
| } | |||||
| executor.statusEffects.forEach(effect => { | |||||
| executor.removeEffect(effect) | |||||
| }) | |||||
| executor.destroyed = false | |||||
| return new LogLine(`You're healthy again`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| home.choices.push( | |||||
| new Choice( | |||||
| "Grab potions", | |||||
| "Grab some potions", | |||||
| (world, executor) => { | |||||
| executor.items.push(new Items.HealthPotion()) | |||||
| executor.items.push(new Items.AcidPotion()) | |||||
| executor.items.push(new Items.ShrinkPotion()) | |||||
| executor.items.push(new Items.StrengthPotion()) | |||||
| return new LogLine("You grab some potions") | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Cut stats", | |||||
| "Make your stats less 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.Pure } | |||||
| )) | |||||
| }) | |||||
| return new LogLine(`You're weaker now`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.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`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Grow", | |||||
| "Make yourself larger", | |||||
| (world, executor) => { | |||||
| executor.voreStats.Mass *= 1.5 | |||||
| return new LogLine(`You're larger now`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Shrink", | |||||
| "Make yourself smaller", | |||||
| (world, executor) => { | |||||
| executor.voreStats.Mass /= 1.5 | |||||
| return new LogLine(`You're smaller now`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Instant Digestion", | |||||
| "Make your stomach REALLY powerful", | |||||
| (world, executor) => { | |||||
| executor.applyEffect(new InstantDigestionEffect()) | |||||
| return new LogLine(`You're really gonna melt people now.`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Set Name", | |||||
| "Set your name", | |||||
| (world, executor) => { | |||||
| const input = prompt("Enter a name") | |||||
| if (input !== null) { | |||||
| executor.baseName = new ProperNoun(input) | |||||
| return new LogLine(`Your new name is ${executor.baseName}.`) | |||||
| } else { | |||||
| return new LogLine(`nvm`) | |||||
| } | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | |||||
| new Choice( | |||||
| "Add money", | |||||
| "Get some money", | |||||
| (world, executor) => { | |||||
| executor.wallet.Gold += 1000 | |||||
| return new LogLine(`$$$$$$$$$$$$$$$$$`) | |||||
| } | |||||
| ) | |||||
| ) | |||||
| woods.choices.push( | |||||
| new Choice( | |||||
| "Fight a slime", | |||||
| "Go fight a slime", | |||||
| (world, executor) => { | |||||
| const enemy = new Slime() | |||||
| const encounter = new Encounter( | |||||
| { | |||||
| name: "Fight some tasty nerd", | |||||
| intro: () => new LogLine(`A slime draws near!`) | |||||
| }, | |||||
| [world.player, enemy].concat(world.party) | |||||
| ) | |||||
| world.encounter = encounter | |||||
| return nilLog | |||||
| } | |||||
| ) | |||||
| ) | |||||
| woods.choices.push( | |||||
| new Choice( | |||||
| "Fight Samuel", | |||||
| "Go fight a poor little wolf!", | |||||
| (world, executor) => { | |||||
| const enemy = new Samuel() | |||||
| const encounter = new Encounter( | |||||
| { | |||||
| name: "Fight some tasty nerd", | |||||
| intro: () => new LogLine(`Samuel pokes his head out from the bushes!`) | |||||
| }, | |||||
| [world.player, enemy].concat(world.party) | |||||
| ) | |||||
| world.encounter = encounter | |||||
| return nilLog | |||||
| } | |||||
| ) | |||||
| ) | |||||
| const bosses = new Place( | |||||
| new ProperNoun("BOSS ZONE"), | |||||
| "Extra scary" | |||||
| ) | |||||
| bossEncounters.forEach(encounter => { | |||||
| bosses.choices.push( | |||||
| new Choice( | |||||
| encounter.desc.name, | |||||
| "Boss fight!", | |||||
| (world) => { | |||||
| world.encounter = encounter | |||||
| return nilLog | |||||
| } | |||||
| ) | |||||
| ) | |||||
| }) | |||||
| home.biconnect(Direction.South, debug, "Walk", "Enter the debug room", "Leave", "Exit the debug room") | |||||
| home.biconnect(Direction.Northeast, townSquare, "Leave", "Go outside", "Enter", "Enter your home") | |||||
| townSquare.biconnect(Direction.North, northTownStreet, "Walk", "Go that way", "Walk", "Go that way") | |||||
| townSquare.biconnect(Direction.East, eastTownStreet, "Walk", "Go that way", "Walk", "Go that way") | |||||
| townSquare.biconnect(Direction.South, southTownStreet, "Walk", "Go that way", "Walk", "Go that way") | |||||
| townSquare.biconnect(Direction.West, westTownStreet, "Walk", "Go that way", "Walk", "Go that way") | |||||
| debug.biconnect(Direction.South, bosses, "Enter", "Boss Fight!", "Leave", "Go back to the debug room") | |||||
| eastTownStreet.biconnect(Direction.East, eastGate, "Walk", "Go that way", "Walk", "Go that way") | |||||
| eastGate.biconnect(Direction.East, woods, "Walk", "Enter the woods", "Approach", "Enter the city gates") | |||||
| woods.biconnect(Direction.North, deepwoods, "Walk", "Go deeper", "Walk", "Leave the deep woods") | |||||
| return home | |||||
| } | |||||
| @@ -12,6 +12,7 @@ import { DeliciousPerk } from '@/game/combat/perks' | |||||
| import Inazuma from '../creatures/characters/inazuma' | import Inazuma from '../creatures/characters/inazuma' | ||||
| import Human from '../creatures/human' | import Human from '../creatures/human' | ||||
| import Slime from '../creatures/monsters/slime' | import Slime from '../creatures/monsters/slime' | ||||
| import Samuel from '../creatures/characters/Samuel' | |||||
| function makeParty (): Creature[] { | function makeParty (): Creature[] { | ||||
| const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, { | const fighter = new Human(new ProperNoun("Redgar"), MalePronouns, { | ||||
| @@ -340,6 +341,25 @@ export const Town = (): Place => { | |||||
| ) | ) | ||||
| ) | ) | ||||
| woods.choices.push( | |||||
| new Choice( | |||||
| "Fight Samuel", | |||||
| "Go fight a poor little wolf!", | |||||
| (world, executor) => { | |||||
| const enemy = new Samuel() | |||||
| const encounter = new Encounter( | |||||
| { | |||||
| name: "Fight some tasty nerd", | |||||
| intro: () => new LogLine(`Samuel pokes his head out from the bushes!`) | |||||
| }, | |||||
| [world.player, enemy].concat(world.party) | |||||
| ) | |||||
| world.encounter = encounter | |||||
| return nilLog | |||||
| } | |||||
| ) | |||||
| ) | |||||
| debug.choices.push( | debug.choices.push( | ||||
| new Choice( | new Choice( | ||||
| "Add money", | "Add money", | ||||
| @@ -351,8 +371,8 @@ export const Town = (): Place => { | |||||
| ) | ) | ||||
| ) | ) | ||||
| home.biconnect(Direction.South, debug) | |||||
| debug.biconnect(Direction.South, bosses) | |||||
| home.biconnect(Direction.South, debug, "Walk", "Enter the debug room", "Leave", "Exit the debug room") | |||||
| debug.biconnect(Direction.South, bosses, "Enter", "Boss Fight!", "Leave", "Go back to the debug room") | |||||
| home.biconnect(Direction.North, square) | home.biconnect(Direction.North, square) | ||||
| westRoad.biconnect(Direction.South, woods) | westRoad.biconnect(Direction.South, woods) | ||||
| square.biconnect(Direction.West, westRoad) | square.biconnect(Direction.West, westRoad) | ||||
| @@ -29,34 +29,55 @@ export function reverse (dir: Direction): Direction { | |||||
| } | } | ||||
| export class Choice { | export class Choice { | ||||
| isAccessible: boolean | |||||
| isVisible: boolean | |||||
| constructor (public name: TextLike, public desc: TextLike, public execute: (world: World, executor: Creature) => LogEntry) { | constructor (public name: TextLike, public desc: TextLike, public execute: (world: World, executor: Creature) => LogEntry) { | ||||
| this.isAccessible = true | |||||
| this.isVisible = true | |||||
| } | } | ||||
| /** | |||||
| * Gets the choice's visiblity. No funtionality at the moment. | |||||
| */ | |||||
| visible (): boolean { | visible (): boolean { | ||||
| return true | return true | ||||
| } | } | ||||
| /** | |||||
| * Gets the choice's visiblity. No funtionality at the moment. | |||||
| */ | |||||
| accessible (): boolean { | accessible (): boolean { | ||||
| return true | return true | ||||
| } | } | ||||
| } | } | ||||
| export class Connection { | export class Connection { | ||||
| isAccessible: boolean | |||||
| isVisible: boolean | |||||
| constructor (public src: Place, public dst: Place, public name: TextLike = "Travel", public desc: TextLike = "Go there lol") { | constructor (public src: Place, public dst: Place, public name: TextLike = "Travel", public desc: TextLike = "Go there lol") { | ||||
| this.isAccessible = true | |||||
| this.isVisible = true | |||||
| } | } | ||||
| /** | |||||
| * Gets the connection's visiblity. No funtionality at the moment. | |||||
| */ | |||||
| visible (): boolean { | visible (): boolean { | ||||
| return true | |||||
| return this.isVisible | |||||
| } | } | ||||
| /** | |||||
| * Gets the connection's accessibility. No funtionality at the moment. | |||||
| */ | |||||
| accessible (): boolean { | accessible (): boolean { | ||||
| return true | |||||
| return this.isAccessible | |||||
| } | } | ||||
| travel (world: World, traveler: Creature): LogEntry { | |||||
| const advanceLogs = world.advance(moment.duration(5, "minutes")) | |||||
| /** | |||||
| * Moves [[traveler]] through this connection to [[dst]] and progresses the time by [[moveTime]]. | |||||
| */ | |||||
| travel (world: World, traveler: Creature, moveTime: Duration = moment.duration(5, "minutes")): LogEntry { | |||||
| const advanceLogs = world.advance(moveTime) | |||||
| traveler.location = this.dst | traveler.location = this.dst | ||||
| return new LogLines( | return new LogLines( | ||||
| advanceLogs, | advanceLogs, | ||||
| @@ -73,13 +94,19 @@ export class Place { | |||||
| } | } | ||||
| connect (dir: Direction, dst: Place) { | |||||
| this.connections[dir] = new Connection(this, dst) | |||||
| /** | |||||
| * Connects a room one way. | |||||
| */ | |||||
| connect (dir: Direction, dst: Place, name: TextLike = "Travel", desc: TextLike = "Go there lol") { | |||||
| this.connections[dir] = new Connection(this, dst, name, desc) | |||||
| } | } | ||||
| biconnect (dir: Direction, dst: Place) { | |||||
| this.connect(dir, dst) | |||||
| dst.connect(reverse(dir), this) | |||||
| /** | |||||
| * Connects two rooms and names both hover boxes. | |||||
| */ | |||||
| biconnect (dir: Direction, dst: Place, name1: TextLike = "Travel", desc1: TextLike = "Go there lol", name2: TextLike = "Travel", desc2: TextLike = "Go there lol") { | |||||
| this.connect(dir, dst, name1, desc1) | |||||
| dst.connect(reverse(dir), this, name2, desc2) | |||||
| } | } | ||||
| } | } | ||||
| @@ -99,6 +126,9 @@ export class World { | |||||
| this.creatures.push(player) | this.creatures.push(player) | ||||
| } | } | ||||
| /** | |||||
| * Progresses the clock. | |||||
| */ | |||||
| advance (dt: Duration): LogEntry { | advance (dt: Duration): LogEntry { | ||||
| this.time.add(dt) | this.time.add(dt) | ||||
| return new LogLines( | return new LogLines( | ||||