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-useless-constructor': 'off', | |||
| '@typescript-eslint/no-unused-vars': 'off', | |||
| 'quotes': 'off', | |||
| quotes: 'off', | |||
| 'function-paren-newline': ['error', 'multiline-arguments'], | |||
| '@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 { Place, Direction, World, Choice } from '@/game/world' | |||
| 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 moment from 'moment' | |||
| import { Town } from '@/game/maps/town' | |||
| import { Newtown } from '@/game/maps/Newtown' | |||
| import Player from './game/creatures/player' | |||
| @Component({ | |||
| @@ -84,7 +84,7 @@ export default class App extends Vue { | |||
| player.items.push(new Items.Mace()) | |||
| player.items.push(new Items.Dagger()) | |||
| this.$data.world = new World(player) | |||
| this.$data.home = Town() | |||
| this.$data.home = Newtown() | |||
| player.location = this.$data.home | |||
| } | |||
| @@ -2,7 +2,7 @@ | |||
| <div class="character-layout"> | |||
| <button @click="$emit('exit')" class="profile-exit">Exit</button> | |||
| <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 class="character-containers"> | |||
| <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 { World } from '@/game/world' | |||
| import { LogEntry } from '@/game/interface' | |||
| import { Item, ItemKind, Equipment } from '@/game/items' | |||
| import { Item, ItemKind, Equipment, KeyItem } from '@/game/items' | |||
| @Component({ | |||
| components: { | |||
| 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 }))) | |||
| this.addVoreContainer(stomach) | |||
| this.perspective = POV.First | |||
| this.perspective = POV.Second | |||
| this.ai = new VoreAI(this) | |||
| } | |||
| @@ -37,7 +37,6 @@ export abstract class Item implements Actionable { | |||
| abstract kind: ItemKind | |||
| constructor (public name: Word, public desc: TextLike) { | |||
| } | |||
| } | |||
| @@ -169,7 +168,11 @@ export class ItemAction extends Action { | |||
| } | |||
| 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 | |||
| 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) | |||
| } | |||
| @@ -195,7 +198,7 @@ export class Consumable extends Item { | |||
| export abstract class Potion extends Consumable { | |||
| constructor (name: ImproperNoun, desc: string, consequences: Array<Consequence>) { | |||
| super( | |||
| new ImproperNoun("health potion"), | |||
| name, | |||
| desc, | |||
| new CompositionAction( | |||
| "Drink " + name, | |||
| @@ -537,14 +537,14 @@ export const SecondPersonPronouns = new Pronoun({ | |||
| objective: 'you', | |||
| possessive: 'your', | |||
| reflexive: 'yourself' | |||
| }, false, true) | |||
| }) | |||
| export const FirstPersonPronouns = new Pronoun({ | |||
| subjective: 'I', | |||
| objective: 'me', | |||
| possessive: 'my', | |||
| reflexive: 'myself' | |||
| }, false, true) | |||
| }) | |||
| export class PronounAsNoun extends Noun { | |||
| 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 Human from '../creatures/human' | |||
| import Slime from '../creatures/monsters/slime' | |||
| import Samuel from '../creatures/characters/Samuel' | |||
| function makeParty (): Creature[] { | |||
| 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( | |||
| new Choice( | |||
| "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) | |||
| westRoad.biconnect(Direction.South, woods) | |||
| square.biconnect(Direction.West, westRoad) | |||
| @@ -29,34 +29,55 @@ export function reverse (dir: Direction): Direction { | |||
| } | |||
| export class Choice { | |||
| isAccessible: boolean | |||
| isVisible: boolean | |||
| 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 { | |||
| return true | |||
| } | |||
| /** | |||
| * Gets the choice's visiblity. No funtionality at the moment. | |||
| */ | |||
| accessible (): boolean { | |||
| return true | |||
| } | |||
| } | |||
| export class Connection { | |||
| isAccessible: boolean | |||
| isVisible: boolean | |||
| 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 { | |||
| return true | |||
| return this.isVisible | |||
| } | |||
| /** | |||
| * Gets the connection's accessibility. No funtionality at the moment. | |||
| */ | |||
| 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 | |||
| return new LogLines( | |||
| 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) | |||
| } | |||
| /** | |||
| * Progresses the clock. | |||
| */ | |||
| advance (dt: Duration): LogEntry { | |||
| this.time.add(dt) | |||
| return new LogLines( | |||