@datamoc/mw_games 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +327 -0
- package/dist/actors/Advancement.d.ts +73 -0
- package/dist/actors/Advancement.d.ts.map +1 -0
- package/dist/actors/Advancement.js +98 -0
- package/dist/actors/Advancement.js.map +1 -0
- package/dist/actors/Affix.d.ts +44 -0
- package/dist/actors/Affix.d.ts.map +1 -0
- package/dist/actors/Affix.js +35 -0
- package/dist/actors/Affix.js.map +1 -0
- package/dist/actors/Appearances.d.ts +36 -0
- package/dist/actors/Appearances.d.ts.map +1 -0
- package/dist/actors/Appearances.js +50 -0
- package/dist/actors/Appearances.js.map +1 -0
- package/dist/actors/Charges.d.ts +31 -0
- package/dist/actors/Charges.d.ts.map +1 -0
- package/dist/actors/Charges.js +35 -0
- package/dist/actors/Charges.js.map +1 -0
- package/dist/actors/Equipment.d.ts +40 -0
- package/dist/actors/Equipment.d.ts.map +1 -0
- package/dist/actors/Equipment.js +57 -0
- package/dist/actors/Equipment.js.map +1 -0
- package/dist/actors/Inventory.d.ts +50 -0
- package/dist/actors/Inventory.d.ts.map +1 -0
- package/dist/actors/Inventory.js +56 -0
- package/dist/actors/Inventory.js.map +1 -0
- package/dist/actors/ItemState.d.ts +21 -0
- package/dist/actors/ItemState.d.ts.map +1 -0
- package/dist/actors/ItemState.js +34 -0
- package/dist/actors/ItemState.js.map +1 -0
- package/dist/actors/Loot.d.ts +24 -0
- package/dist/actors/Loot.d.ts.map +1 -0
- package/dist/actors/Loot.js +14 -0
- package/dist/actors/Loot.js.map +1 -0
- package/dist/actors/Progression.d.ts +30 -0
- package/dist/actors/Progression.d.ts.map +1 -0
- package/dist/actors/Progression.js +39 -0
- package/dist/actors/Progression.js.map +1 -0
- package/dist/actors/Resource.d.ts +23 -0
- package/dist/actors/Resource.d.ts.map +1 -0
- package/dist/actors/Resource.js +28 -0
- package/dist/actors/Resource.js.map +1 -0
- package/dist/actors/Scaling.d.ts +22 -0
- package/dist/actors/Scaling.d.ts.map +1 -0
- package/dist/actors/Scaling.js +9 -0
- package/dist/actors/Scaling.js.map +1 -0
- package/dist/actors/Shop.d.ts +25 -0
- package/dist/actors/Shop.d.ts.map +1 -0
- package/dist/actors/Shop.js +33 -0
- package/dist/actors/Shop.js.map +1 -0
- package/dist/actors/SkillPoints.d.ts +45 -0
- package/dist/actors/SkillPoints.d.ts.map +1 -0
- package/dist/actors/SkillPoints.js +58 -0
- package/dist/actors/SkillPoints.js.map +1 -0
- package/dist/actors/StatBlock.d.ts +52 -0
- package/dist/actors/StatBlock.d.ts.map +1 -0
- package/dist/actors/StatBlock.js +80 -0
- package/dist/actors/StatBlock.js.map +1 -0
- package/dist/actors/StatusEffect.d.ts +38 -0
- package/dist/actors/StatusEffect.d.ts.map +1 -0
- package/dist/actors/StatusEffect.js +28 -0
- package/dist/actors/StatusEffect.js.map +1 -0
- package/dist/actors/craft.d.ts +26 -0
- package/dist/actors/craft.d.ts.map +1 -0
- package/dist/actors/craft.js +34 -0
- package/dist/actors/craft.js.map +1 -0
- package/dist/actors/index.d.ts +33 -0
- package/dist/actors/index.d.ts.map +1 -0
- package/dist/actors/index.js +18 -0
- package/dist/actors/index.js.map +1 -0
- package/dist/actors/skillCheck.d.ts +13 -0
- package/dist/actors/skillCheck.d.ts.map +1 -0
- package/dist/actors/skillCheck.js +16 -0
- package/dist/actors/skillCheck.js.map +1 -0
- package/dist/assets/index.d.ts +37 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +62 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/audio/Music.d.ts +22 -0
- package/dist/audio/Music.d.ts.map +1 -0
- package/dist/audio/Music.js +67 -0
- package/dist/audio/Music.js.map +1 -0
- package/dist/audio/Playable.d.ts +16 -0
- package/dist/audio/Playable.d.ts.map +1 -0
- package/dist/audio/Playable.js +6 -0
- package/dist/audio/Playable.js.map +1 -0
- package/dist/audio/Sound.d.ts +23 -0
- package/dist/audio/Sound.d.ts.map +1 -0
- package/dist/audio/Sound.js +30 -0
- package/dist/audio/Sound.js.map +1 -0
- package/dist/audio/index.d.ts +7 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/index.js +4 -0
- package/dist/audio/index.js.map +1 -0
- package/dist/battle/BattleAI.d.ts +24 -0
- package/dist/battle/BattleAI.d.ts.map +1 -0
- package/dist/battle/BattleAI.js +47 -0
- package/dist/battle/BattleAI.js.map +1 -0
- package/dist/battle/Evolution.d.ts +22 -0
- package/dist/battle/Evolution.d.ts.map +1 -0
- package/dist/battle/Evolution.js +25 -0
- package/dist/battle/Evolution.js.map +1 -0
- package/dist/battle/Field.d.ts +25 -0
- package/dist/battle/Field.d.ts.map +1 -0
- package/dist/battle/Field.js +31 -0
- package/dist/battle/Field.js.map +1 -0
- package/dist/battle/Hooks.d.ts +29 -0
- package/dist/battle/Hooks.d.ts.map +1 -0
- package/dist/battle/Hooks.js +20 -0
- package/dist/battle/Hooks.js.map +1 -0
- package/dist/battle/Move.d.ts +32 -0
- package/dist/battle/Move.d.ts.map +1 -0
- package/dist/battle/Move.js +10 -0
- package/dist/battle/Move.js.map +1 -0
- package/dist/battle/Party.d.ts +21 -0
- package/dist/battle/Party.d.ts.map +1 -0
- package/dist/battle/Party.js +49 -0
- package/dist/battle/Party.js.map +1 -0
- package/dist/battle/Species.d.ts +40 -0
- package/dist/battle/Species.d.ts.map +1 -0
- package/dist/battle/Species.js +31 -0
- package/dist/battle/Species.js.map +1 -0
- package/dist/battle/StatStages.d.ts +38 -0
- package/dist/battle/StatStages.d.ts.map +1 -0
- package/dist/battle/StatStages.js +50 -0
- package/dist/battle/StatStages.js.map +1 -0
- package/dist/battle/TypeMatrix.d.ts +14 -0
- package/dist/battle/TypeMatrix.d.ts.map +1 -0
- package/dist/battle/TypeMatrix.js +24 -0
- package/dist/battle/TypeMatrix.js.map +1 -0
- package/dist/battle/index.d.ts +16 -0
- package/dist/battle/index.d.ts.map +1 -0
- package/dist/battle/index.js +10 -0
- package/dist/battle/index.js.map +1 -0
- package/dist/board/Classics.d.ts +123 -0
- package/dist/board/Classics.d.ts.map +1 -0
- package/dist/board/Classics.js +260 -0
- package/dist/board/Classics.js.map +1 -0
- package/dist/board/Engine.d.ts +23 -0
- package/dist/board/Engine.d.ts.map +1 -0
- package/dist/board/Engine.js +87 -0
- package/dist/board/Engine.js.map +1 -0
- package/dist/board/Tactics.d.ts +46 -0
- package/dist/board/Tactics.d.ts.map +1 -0
- package/dist/board/Tactics.js +108 -0
- package/dist/board/Tactics.js.map +1 -0
- package/dist/board/chess.d.ts +67 -0
- package/dist/board/chess.d.ts.map +1 -0
- package/dist/board/chess.js +439 -0
- package/dist/board/chess.js.map +1 -0
- package/dist/board/index.d.ts +9 -0
- package/dist/board/index.d.ts.map +1 -0
- package/dist/board/index.js +5 -0
- package/dist/board/index.js.map +1 -0
- package/dist/core/Achievements.d.ts +53 -0
- package/dist/core/Achievements.d.ts.map +1 -0
- package/dist/core/Achievements.js +80 -0
- package/dist/core/Achievements.js.map +1 -0
- package/dist/core/Collection.d.ts +46 -0
- package/dist/core/Collection.d.ts.map +1 -0
- package/dist/core/Collection.js +61 -0
- package/dist/core/Collection.js.map +1 -0
- package/dist/core/Game.d.ts +115 -0
- package/dist/core/Game.d.ts.map +1 -0
- package/dist/core/Game.js +236 -0
- package/dist/core/Game.js.map +1 -0
- package/dist/core/Hex.d.ts +45 -0
- package/dist/core/Hex.d.ts.map +1 -0
- package/dist/core/Hex.js +120 -0
- package/dist/core/Hex.js.map +1 -0
- package/dist/core/Input.d.ts +41 -0
- package/dist/core/Input.d.ts.map +1 -0
- package/dist/core/Input.js +132 -0
- package/dist/core/Input.js.map +1 -0
- package/dist/core/Log.d.ts +39 -0
- package/dist/core/Log.d.ts.map +1 -0
- package/dist/core/Log.js +50 -0
- package/dist/core/Log.js.map +1 -0
- package/dist/core/Random.d.ts +64 -0
- package/dist/core/Random.d.ts.map +1 -0
- package/dist/core/Random.js +178 -0
- package/dist/core/Random.js.map +1 -0
- package/dist/core/Replay.d.ts +71 -0
- package/dist/core/Replay.d.ts.map +1 -0
- package/dist/core/Replay.js +102 -0
- package/dist/core/Replay.js.map +1 -0
- package/dist/core/Save.d.ts +52 -0
- package/dist/core/Save.d.ts.map +1 -0
- package/dist/core/Save.js +81 -0
- package/dist/core/Save.js.map +1 -0
- package/dist/core/Scene.d.ts +40 -0
- package/dist/core/Scene.d.ts.map +1 -0
- package/dist/core/Scene.js +56 -0
- package/dist/core/Scene.js.map +1 -0
- package/dist/core/SceneStack.d.ts +37 -0
- package/dist/core/SceneStack.d.ts.map +1 -0
- package/dist/core/SceneStack.js +67 -0
- package/dist/core/SceneStack.js.map +1 -0
- package/dist/core/Signal.d.ts +24 -0
- package/dist/core/Signal.d.ts.map +1 -0
- package/dist/core/Signal.js +41 -0
- package/dist/core/Signal.js.map +1 -0
- package/dist/core/index.d.ts +23 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +14 -0
- package/dist/core/index.js.map +1 -0
- package/dist/i18n/index.d.ts +51 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +74 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/mw_games.global.js +993 -0
- package/dist/render/ActorAnimator.d.ts +60 -0
- package/dist/render/ActorAnimator.d.ts.map +1 -0
- package/dist/render/ActorAnimator.js +76 -0
- package/dist/render/ActorAnimator.js.map +1 -0
- package/dist/render/AnimatedSprite.d.ts +57 -0
- package/dist/render/AnimatedSprite.d.ts.map +1 -0
- package/dist/render/AnimatedSprite.js +105 -0
- package/dist/render/AnimatedSprite.js.map +1 -0
- package/dist/render/Autotile.d.ts +42 -0
- package/dist/render/Autotile.d.ts.map +1 -0
- package/dist/render/Autotile.js +117 -0
- package/dist/render/Autotile.js.map +1 -0
- package/dist/render/Camera.d.ts +88 -0
- package/dist/render/Camera.d.ts.map +1 -0
- package/dist/render/Camera.js +145 -0
- package/dist/render/Camera.js.map +1 -0
- package/dist/render/ColorTransformBatcher.d.ts +57 -0
- package/dist/render/ColorTransformBatcher.d.ts.map +1 -0
- package/dist/render/ColorTransformBatcher.js +212 -0
- package/dist/render/ColorTransformBatcher.js.map +1 -0
- package/dist/render/LayeredSprite.d.ts +27 -0
- package/dist/render/LayeredSprite.d.ts.map +1 -0
- package/dist/render/LayeredSprite.js +53 -0
- package/dist/render/LayeredSprite.js.map +1 -0
- package/dist/render/Projectile.d.ts +37 -0
- package/dist/render/Projectile.d.ts.map +1 -0
- package/dist/render/Projectile.js +50 -0
- package/dist/render/Projectile.js.map +1 -0
- package/dist/render/SpriteSheet.d.ts +38 -0
- package/dist/render/SpriteSheet.d.ts.map +1 -0
- package/dist/render/SpriteSheet.js +79 -0
- package/dist/render/SpriteSheet.js.map +1 -0
- package/dist/render/TileMap.d.ts +188 -0
- package/dist/render/TileMap.d.ts.map +1 -0
- package/dist/render/TileMap.js +488 -0
- package/dist/render/TileMap.js.map +1 -0
- package/dist/render/TintedSprite.d.ts +47 -0
- package/dist/render/TintedSprite.d.ts.map +1 -0
- package/dist/render/TintedSprite.js +173 -0
- package/dist/render/TintedSprite.js.map +1 -0
- package/dist/render/index.d.ts +18 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +11 -0
- package/dist/render/index.js.map +1 -0
- package/dist/roguelike/Blob.d.ts +46 -0
- package/dist/roguelike/Blob.d.ts.map +1 -0
- package/dist/roguelike/Blob.js +98 -0
- package/dist/roguelike/Blob.js.map +1 -0
- package/dist/roguelike/Boss.d.ts +67 -0
- package/dist/roguelike/Boss.d.ts.map +1 -0
- package/dist/roguelike/Boss.js +114 -0
- package/dist/roguelike/Boss.js.map +1 -0
- package/dist/roguelike/Combat.d.ts +23 -0
- package/dist/roguelike/Combat.d.ts.map +1 -0
- package/dist/roguelike/Combat.js +27 -0
- package/dist/roguelike/Combat.js.map +1 -0
- package/dist/roguelike/Doors.d.ts +60 -0
- package/dist/roguelike/Doors.d.ts.map +1 -0
- package/dist/roguelike/Doors.js +102 -0
- package/dist/roguelike/Doors.js.map +1 -0
- package/dist/roguelike/Elevation.d.ts +26 -0
- package/dist/roguelike/Elevation.d.ts.map +1 -0
- package/dist/roguelike/Elevation.js +37 -0
- package/dist/roguelike/Elevation.js.map +1 -0
- package/dist/roguelike/FieldOfView.d.ts +72 -0
- package/dist/roguelike/FieldOfView.d.ts.map +1 -0
- package/dist/roguelike/FieldOfView.js +134 -0
- package/dist/roguelike/FieldOfView.js.map +1 -0
- package/dist/roguelike/Level.d.ts +96 -0
- package/dist/roguelike/Level.d.ts.map +1 -0
- package/dist/roguelike/Level.js +137 -0
- package/dist/roguelike/Level.js.map +1 -0
- package/dist/roguelike/MonsterAI.d.ts +40 -0
- package/dist/roguelike/MonsterAI.d.ts.map +1 -0
- package/dist/roguelike/MonsterAI.js +69 -0
- package/dist/roguelike/MonsterAI.js.map +1 -0
- package/dist/roguelike/Pathfinder.d.ts +82 -0
- package/dist/roguelike/Pathfinder.d.ts.map +1 -0
- package/dist/roguelike/Pathfinder.js +192 -0
- package/dist/roguelike/Pathfinder.js.map +1 -0
- package/dist/roguelike/Scheduler.d.ts +45 -0
- package/dist/roguelike/Scheduler.d.ts.map +1 -0
- package/dist/roguelike/Scheduler.js +82 -0
- package/dist/roguelike/Scheduler.js.map +1 -0
- package/dist/roguelike/Secrets.d.ts +44 -0
- package/dist/roguelike/Secrets.d.ts.map +1 -0
- package/dist/roguelike/Secrets.js +64 -0
- package/dist/roguelike/Secrets.js.map +1 -0
- package/dist/roguelike/Targeting.d.ts +66 -0
- package/dist/roguelike/Targeting.d.ts.map +1 -0
- package/dist/roguelike/Targeting.js +150 -0
- package/dist/roguelike/Targeting.js.map +1 -0
- package/dist/roguelike/generate.d.ts +44 -0
- package/dist/roguelike/generate.d.ts.map +1 -0
- package/dist/roguelike/generate.js +88 -0
- package/dist/roguelike/generate.js.map +1 -0
- package/dist/roguelike/index.d.ts +23 -0
- package/dist/roguelike/index.d.ts.map +1 -0
- package/dist/roguelike/index.js +15 -0
- package/dist/roguelike/index.js.map +1 -0
- package/dist/rpg/Event.d.ts +33 -0
- package/dist/rpg/Event.d.ts.map +1 -0
- package/dist/rpg/Event.js +19 -0
- package/dist/rpg/Event.js.map +1 -0
- package/dist/rpg/EventRunner.d.ts +72 -0
- package/dist/rpg/EventRunner.d.ts.map +1 -0
- package/dist/rpg/EventRunner.js +76 -0
- package/dist/rpg/EventRunner.js.map +1 -0
- package/dist/rpg/GameState.d.ts +22 -0
- package/dist/rpg/GameState.d.ts.map +1 -0
- package/dist/rpg/GameState.js +35 -0
- package/dist/rpg/GameState.js.map +1 -0
- package/dist/rpg/GridMover.d.ts +51 -0
- package/dist/rpg/GridMover.d.ts.map +1 -0
- package/dist/rpg/GridMover.js +91 -0
- package/dist/rpg/GridMover.js.map +1 -0
- package/dist/rpg/Quest.d.ts +67 -0
- package/dist/rpg/Quest.d.ts.map +1 -0
- package/dist/rpg/Quest.js +92 -0
- package/dist/rpg/Quest.js.map +1 -0
- package/dist/rpg/TiledMap.d.ts +107 -0
- package/dist/rpg/TiledMap.d.ts.map +1 -0
- package/dist/rpg/TiledMap.js +123 -0
- package/dist/rpg/TiledMap.js.map +1 -0
- package/dist/rpg/automap.d.ts +40 -0
- package/dist/rpg/automap.d.ts.map +1 -0
- package/dist/rpg/automap.js +81 -0
- package/dist/rpg/automap.js.map +1 -0
- package/dist/rpg/index.d.ts +14 -0
- package/dist/rpg/index.d.ts.map +1 -0
- package/dist/rpg/index.js +8 -0
- package/dist/rpg/index.js.map +1 -0
- package/dist/stage/DialogueStage.d.ts +75 -0
- package/dist/stage/DialogueStage.d.ts.map +1 -0
- package/dist/stage/DialogueStage.js +207 -0
- package/dist/stage/DialogueStage.js.map +1 -0
- package/dist/stage/index.d.ts +7 -0
- package/dist/stage/index.d.ts.map +1 -0
- package/dist/stage/index.js +4 -0
- package/dist/stage/index.js.map +1 -0
- package/dist/stage/script.d.ts +111 -0
- package/dist/stage/script.d.ts.map +1 -0
- package/dist/stage/script.js +133 -0
- package/dist/stage/script.js.map +1 -0
- package/dist/stage/twee.d.ts +42 -0
- package/dist/stage/twee.d.ts.map +1 -0
- package/dist/stage/twee.js +169 -0
- package/dist/stage/twee.js.map +1 -0
- package/dist/ui/IconGrid.d.ts +110 -0
- package/dist/ui/IconGrid.d.ts.map +1 -0
- package/dist/ui/IconGrid.js +284 -0
- package/dist/ui/IconGrid.js.map +1 -0
- package/dist/ui/Label.d.ts +26 -0
- package/dist/ui/Label.d.ts.map +1 -0
- package/dist/ui/Label.js +41 -0
- package/dist/ui/Label.js.map +1 -0
- package/dist/ui/ListView.d.ts +67 -0
- package/dist/ui/ListView.d.ts.map +1 -0
- package/dist/ui/ListView.js +167 -0
- package/dist/ui/ListView.js.map +1 -0
- package/dist/ui/MessageBox.d.ts +66 -0
- package/dist/ui/MessageBox.d.ts.map +1 -0
- package/dist/ui/MessageBox.js +161 -0
- package/dist/ui/MessageBox.js.map +1 -0
- package/dist/ui/NinePatch.d.ts +34 -0
- package/dist/ui/NinePatch.d.ts.map +1 -0
- package/dist/ui/NinePatch.js +45 -0
- package/dist/ui/NinePatch.js.map +1 -0
- package/dist/ui/VerticalLabel.d.ts +46 -0
- package/dist/ui/VerticalLabel.d.ts.map +1 -0
- package/dist/ui/VerticalLabel.js +81 -0
- package/dist/ui/VerticalLabel.js.map +1 -0
- package/dist/ui/Window.d.ts +71 -0
- package/dist/ui/Window.d.ts.map +1 -0
- package/dist/ui/Window.js +126 -0
- package/dist/ui/Window.js.map +1 -0
- package/dist/ui/WindowStack.d.ts +40 -0
- package/dist/ui/WindowStack.d.ts.map +1 -0
- package/dist/ui/WindowStack.js +106 -0
- package/dist/ui/WindowStack.js.map +1 -0
- package/dist/ui/index.d.ts +18 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +10 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/theme.d.ts +50 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +36 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/world/Encounters.d.ts +20 -0
- package/dist/world/Encounters.d.ts.map +1 -0
- package/dist/world/Encounters.js +9 -0
- package/dist/world/Encounters.js.map +1 -0
- package/dist/world/Overworld.d.ts +25 -0
- package/dist/world/Overworld.d.ts.map +1 -0
- package/dist/world/Overworld.js +26 -0
- package/dist/world/Overworld.js.map +1 -0
- package/dist/world/TurnClock.d.ts +25 -0
- package/dist/world/TurnClock.d.ts.map +1 -0
- package/dist/world/TurnClock.js +33 -0
- package/dist/world/TurnClock.js.map +1 -0
- package/dist/world/World.d.ts +50 -0
- package/dist/world/World.d.ts.map +1 -0
- package/dist/world/World.js +77 -0
- package/dist/world/World.js.map +1 -0
- package/dist/world/index.d.ts +8 -0
- package/dist/world/index.d.ts.map +1 -0
- package/dist/world/index.js +5 -0
- package/dist/world/index.js.map +1 -0
- package/package.json +76 -0
- package/tools/compile-resources.mjs +129 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { Container, Sprite, Texture } from 'pixi.js';
|
|
2
|
+
import { TintedSprite } from '../render/TintedSprite.js';
|
|
3
|
+
/** where a slot sits, as a fraction of the stage width */
|
|
4
|
+
const SLOTS = {
|
|
5
|
+
farLeft: 0.12,
|
|
6
|
+
left: 0.28,
|
|
7
|
+
center: 0.5,
|
|
8
|
+
right: 0.72,
|
|
9
|
+
farRight: 0.88,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* A dialogue scene: a backdrop, characters standing in front of it, and whoever is
|
|
13
|
+
* speaking picked out from the rest.
|
|
14
|
+
*
|
|
15
|
+
* This is the presentation the tile map is not — a still image with figures on it, the
|
|
16
|
+
* mode nearly every RPG drops into for a conversation that matters, and the whole of how a
|
|
17
|
+
* visual novel looks.
|
|
18
|
+
*
|
|
19
|
+
* It draws only the scene. The words go in a `MessageBox` from `mwg/ui`, so a game gets
|
|
20
|
+
* the same dialogue box whether it is talking to a shopkeeper on a tile map or running a
|
|
21
|
+
* scripted scene here.
|
|
22
|
+
*/
|
|
23
|
+
export class DialogueStage extends Container {
|
|
24
|
+
constructor(width, height) {
|
|
25
|
+
super();
|
|
26
|
+
this.backdropLayer = new Container();
|
|
27
|
+
this.actorLayer = new Container();
|
|
28
|
+
this.backdrop = null;
|
|
29
|
+
this.outgoingBackdrop = null;
|
|
30
|
+
this.actors = new Map();
|
|
31
|
+
this.definitions = new Map();
|
|
32
|
+
this.focused = null;
|
|
33
|
+
this.tweens = [];
|
|
34
|
+
/** how far a character is darkened while someone else is speaking, 0 to 1 */
|
|
35
|
+
this.dimAmount = 0.45;
|
|
36
|
+
this.stageWidth = width;
|
|
37
|
+
this.stageHeight = height;
|
|
38
|
+
this.addChild(this.backdropLayer);
|
|
39
|
+
this.addChild(this.actorLayer);
|
|
40
|
+
}
|
|
41
|
+
/** registers a character so a script can refer to it by name alone */
|
|
42
|
+
defineCharacter(id, definition) {
|
|
43
|
+
this.definitions.set(id, definition);
|
|
44
|
+
}
|
|
45
|
+
resize(width, height) {
|
|
46
|
+
this.stageWidth = width;
|
|
47
|
+
this.stageHeight = height;
|
|
48
|
+
for (const sprite of [this.backdrop, this.outgoingBackdrop]) {
|
|
49
|
+
if (sprite)
|
|
50
|
+
this.fitBackdrop(sprite);
|
|
51
|
+
}
|
|
52
|
+
for (const actor of this.actors.values())
|
|
53
|
+
this.placeActor(actor);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Changes the backdrop.
|
|
57
|
+
*
|
|
58
|
+
* The old one stays underneath while the new one fades in over it, so the scene never
|
|
59
|
+
* flashes through to an empty stage mid-transition.
|
|
60
|
+
*/
|
|
61
|
+
setBackdrop(texture, fade = 0.4) {
|
|
62
|
+
this.outgoingBackdrop?.destroy();
|
|
63
|
+
this.outgoingBackdrop = this.backdrop;
|
|
64
|
+
const sprite = new Sprite(texture);
|
|
65
|
+
this.fitBackdrop(sprite);
|
|
66
|
+
this.backdrop = sprite;
|
|
67
|
+
this.backdropLayer.addChild(sprite);
|
|
68
|
+
if (fade <= 0) {
|
|
69
|
+
this.outgoingBackdrop?.destroy();
|
|
70
|
+
this.outgoingBackdrop = null;
|
|
71
|
+
return Promise.resolve();
|
|
72
|
+
}
|
|
73
|
+
sprite.alpha = 0;
|
|
74
|
+
return this.tween(fade, (t) => {
|
|
75
|
+
sprite.alpha = t;
|
|
76
|
+
}).then(() => {
|
|
77
|
+
this.outgoingBackdrop?.destroy();
|
|
78
|
+
this.outgoingBackdrop = null;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
fitBackdrop(sprite) {
|
|
82
|
+
//cover the stage without distorting: scale by the larger ratio and centre the rest
|
|
83
|
+
const source = sprite.texture;
|
|
84
|
+
const scale = Math.max(this.stageWidth / source.width, this.stageHeight / source.height);
|
|
85
|
+
sprite.scale.set(scale);
|
|
86
|
+
sprite.x = Math.round((this.stageWidth - source.width * scale) / 2);
|
|
87
|
+
sprite.y = Math.round((this.stageHeight - source.height * scale) / 2);
|
|
88
|
+
}
|
|
89
|
+
show(id, options = {}) {
|
|
90
|
+
const definition = this.definitions.get(id);
|
|
91
|
+
if (!definition)
|
|
92
|
+
throw new Error(`no character defined as "${id}"`);
|
|
93
|
+
const expression = options.expression ?? Object.keys(definition.expressions)[0];
|
|
94
|
+
const existing = this.actors.get(id);
|
|
95
|
+
if (existing) {
|
|
96
|
+
//already on stage: this is a move or an expression change, not an entrance
|
|
97
|
+
if (options.at !== undefined)
|
|
98
|
+
existing.slot = this.slotOf(options.at);
|
|
99
|
+
this.setExpression(id, expression);
|
|
100
|
+
this.placeActor(existing);
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
103
|
+
const sprite = new TintedSprite(definition.sheet.get(definition.expressions[expression]));
|
|
104
|
+
const actor = {
|
|
105
|
+
id,
|
|
106
|
+
sprite,
|
|
107
|
+
definition,
|
|
108
|
+
slot: this.slotOf(options.at ?? 'center'),
|
|
109
|
+
expression,
|
|
110
|
+
};
|
|
111
|
+
this.actors.set(id, actor);
|
|
112
|
+
this.actorLayer.addChild(sprite);
|
|
113
|
+
this.placeActor(actor);
|
|
114
|
+
this.applyFocus();
|
|
115
|
+
const fade = options.fade ?? 0.25;
|
|
116
|
+
if (fade <= 0)
|
|
117
|
+
return Promise.resolve();
|
|
118
|
+
sprite.alpha = 0;
|
|
119
|
+
return this.tween(fade, (t) => {
|
|
120
|
+
sprite.alpha = t;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
hide(id, fade = 0.25) {
|
|
124
|
+
const actor = this.actors.get(id);
|
|
125
|
+
if (!actor)
|
|
126
|
+
return Promise.resolve();
|
|
127
|
+
this.actors.delete(id);
|
|
128
|
+
if (this.focused === id)
|
|
129
|
+
this.focused = null;
|
|
130
|
+
this.applyFocus();
|
|
131
|
+
if (fade <= 0) {
|
|
132
|
+
actor.sprite.destroy();
|
|
133
|
+
return Promise.resolve();
|
|
134
|
+
}
|
|
135
|
+
return this.tween(fade, (t) => {
|
|
136
|
+
actor.sprite.alpha = 1 - t;
|
|
137
|
+
}).then(() => actor.sprite.destroy());
|
|
138
|
+
}
|
|
139
|
+
hideAll(fade = 0.25) {
|
|
140
|
+
return Promise.all([...this.actors.keys()].map((id) => this.hide(id, fade))).then(() => undefined);
|
|
141
|
+
}
|
|
142
|
+
setExpression(id, expression) {
|
|
143
|
+
const actor = this.actors.get(id);
|
|
144
|
+
if (!actor)
|
|
145
|
+
return;
|
|
146
|
+
const frame = actor.definition.expressions[expression];
|
|
147
|
+
if (frame === undefined) {
|
|
148
|
+
throw new Error(`character "${id}" has no expression "${expression}"`);
|
|
149
|
+
}
|
|
150
|
+
actor.expression = expression;
|
|
151
|
+
actor.sprite.texture = actor.definition.sheet.get(frame);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Picks out whoever is speaking by dimming everyone else.
|
|
155
|
+
*
|
|
156
|
+
* A multiply tint is exactly right here: it darkens without changing hue, so a dimmed
|
|
157
|
+
* character reads as standing back rather than as being a different colour.
|
|
158
|
+
*/
|
|
159
|
+
focus(id) {
|
|
160
|
+
this.focused = id;
|
|
161
|
+
this.applyFocus();
|
|
162
|
+
}
|
|
163
|
+
applyFocus() {
|
|
164
|
+
const lit = Math.round(0xff * (1 - this.dimAmount));
|
|
165
|
+
const dim = (lit << 16) | (lit << 8) | lit;
|
|
166
|
+
for (const actor of this.actors.values()) {
|
|
167
|
+
const isDimmed = this.focused !== null && actor.id !== this.focused;
|
|
168
|
+
actor.sprite.tint = isDimmed ? dim : 0xffffff;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
slotOf(at) {
|
|
172
|
+
return typeof at === 'number' ? at : SLOTS[at];
|
|
173
|
+
}
|
|
174
|
+
placeActor(actor) {
|
|
175
|
+
const definition = actor.definition;
|
|
176
|
+
const wanted = (definition.height ?? 0.7) * this.stageHeight;
|
|
177
|
+
const scale = wanted / definition.sheet.frameHeight;
|
|
178
|
+
actor.sprite.scale.set(scale);
|
|
179
|
+
actor.sprite.x = Math.round(actor.slot * this.stageWidth - (definition.sheet.frameWidth * scale) / 2);
|
|
180
|
+
//positioned by the feet, so characters of different heights stand on the same floor
|
|
181
|
+
actor.sprite.y = Math.round((definition.baseline ?? 0.92) * this.stageHeight - wanted);
|
|
182
|
+
}
|
|
183
|
+
tween(duration, apply) {
|
|
184
|
+
return new Promise((resolve) => {
|
|
185
|
+
this.tweens.push({ elapsed: 0, duration, apply, resolve });
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
update(dt) {
|
|
189
|
+
if (this.tweens.length === 0)
|
|
190
|
+
return;
|
|
191
|
+
//iterate a copy: a tween's resolve may start another
|
|
192
|
+
for (const tween of [...this.tweens]) {
|
|
193
|
+
tween.elapsed += dt;
|
|
194
|
+
const t = Math.min(1, tween.elapsed / tween.duration);
|
|
195
|
+
tween.apply(t);
|
|
196
|
+
if (t >= 1) {
|
|
197
|
+
this.tweens.splice(this.tweens.indexOf(tween), 1);
|
|
198
|
+
tween.resolve();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** true while a fade is running, so a script can wait for it */
|
|
203
|
+
get isBusy() {
|
|
204
|
+
return this.tweens.length > 0;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=DialogueStage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DialogueStage.js","sourceRoot":"","sources":["../../src/stage/DialogueStage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DialogueStage } from './DialogueStage.ts';
|
|
2
|
+
export type { CharacterDefinition, ShowOptions, SlotName } from './DialogueStage.ts';
|
|
3
|
+
export { StageScript } from './script.ts';
|
|
4
|
+
export type { StageCommand, StageChoice, StoryScript, ScriptOptions, ScriptState } from './script.ts';
|
|
5
|
+
export { importTwee } from './twee.ts';
|
|
6
|
+
export type { TwineStory } from './twee.ts';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAErF,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtG,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { Texture } from 'pixi.js';
|
|
2
|
+
import { type Choice } from '../ui/MessageBox.ts';
|
|
3
|
+
import type { WindowStack } from '../ui/WindowStack.ts';
|
|
4
|
+
import type { DialogueStage, SlotName } from './DialogueStage.ts';
|
|
5
|
+
/**
|
|
6
|
+
* A scene, written as data.
|
|
7
|
+
*
|
|
8
|
+
* A scripted conversation is a list of instructions, not a function. That is deliberate:
|
|
9
|
+
* the same list can be written by hand, generated, translated, or one day produced by an
|
|
10
|
+
* editor, and none of those need the runtime to change. It is also what lets the RPG event
|
|
11
|
+
* interpreter and this share a format later — a cutscene on a tile map is the same list
|
|
12
|
+
* with a different backdrop.
|
|
13
|
+
*/
|
|
14
|
+
export type StageCommand = {
|
|
15
|
+
backdrop: string;
|
|
16
|
+
fade?: number;
|
|
17
|
+
} | {
|
|
18
|
+
show: string;
|
|
19
|
+
at?: SlotName | number;
|
|
20
|
+
expression?: string;
|
|
21
|
+
fade?: number;
|
|
22
|
+
} | {
|
|
23
|
+
hide: string;
|
|
24
|
+
fade?: number;
|
|
25
|
+
} | {
|
|
26
|
+
hideAll: true;
|
|
27
|
+
fade?: number;
|
|
28
|
+
} | {
|
|
29
|
+
expression: string;
|
|
30
|
+
of: string;
|
|
31
|
+
} | {
|
|
32
|
+
say: string;
|
|
33
|
+
as?: string;
|
|
34
|
+
speaker?: string;
|
|
35
|
+
} | {
|
|
36
|
+
ask: string;
|
|
37
|
+
as?: string;
|
|
38
|
+
speaker?: string;
|
|
39
|
+
choices: StageChoice[];
|
|
40
|
+
store?: string;
|
|
41
|
+
} | {
|
|
42
|
+
goto: string;
|
|
43
|
+
} | {
|
|
44
|
+
wait: number;
|
|
45
|
+
} | {
|
|
46
|
+
call: (state: ScriptState) => void | Promise<void>;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* A choice that can also move the story: when the player picks it inside
|
|
50
|
+
* `runStory`, the story jumps to the named passage afterwards. Plain `Choice`
|
|
51
|
+
* objects stay valid - every one of them is already a `StageChoice` that goes
|
|
52
|
+
* nowhere - and a `MessageBox` never sees the extra field.
|
|
53
|
+
*/
|
|
54
|
+
export type StageChoice = Choice & {
|
|
55
|
+
/** the passage to jump to when this choice is picked, in a `runStory` story */
|
|
56
|
+
goto?: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A story as a graph of named passages, each a list of commands - Twine's shape
|
|
60
|
+
* rather than a straight line. Passages can loop back or braid together; reaching
|
|
61
|
+
* the end of a passage ends the story.
|
|
62
|
+
*/
|
|
63
|
+
export type StoryScript = Record<string, readonly StageCommand[]>;
|
|
64
|
+
export interface ScriptState {
|
|
65
|
+
/** whatever `ask` commands have stored, keyed by their `store` name */
|
|
66
|
+
answers: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
export interface ScriptOptions {
|
|
69
|
+
stage: DialogueStage;
|
|
70
|
+
windows: WindowStack;
|
|
71
|
+
/** resolves a backdrop name from a command to a texture */
|
|
72
|
+
backdrop: (name: string) => Texture;
|
|
73
|
+
/** the name shown for a character id, when a `say` gives no explicit speaker */
|
|
74
|
+
displayName?: (id: string) => string;
|
|
75
|
+
/** width of the dialogue box; defaults to most of the stage */
|
|
76
|
+
boxWidth?: number;
|
|
77
|
+
boxHeight?: number;
|
|
78
|
+
/** characters revealed per second */
|
|
79
|
+
speed?: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Runs a scene.
|
|
83
|
+
*
|
|
84
|
+
* `run` resolves when the list is exhausted, so a caller can simply await a conversation
|
|
85
|
+
* and carry on afterwards — which is what makes a cutscene readable at the call site
|
|
86
|
+
* instead of a chain of callbacks.
|
|
87
|
+
*/
|
|
88
|
+
export declare class StageScript {
|
|
89
|
+
private options;
|
|
90
|
+
readonly state: ScriptState;
|
|
91
|
+
private cancelled;
|
|
92
|
+
constructor(options: ScriptOptions);
|
|
93
|
+
cancel(): void;
|
|
94
|
+
run(commands: readonly StageCommand[]): Promise<ScriptState>;
|
|
95
|
+
/**
|
|
96
|
+
* Runs a graph of passages starting at `start`, following `goto` commands and
|
|
97
|
+
* choice jumps until a passage runs out or the script is cancelled.
|
|
98
|
+
*/
|
|
99
|
+
runStory(story: StoryScript, start: string): Promise<ScriptState>;
|
|
100
|
+
/** runs one command; returns the passage to jump to, if the command jumps anywhere */
|
|
101
|
+
private step;
|
|
102
|
+
/**
|
|
103
|
+
* Puts one line in front of the player and resolves with their answer.
|
|
104
|
+
*
|
|
105
|
+
* Protected rather than private on purpose: this is the seam for a game that presents
|
|
106
|
+
* dialogue its own way — a different box, a voice line, a test harness — without
|
|
107
|
+
* reimplementing the sequencing above.
|
|
108
|
+
*/
|
|
109
|
+
protected speak(text: string, as: string | undefined, speaker?: string, choices?: Choice[]): Promise<unknown>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../src/stage/script.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { MessageBox } from '../ui/MessageBox.js';
|
|
2
|
+
/**
|
|
3
|
+
* Runs a scene.
|
|
4
|
+
*
|
|
5
|
+
* `run` resolves when the list is exhausted, so a caller can simply await a conversation
|
|
6
|
+
* and carry on afterwards — which is what makes a cutscene readable at the call site
|
|
7
|
+
* instead of a chain of callbacks.
|
|
8
|
+
*/
|
|
9
|
+
export class StageScript {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.state = { answers: {} };
|
|
12
|
+
this.cancelled = false;
|
|
13
|
+
this.options = options;
|
|
14
|
+
}
|
|
15
|
+
cancel() {
|
|
16
|
+
this.cancelled = true;
|
|
17
|
+
}
|
|
18
|
+
async run(commands) {
|
|
19
|
+
for (const command of commands) {
|
|
20
|
+
if (this.cancelled)
|
|
21
|
+
break;
|
|
22
|
+
const jump = await this.step(command);
|
|
23
|
+
if (jump !== undefined) {
|
|
24
|
+
throw new Error(`a "goto ${jump}" only runs inside runStory, not a straight run`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return this.state;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Runs a graph of passages starting at `start`, following `goto` commands and
|
|
31
|
+
* choice jumps until a passage runs out or the script is cancelled.
|
|
32
|
+
*/
|
|
33
|
+
async runStory(story, start) {
|
|
34
|
+
if (!Object.prototype.hasOwnProperty.call(story, start)) {
|
|
35
|
+
throw new Error(`this story has no passage named "${start}"`);
|
|
36
|
+
}
|
|
37
|
+
let commands = story[start];
|
|
38
|
+
let index = 0;
|
|
39
|
+
while (index < commands.length) {
|
|
40
|
+
if (this.cancelled)
|
|
41
|
+
break;
|
|
42
|
+
const jump = await this.step(commands[index]);
|
|
43
|
+
index++;
|
|
44
|
+
if (jump !== undefined) {
|
|
45
|
+
if (!Object.prototype.hasOwnProperty.call(story, jump)) {
|
|
46
|
+
throw new Error(`this story has no passage named "${jump}"`);
|
|
47
|
+
}
|
|
48
|
+
commands = story[jump];
|
|
49
|
+
index = 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return this.state;
|
|
53
|
+
}
|
|
54
|
+
/** runs one command; returns the passage to jump to, if the command jumps anywhere */
|
|
55
|
+
async step(command) {
|
|
56
|
+
const { stage } = this.options;
|
|
57
|
+
if ('backdrop' in command) {
|
|
58
|
+
await stage.setBackdrop(this.options.backdrop(command.backdrop), command.fade);
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
if ('show' in command) {
|
|
62
|
+
await stage.show(command.show, {
|
|
63
|
+
at: command.at,
|
|
64
|
+
expression: command.expression,
|
|
65
|
+
fade: command.fade,
|
|
66
|
+
});
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
if ('hide' in command) {
|
|
70
|
+
await stage.hide(command.hide, command.fade);
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
if ('hideAll' in command) {
|
|
74
|
+
await stage.hideAll(command.fade);
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
if ('expression' in command) {
|
|
78
|
+
stage.setExpression(command.of, command.expression);
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
if ('say' in command) {
|
|
82
|
+
await this.speak(command.say, command.as, command.speaker);
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
if ('ask' in command) {
|
|
86
|
+
const chosen = await this.speak(command.ask, command.as, command.speaker, command.choices);
|
|
87
|
+
if (command.store)
|
|
88
|
+
this.state.answers[command.store] = chosen;
|
|
89
|
+
//a MessageBox resolves with the chosen value, which defaults to the text
|
|
90
|
+
return command.choices.find((c) => (c.value ?? c.text) === chosen)?.goto;
|
|
91
|
+
}
|
|
92
|
+
if ('goto' in command) {
|
|
93
|
+
return command.goto;
|
|
94
|
+
}
|
|
95
|
+
if ('wait' in command) {
|
|
96
|
+
await new Promise((resolve) => setTimeout(resolve, command.wait * 1000));
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
if ('call' in command) {
|
|
100
|
+
await command.call(this.state);
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Puts one line in front of the player and resolves with their answer.
|
|
106
|
+
*
|
|
107
|
+
* Protected rather than private on purpose: this is the seam for a game that presents
|
|
108
|
+
* dialogue its own way — a different box, a voice line, a test harness — without
|
|
109
|
+
* reimplementing the sequencing above.
|
|
110
|
+
*/
|
|
111
|
+
speak(text, as, speaker, choices) {
|
|
112
|
+
const { stage, windows } = this.options;
|
|
113
|
+
//dim everyone but the speaker; a line with no speaker lights the whole stage again
|
|
114
|
+
stage.focus(as ?? null);
|
|
115
|
+
const name = speaker ?? (as ? (this.options.displayName?.(as) ?? as) : undefined);
|
|
116
|
+
return new Promise((resolve) => {
|
|
117
|
+
windows.push(new MessageBox({
|
|
118
|
+
width: this.options.boxWidth ?? 480,
|
|
119
|
+
height: this.options.boxHeight ?? 120,
|
|
120
|
+
speed: this.options.speed ?? 45,
|
|
121
|
+
pages: [{ text, speaker: name }],
|
|
122
|
+
//choices, when the line has them, are answered in the same box
|
|
123
|
+
choices,
|
|
124
|
+
//the scene behind is what the player is meant to be looking at, so it
|
|
125
|
+
//keeps its light; only the input is taken
|
|
126
|
+
dims: false,
|
|
127
|
+
anchor: 'bottom',
|
|
128
|
+
onDone: (chosen) => resolve(chosen),
|
|
129
|
+
}));
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script.js","sourceRoot":"","sources":["../../src/stage/script.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { StoryScript } from './script.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A story imported from Twine's Twee notation, ready for `StageScript.runStory`.
|
|
4
|
+
*/
|
|
5
|
+
export interface TwineStory {
|
|
6
|
+
story: StoryScript;
|
|
7
|
+
/** `StoryData`'s start passage when the file names one, else the first passage */
|
|
8
|
+
start: string;
|
|
9
|
+
/** the `StoryTitle` passage, when the file has one */
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reads a `.twee` file into a `StoryScript`.
|
|
14
|
+
*
|
|
15
|
+
* Twee was chosen over Twine's `<tw-passagedata>` HTML export on purpose: it is
|
|
16
|
+
* plain text, so this stays a pure string parser with no DOM - testable under
|
|
17
|
+
* `node --test` and loadable through `mwg/assets` like any other text asset.
|
|
18
|
+
*
|
|
19
|
+
* Only structure is imported, and that answers the format question the roadmap
|
|
20
|
+
* left open: each passage's text lines become `say` commands and its
|
|
21
|
+
* `[[links]]` become one closing `ask` whose choices jump (`[[text]]`,
|
|
22
|
+
* `[[text->target]]` and `[[target<-text]]`) - the last text line doubles as
|
|
23
|
+
* the question, since a choice box needs a prompt and repeating it works.
|
|
24
|
+
* No story-format macro language
|
|
25
|
+
* (Harlowe, SugarCube, Chapbook) is interpreted - body text reaches the stage
|
|
26
|
+
* untouched, and a link carrying a setter throws instead of silently dropping
|
|
27
|
+
* the behaviour the setter described.
|
|
28
|
+
*
|
|
29
|
+
* ```twee
|
|
30
|
+
* :: Start
|
|
31
|
+
* You stand at a crossroads.
|
|
32
|
+
*
|
|
33
|
+
* [[Take the left path->Left]]
|
|
34
|
+
* [[Take the right path->Right]]
|
|
35
|
+
*
|
|
36
|
+
* :: Left
|
|
37
|
+
* The path ends at a wall.
|
|
38
|
+
* [[Go back->Start]]
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function importTwee(source: string): TwineStory;
|
|
42
|
+
//# sourceMappingURL=twee.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twee.d.ts","sourceRoot":"","sources":["../../src/stage/twee.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAwCrD"}
|