@strixit/storyscript 0.0.0-stage → 1.0.0
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/.env +1 -0
- package/CodeSnippets/StoryScriptSnippets.code-snippets +573 -0
- package/LICENSE.txt +21 -0
- package/LiveTemplates/StoryScript.xml +271 -0
- package/README.md +9 -2
- package/baseViteConfig.js +112 -0
- package/clientFiles/currentGameName.js +1 -0
- package/clientFiles/gitignore +12 -0
- package/clientFiles/tsconfig.json +34 -0
- package/clientFiles/vite.config.ts +14 -0
- package/clientFiles/vitest.config.ts +29 -0
- package/dist/src/Engine/Actions/index.d.ts +2 -0
- package/dist/src/Engine/Actions/open.d.ts +6 -0
- package/dist/src/Engine/Actions/openWithKey.d.ts +7 -0
- package/dist/src/Engine/EntityCreatorFunctions.d.ts +18 -0
- package/dist/src/Engine/Interfaces/action.d.ts +37 -0
- package/dist/src/Engine/Interfaces/autoplayStep.d.ts +11 -0
- package/dist/src/Engine/Interfaces/barrier.d.ts +16 -0
- package/dist/src/Engine/Interfaces/barrierAction.d.ts +19 -0
- package/dist/src/Engine/Interfaces/character.d.ts +48 -0
- package/dist/src/Engine/Interfaces/combatSetup.d.ts +9 -0
- package/dist/src/Engine/Interfaces/combatTurn.d.ts +37 -0
- package/dist/src/Engine/Interfaces/combatWinnings.d.ts +6 -0
- package/dist/src/Engine/Interfaces/combinations/activeCombination.d.ts +14 -0
- package/dist/src/Engine/Interfaces/combinations/combinable.d.ts +18 -0
- package/dist/src/Engine/Interfaces/combinations/combinationAction.d.ts +41 -0
- package/dist/src/Engine/Interfaces/combinations/combinationMatchResult.d.ts +14 -0
- package/dist/src/Engine/Interfaces/combinations/combinations.d.ts +17 -0
- package/dist/src/Engine/Interfaces/combinations/combine.d.ts +22 -0
- package/dist/src/Engine/Interfaces/combinations/combineResult.d.ts +18 -0
- package/dist/src/Engine/Interfaces/combinations/gameCombinations.d.ts +40 -0
- package/dist/src/Engine/Interfaces/compiledLocation.d.ts +33 -0
- package/dist/src/Engine/Interfaces/conversations/conversation.d.ts +44 -0
- package/dist/src/Engine/Interfaces/conversations/conversationLogEntry.d.ts +13 -0
- package/dist/src/Engine/Interfaces/conversations/conversationNode.d.ts +22 -0
- package/dist/src/Engine/Interfaces/conversations/conversationReply.d.ts +49 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacter.d.ts +20 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacterAttribute.d.ts +18 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacterAttributeEntry.d.ts +18 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacterQuestion.d.ts +18 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacterQuestionEntry.d.ts +22 -0
- package/dist/src/Engine/Interfaces/createCharacter/createCharacterStep.d.ts +40 -0
- package/dist/src/Engine/Interfaces/customCursor.d.ts +8 -0
- package/dist/src/Engine/Interfaces/defaultEquipment.d.ts +19 -0
- package/dist/src/Engine/Interfaces/definitions.d.ts +40 -0
- package/dist/src/Engine/Interfaces/destination.d.ts +31 -0
- package/dist/src/Engine/Interfaces/dynamicStyle.d.ts +10 -0
- package/dist/src/Engine/Interfaces/enemy.d.ts +46 -0
- package/dist/src/Engine/Interfaces/enumerations/actionStatus.d.ts +18 -0
- package/dist/src/Engine/Interfaces/enumerations/actionType.d.ts +9 -0
- package/dist/src/Engine/Interfaces/enumerations/equipmentType.d.ts +51 -0
- package/dist/src/Engine/Interfaces/enumerations/gameState.d.ts +11 -0
- package/dist/src/Engine/Interfaces/enumerations/playState.d.ts +10 -0
- package/dist/src/Engine/Interfaces/enumerations/targetType.d.ts +9 -0
- package/dist/src/Engine/Interfaces/equipment.d.ts +43 -0
- package/dist/src/Engine/Interfaces/feature.d.ts +37 -0
- package/dist/src/Engine/Interfaces/featureCollection.d.ts +7 -0
- package/dist/src/Engine/Interfaces/game.d.ts +148 -0
- package/dist/src/Engine/Interfaces/gameEvents.d.ts +7 -0
- package/dist/src/Engine/Interfaces/groupableItem.d.ts +32 -0
- package/dist/src/Engine/Interfaces/helpers.d.ts +50 -0
- package/dist/src/Engine/Interfaces/index.d.ts +78 -0
- package/dist/src/Engine/Interfaces/interfaceTexts.d.ts +140 -0
- package/dist/src/Engine/Interfaces/item.d.ts +96 -0
- package/dist/src/Engine/Interfaces/key.d.ts +16 -0
- package/dist/src/Engine/Interfaces/location.d.ts +78 -0
- package/dist/src/Engine/Interfaces/maps/map.d.ts +45 -0
- package/dist/src/Engine/Interfaces/maps/mapLocation.d.ts +23 -0
- package/dist/src/Engine/Interfaces/party.d.ts +33 -0
- package/dist/src/Engine/Interfaces/person.d.ts +25 -0
- package/dist/src/Engine/Interfaces/quest.d.ts +51 -0
- package/dist/src/Engine/Interfaces/rules/characterRules.d.ts +84 -0
- package/dist/src/Engine/Interfaces/rules/combatRules.d.ts +46 -0
- package/dist/src/Engine/Interfaces/rules/combinationRules.d.ts +15 -0
- package/dist/src/Engine/Interfaces/rules/demoMode.d.ts +15 -0
- package/dist/src/Engine/Interfaces/rules/encounterRules.d.ts +4 -0
- package/dist/src/Engine/Interfaces/rules/explorationRules.d.ts +42 -0
- package/dist/src/Engine/Interfaces/rules/generalRules.d.ts +62 -0
- package/dist/src/Engine/Interfaces/rules/rules.d.ts +31 -0
- package/dist/src/Engine/Interfaces/rules/setupRules.d.ts +56 -0
- package/dist/src/Engine/Interfaces/rules/titleScreen.d.ts +16 -0
- package/dist/src/Engine/Interfaces/saveGame.d.ts +33 -0
- package/dist/src/Engine/Interfaces/scoreEntry.d.ts +13 -0
- package/dist/src/Engine/Interfaces/services/autoplayService.d.ts +19 -0
- package/dist/src/Engine/Interfaces/services/characterService.d.ts +17 -0
- package/dist/src/Engine/Interfaces/services/combatService.d.ts +26 -0
- package/dist/src/Engine/Interfaces/services/combinationService.d.ts +9 -0
- package/dist/src/Engine/Interfaces/services/commandService.d.ts +64 -0
- package/dist/src/Engine/Interfaces/services/conversationService.d.ts +5 -0
- package/dist/src/Engine/Interfaces/services/dataSerializer.d.ts +4 -0
- package/dist/src/Engine/Interfaces/services/dataService.d.ts +33 -0
- package/dist/src/Engine/Interfaces/services/dataSynchronizer.d.ts +3 -0
- package/dist/src/Engine/Interfaces/services/gameService.d.ts +10 -0
- package/dist/src/Engine/Interfaces/services/index.d.ts +16 -0
- package/dist/src/Engine/Interfaces/services/itemService.d.ts +14 -0
- package/dist/src/Engine/Interfaces/services/localStorageService.d.ts +6 -0
- package/dist/src/Engine/Interfaces/services/locationService.d.ts +8 -0
- package/dist/src/Engine/Interfaces/services/soundService.d.ts +5 -0
- package/dist/src/Engine/Interfaces/services/tradeService.d.ts +9 -0
- package/dist/src/Engine/Interfaces/soundPlayer.d.ts +30 -0
- package/dist/src/Engine/Interfaces/sprite.d.ts +23 -0
- package/dist/src/Engine/Interfaces/stateList.d.ts +9 -0
- package/dist/src/Engine/Interfaces/statistics.d.ts +13 -0
- package/dist/src/Engine/Interfaces/stock.d.ts +39 -0
- package/dist/src/Engine/Interfaces/trade.d.ts +62 -0
- package/dist/src/Engine/ServiceFactory.d.ts +52 -0
- package/dist/src/Engine/Services/AutoplayService.d.ts +11 -0
- package/dist/src/Engine/Services/CharacterService.d.ts +21 -0
- package/dist/src/Engine/Services/CombatService.d.ts +16 -0
- package/dist/src/Engine/Services/CombinationService.d.ts +15 -0
- package/dist/src/Engine/Services/CommandService.d.ts +24 -0
- package/dist/src/Engine/Services/ConversationService.d.ts +26 -0
- package/dist/src/Engine/Services/DataSerializer.d.ts +17 -0
- package/dist/src/Engine/Services/DataService.d.ts +16 -0
- package/dist/src/Engine/Services/DataSynchronizer.d.ts +12 -0
- package/dist/src/Engine/Services/GameService.d.ts +28 -0
- package/dist/src/Engine/Services/HelperService.d.ts +18 -0
- package/dist/src/Engine/Services/ItemService.d.ts +21 -0
- package/dist/src/Engine/Services/LocalStorageService.d.ts +7 -0
- package/dist/src/Engine/Services/LocationService.d.ts +25 -0
- package/dist/src/Engine/Services/SoundService.d.ts +13 -0
- package/dist/src/Engine/Services/TradeService.d.ts +17 -0
- package/dist/src/Engine/Services/index.d.ts +17 -0
- package/dist/src/Engine/Services/serializationData.d.ts +8 -0
- package/dist/src/Engine/Services/sharedFunctions.d.ts +21 -0
- package/dist/src/Engine/arrayAndFunctionExtensions.d.ts +3 -0
- package/dist/src/Engine/defaultTexts.d.ts +7 -0
- package/dist/src/Engine/gameEvents.d.ts +10 -0
- package/dist/src/Engine/index.d.ts +8 -0
- package/dist/src/Engine/stateProperties.d.ts +6 -0
- package/dist/src/Engine/utilityFunctions.d.ts +25 -0
- package/dist/src/UI/Composables/CustomCursor.d.ts +2 -0
- package/dist/src/UI/Composables/LocationMap.d.ts +26 -0
- package/dist/src/UI/Composables/Sound.d.ts +7 -0
- package/dist/src/UI/Composables/TextFeatures.d.ts +8 -0
- package/dist/src/UI/Composables/VisualFeatures.d.ts +7 -0
- package/dist/src/UI/Composables/index.d.ts +7 -0
- package/dist/src/UI/Composables/playStateWatch.d.ts +2 -0
- package/dist/src/UI/StateStore.d.ts +14256 -0
- package/dist/src/UI/error.d.ts +6 -0
- package/dist/src/UI/helpers.d.ts +3 -0
- package/dist/src/UI/index.d.ts +6 -0
- package/dist/src/UI/main.d.ts +1 -0
- package/dist/src/UI/startup.d.ts +2 -0
- package/dist/src/constants.d.ts +17 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/storyscript.css +9566 -0
- package/dist/storyscript.js +9659 -0
- package/dist/storyscript.js.map +1 -0
- package/dist/storyscript.mjs +9569 -0
- package/dist/storyscript.mjs.map +1 -0
- package/electron.cjs +44 -0
- package/index.html +14 -0
- package/package.json +118 -4
- package/scripts/cli.js +268 -0
- package/scripts/createAsset.js +117 -0
- package/scripts/createGame.js +40 -0
- package/scripts/helpers.js +21 -0
- package/scripts/postbuild.js +179 -0
- package/scripts/setupTesting.js +17 -0
- package/shims-vue.d.ts +1 -0
- package/src/Engine/Actions/index.ts +2 -0
- package/src/Engine/Actions/open.ts +12 -0
- package/src/Engine/Actions/openWithKey.ts +23 -0
- package/src/Engine/EntityCreatorFunctions.ts +602 -0
- package/src/Engine/Interfaces/action.ts +43 -0
- package/src/Engine/Interfaces/autoplayStep.ts +13 -0
- package/src/Engine/Interfaces/barrier.ts +18 -0
- package/src/Engine/Interfaces/barrierAction.ts +21 -0
- package/src/Engine/Interfaces/character.ts +58 -0
- package/src/Engine/Interfaces/combatSetup.ts +10 -0
- package/src/Engine/Interfaces/combatTurn.ts +45 -0
- package/src/Engine/Interfaces/combatWinnings.ts +7 -0
- package/src/Engine/Interfaces/combinations/activeCombination.ts +16 -0
- package/src/Engine/Interfaces/combinations/combinable.ts +21 -0
- package/src/Engine/Interfaces/combinations/combinationAction.ts +45 -0
- package/src/Engine/Interfaces/combinations/combinationMatchResult.ts +16 -0
- package/src/Engine/Interfaces/combinations/combinations.ts +19 -0
- package/src/Engine/Interfaces/combinations/combine.ts +25 -0
- package/src/Engine/Interfaces/combinations/combineResult.ts +21 -0
- package/src/Engine/Interfaces/combinations/gameCombinations.ts +48 -0
- package/src/Engine/Interfaces/compiledLocation.ts +37 -0
- package/src/Engine/Interfaces/conversations/conversation.ts +47 -0
- package/src/Engine/Interfaces/conversations/conversationLogEntry.ts +14 -0
- package/src/Engine/Interfaces/conversations/conversationNode.ts +26 -0
- package/src/Engine/Interfaces/conversations/conversationReply.ts +59 -0
- package/src/Engine/Interfaces/createCharacter/createCharacter.ts +23 -0
- package/src/Engine/Interfaces/createCharacter/createCharacterAttribute.ts +21 -0
- package/src/Engine/Interfaces/createCharacter/createCharacterAttributeEntry.ts +21 -0
- package/src/Engine/Interfaces/createCharacter/createCharacterQuestion.ts +21 -0
- package/src/Engine/Interfaces/createCharacter/createCharacterQuestionEntry.ts +25 -0
- package/src/Engine/Interfaces/createCharacter/createCharacterStep.ts +47 -0
- package/src/Engine/Interfaces/customCursor.ts +5 -0
- package/src/Engine/Interfaces/defaultEquipment.ts +32 -0
- package/src/Engine/Interfaces/definitions.ts +48 -0
- package/src/Engine/Interfaces/destination.ts +37 -0
- package/src/Engine/Interfaces/dynamicStyle.ts +11 -0
- package/src/Engine/Interfaces/enemy.ts +54 -0
- package/src/Engine/Interfaces/enumerations/actionStatus.ts +20 -0
- package/src/Engine/Interfaces/enumerations/actionType.ts +9 -0
- package/src/Engine/Interfaces/enumerations/equipmentType.ts +61 -0
- package/src/Engine/Interfaces/enumerations/gameState.ts +11 -0
- package/src/Engine/Interfaces/enumerations/playState.ts +10 -0
- package/src/Engine/Interfaces/enumerations/targetType.ts +9 -0
- package/src/Engine/Interfaces/equipment.ts +44 -0
- package/src/Engine/Interfaces/feature.ts +43 -0
- package/src/Engine/Interfaces/featureCollection.ts +8 -0
- package/src/Engine/Interfaces/game.ts +201 -0
- package/src/Engine/Interfaces/gameEvents.ts +11 -0
- package/src/Engine/Interfaces/groupableItem.ts +37 -0
- package/src/Engine/Interfaces/helpers.ts +55 -0
- package/src/Engine/Interfaces/index.ts +158 -0
- package/src/Engine/Interfaces/interfaceTexts.ts +142 -0
- package/src/Engine/Interfaces/item.ts +111 -0
- package/src/Engine/Interfaces/key.ts +18 -0
- package/src/Engine/Interfaces/location.ts +92 -0
- package/src/Engine/Interfaces/maps/map.ts +55 -0
- package/src/Engine/Interfaces/maps/mapLocation.ts +28 -0
- package/src/Engine/Interfaces/party.ts +40 -0
- package/src/Engine/Interfaces/person.ts +29 -0
- package/src/Engine/Interfaces/quest.ts +60 -0
- package/src/Engine/Interfaces/rules/characterRules.ts +96 -0
- package/src/Engine/Interfaces/rules/combatRules.ts +52 -0
- package/src/Engine/Interfaces/rules/combinationRules.ts +17 -0
- package/src/Engine/Interfaces/rules/demoMode.ts +18 -0
- package/src/Engine/Interfaces/rules/encounterRules.ts +5 -0
- package/src/Engine/Interfaces/rules/explorationRules.ts +47 -0
- package/src/Engine/Interfaces/rules/generalRules.ts +80 -0
- package/src/Engine/Interfaces/rules/rules.ts +46 -0
- package/src/Engine/Interfaces/rules/setupRules.ts +65 -0
- package/src/Engine/Interfaces/rules/titleScreen.ts +19 -0
- package/src/Engine/Interfaces/saveGame.ts +39 -0
- package/src/Engine/Interfaces/scoreEntry.ts +14 -0
- package/src/Engine/Interfaces/services/autoplayService.ts +23 -0
- package/src/Engine/Interfaces/services/characterService.ts +35 -0
- package/src/Engine/Interfaces/services/combatService.ts +30 -0
- package/src/Engine/Interfaces/services/combinationService.ts +10 -0
- package/src/Engine/Interfaces/services/commandService.ts +75 -0
- package/src/Engine/Interfaces/services/conversationService.ts +7 -0
- package/src/Engine/Interfaces/services/dataSerializer.ts +4 -0
- package/src/Engine/Interfaces/services/dataService.ts +39 -0
- package/src/Engine/Interfaces/services/dataSynchronizer.ts +9 -0
- package/src/Engine/Interfaces/services/gameService.ts +17 -0
- package/src/Engine/Interfaces/services/index.ts +33 -0
- package/src/Engine/Interfaces/services/itemService.ts +25 -0
- package/src/Engine/Interfaces/services/localStorageService.ts +6 -0
- package/src/Engine/Interfaces/services/locationService.ts +13 -0
- package/src/Engine/Interfaces/services/soundService.ts +7 -0
- package/src/Engine/Interfaces/services/tradeService.ts +15 -0
- package/src/Engine/Interfaces/soundPlayer.ts +30 -0
- package/src/Engine/Interfaces/sprite.ts +27 -0
- package/src/Engine/Interfaces/stateList.ts +13 -0
- package/src/Engine/Interfaces/statistics.ts +14 -0
- package/src/Engine/Interfaces/stock.ts +46 -0
- package/src/Engine/Interfaces/trade.ts +72 -0
- package/src/Engine/ServiceFactory.ts +167 -0
- package/src/Engine/Services/AutoplayService.ts +59 -0
- package/src/Engine/Services/CharacterService.ts +291 -0
- package/src/Engine/Services/CombatService.ts +266 -0
- package/src/Engine/Services/CombinationService.ts +197 -0
- package/src/Engine/Services/CommandService.ts +197 -0
- package/src/Engine/Services/ConversationService.ts +406 -0
- package/src/Engine/Services/DataSerializer.ts +326 -0
- package/src/Engine/Services/DataService.ts +93 -0
- package/src/Engine/Services/DataSynchronizer.ts +216 -0
- package/src/Engine/Services/GameService.ts +554 -0
- package/src/Engine/Services/HelperService.ts +94 -0
- package/src/Engine/Services/ItemService.ts +294 -0
- package/src/Engine/Services/LocalStorageService.ts +24 -0
- package/src/Engine/Services/LocationService.ts +380 -0
- package/src/Engine/Services/SoundService.ts +54 -0
- package/src/Engine/Services/TradeService.ts +176 -0
- package/src/Engine/Services/index.ts +17 -0
- package/src/Engine/Services/serializationData.ts +8 -0
- package/src/Engine/Services/sharedFunctions.ts +296 -0
- package/src/Engine/arrayAndFunctionExtensions.ts +269 -0
- package/src/Engine/defaultTexts.ts +162 -0
- package/src/Engine/gameEvents.ts +51 -0
- package/src/Engine/index.ts +9 -0
- package/src/Engine/stateProperties.ts +9 -0
- package/src/Engine/utilityFunctions.ts +238 -0
- package/src/Games/_GameTemplate/character.ts +31 -0
- package/src/Games/_GameTemplate/customTexts.ts +8 -0
- package/src/Games/_GameTemplate/interfaces/action.ts +5 -0
- package/src/Games/_GameTemplate/interfaces/combatSetup.ts +7 -0
- package/src/Games/_GameTemplate/interfaces/combatTurn.ts +8 -0
- package/src/Games/_GameTemplate/interfaces/destination.ts +5 -0
- package/src/Games/_GameTemplate/interfaces/enemy.ts +11 -0
- package/src/Games/_GameTemplate/interfaces/equipment.ts +5 -0
- package/src/Games/_GameTemplate/interfaces/feature.ts +9 -0
- package/src/Games/_GameTemplate/interfaces/game.ts +22 -0
- package/src/Games/_GameTemplate/interfaces/interfaceTexts.ts +5 -0
- package/src/Games/_GameTemplate/interfaces/item.ts +18 -0
- package/src/Games/_GameTemplate/interfaces/key.ts +10 -0
- package/src/Games/_GameTemplate/interfaces/location.ts +22 -0
- package/src/Games/_GameTemplate/interfaces/map.ts +16 -0
- package/src/Games/_GameTemplate/interfaces/party.ts +8 -0
- package/src/Games/_GameTemplate/interfaces/person.ts +11 -0
- package/src/Games/_GameTemplate/interfaces/quest.ts +9 -0
- package/src/Games/_GameTemplate/locations/Start.html +5 -0
- package/src/Games/_GameTemplate/locations/start.ts +12 -0
- package/src/Games/_GameTemplate/rules.ts +60 -0
- package/src/Games/_GameTemplate/types.ts +55 -0
- package/src/Games/_GameTemplate/ui/styles/game.css +3 -0
- package/src/Games/_GameTemplate/webroot/favicon.ico +0 -0
- package/src/Games/_GameTemplate/webroot/gameinfo.json +10 -0
- package/src/Games/_GameTemplate/webroot/logo192.png +0 -0
- package/src/Games/_GameTemplate/webroot/logo512.png +0 -0
- package/src/Tests/Games/_GameTemplate/specs/rules.test.ts +9 -0
- package/src/UI/Components/AppShell.vue +43 -0
- package/src/UI/Components/Autoplay.vue +32 -0
- package/src/UI/Components/Combinations.vue +37 -0
- package/src/UI/Components/Common/Collapsible.vue +50 -0
- package/src/UI/Components/Common/ModalDialog.vue +54 -0
- package/src/UI/Components/Common/Sprite.vue +53 -0
- package/src/UI/Components/Description.vue +23 -0
- package/src/UI/Components/Encounter/Combat/Combat.vue +89 -0
- package/src/UI/Components/Encounter/Combat/CombatActions.vue +26 -0
- package/src/UI/Components/Encounter/Combat/CombatParticipant.vue +22 -0
- package/src/UI/Components/Encounter/Combat/CombatTargetSelect.vue +55 -0
- package/src/UI/Components/Encounter/Combat/CombatWin.vue +33 -0
- package/src/UI/Components/Encounter/Conversation.vue +66 -0
- package/src/UI/Components/Encounter/Encounter.vue +39 -0
- package/src/UI/Components/Encounter/Enemy.vue +30 -0
- package/src/UI/Components/Encounter/Trade/Stock.vue +58 -0
- package/src/UI/Components/Encounter/Trade/Trade.vue +24 -0
- package/src/UI/Components/Exploration/ActionLog.vue +17 -0
- package/src/UI/Components/Exploration/Destination.vue +66 -0
- package/src/UI/Components/Exploration/Exploration.vue +67 -0
- package/src/UI/Components/Exploration/Ground.vue +22 -0
- package/src/UI/Components/Exploration/LocationMap.vue +42 -0
- package/src/UI/Components/Exploration/LocationText.vue +39 -0
- package/src/UI/Components/Exploration/LocationVisual.vue +38 -0
- package/src/UI/Components/GameContainer.vue +49 -0
- package/src/UI/Components/GameMenu.vue +111 -0
- package/src/UI/Components/GameState/GameOver.vue +20 -0
- package/src/UI/Components/GameState/HighScores.vue +22 -0
- package/src/UI/Components/GameState/Intro.vue +17 -0
- package/src/UI/Components/GameState/TitleScreen.vue +42 -0
- package/src/UI/Components/GameState/Victory.vue +28 -0
- package/src/UI/Components/Navigation.vue +94 -0
- package/src/UI/Components/Party/Backpack.vue +68 -0
- package/src/UI/Components/Party/BuildCharacter.vue +64 -0
- package/src/UI/Components/Party/CharacterSheet.vue +57 -0
- package/src/UI/Components/Party/CreateCharacter.vue +46 -0
- package/src/UI/Components/Party/Equipment.vue +48 -0
- package/src/UI/Components/Party/EquipmentSlot.vue +31 -0
- package/src/UI/Components/Party/LevelUp.vue +27 -0
- package/src/UI/Components/Party/Party.vue +29 -0
- package/src/UI/Components/Party/Quests.vue +48 -0
- package/src/UI/Components/Sound.vue +42 -0
- package/src/UI/Composables/CustomCursor.ts +60 -0
- package/src/UI/Composables/LocationMap.ts +315 -0
- package/src/UI/Composables/Sound.ts +111 -0
- package/src/UI/Composables/TextFeatures.ts +148 -0
- package/src/UI/Composables/VisualFeatures.ts +220 -0
- package/src/UI/Composables/index.ts +15 -0
- package/src/UI/Composables/playStateWatch.ts +31 -0
- package/src/UI/StateStore.ts +237 -0
- package/src/UI/error.ts +6 -0
- package/src/UI/helpers.ts +62 -0
- package/src/UI/index.ts +13 -0
- package/src/UI/main.ts +62 -0
- package/src/UI/startup.ts +58 -0
- package/src/UI/styles/bootstrap-storyscript.scss +31 -0
- package/src/UI/styles/empty.css +3 -0
- package/src/UI/styles/lookinglass.png +0 -0
- package/src/UI/styles/storyscript.css +735 -0
- package/typeExtensions.d.ts +25 -0
- package/vite-env.d.ts +1 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
import {
|
|
2
|
+
gameEvents,
|
|
3
|
+
ICombinable,
|
|
4
|
+
ICombine,
|
|
5
|
+
ICompiledLocation,
|
|
6
|
+
IDefinitions,
|
|
7
|
+
IDestination,
|
|
8
|
+
IEnemy,
|
|
9
|
+
IFeature,
|
|
10
|
+
IGroupableItem,
|
|
11
|
+
IItem,
|
|
12
|
+
IKey,
|
|
13
|
+
ILocation,
|
|
14
|
+
IMap,
|
|
15
|
+
IPerson,
|
|
16
|
+
IQuest
|
|
17
|
+
} from 'storyScript';
|
|
18
|
+
import {getId, getPlural, getSingular, parseHtmlDocumentFromString} from './utilityFunctions';
|
|
19
|
+
import {DescriptionProperty, Enemies, Features, Items, Locations, Maps, Persons, Quests} from 'src/constants';
|
|
20
|
+
|
|
21
|
+
const _entityCollections: string[] = [
|
|
22
|
+
'features',
|
|
23
|
+
'items',
|
|
24
|
+
'enemies',
|
|
25
|
+
'persons',
|
|
26
|
+
'quests'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const _gameCollections: string[] = _entityCollections.concat([
|
|
30
|
+
'actions',
|
|
31
|
+
'barriers',
|
|
32
|
+
'combatActions',
|
|
33
|
+
'enterEvents',
|
|
34
|
+
'leaveEvents',
|
|
35
|
+
'triggeredEvents',
|
|
36
|
+
'trade',
|
|
37
|
+
'destinations',
|
|
38
|
+
'combine'
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
// The dictionary containing all registered entity keys and their corresponding ids.
|
|
42
|
+
let _registeredIds: Map<string, string> = new Map<string, string>();
|
|
43
|
+
|
|
44
|
+
// A record to keep all the entities available, fully build.
|
|
45
|
+
const _registeredEntities: Record<string, Record<string, any>> = {};
|
|
46
|
+
|
|
47
|
+
export function Location(entity: ILocation): ILocation {
|
|
48
|
+
return Create('location', entity);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function LocationMap(entity: IMap): IMap {
|
|
52
|
+
return Create('map', entity);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function Enemy<T extends IEnemy>(entity: T): T {
|
|
56
|
+
return Create('enemy', entity);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function Person<T extends IPerson>(entity: T): T {
|
|
60
|
+
return Create('person', entity);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function Item<T extends IItem>(entity: T): T {
|
|
64
|
+
return Create('item', entity);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function Key<T extends IKey>(entity: T): T {
|
|
68
|
+
return Create('item', entity);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function Feature<T extends IFeature>(entity: T): IFeature {
|
|
72
|
+
return Create('feature', entity);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function Quest<T extends IQuest>(entity: T): T {
|
|
76
|
+
return Create('quest', entity);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function DynamicEntity<T>(entityFunction: () => T, id?: string): T {
|
|
80
|
+
const compiledEntity = <any>entityFunction();
|
|
81
|
+
const entityKey = getEntityKey(compiledEntity);
|
|
82
|
+
id ??= getId(entityFunction);
|
|
83
|
+
|
|
84
|
+
if (!id) {
|
|
85
|
+
throw new Error('A dynamic entity needs an id! Either use a named function or specify an id!');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
compiledEntity.id = id;
|
|
89
|
+
_registeredIds.set(entityKey, compiledEntity.id);
|
|
90
|
+
return compiledEntity;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function customEntity<T, C extends { name: string }>(definition: () => T, customData: C): T {
|
|
94
|
+
if (!customData.name) {
|
|
95
|
+
throw new Error('A custom entity needs a custom name!');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const customEntity = <any>extend(definition(), customData);
|
|
99
|
+
const customEntityKey = getEntityKey(customEntity);
|
|
100
|
+
|
|
101
|
+
if (!_registeredIds.has(customEntityKey)) {
|
|
102
|
+
_registeredIds.set(customEntityKey, getIdFromName(customEntity));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
customEntity.id = _registeredIds.get(customEntityKey);
|
|
106
|
+
return customEntity;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function buildEntities(definitions: IDefinitions): Record<string, Record<string, any>> {
|
|
110
|
+
// Build all entities and register them and their ids. The order in which the definitions are read
|
|
111
|
+
// is very important! Entities that can contain other entities should be built AFTER the entities
|
|
112
|
+
// they may contain. Otherwise, the entity id will not be resolved and actions depending on the id
|
|
113
|
+
// to be present cannot be carried out.
|
|
114
|
+
const allDefinitions = [
|
|
115
|
+
Features,
|
|
116
|
+
Quests,
|
|
117
|
+
Items,
|
|
118
|
+
Enemies,
|
|
119
|
+
Persons,
|
|
120
|
+
Locations,
|
|
121
|
+
Maps
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
allDefinitions.forEach(p => {
|
|
125
|
+
definitions[p]?.forEach((f: Function) => {
|
|
126
|
+
const compiledEntity = f();
|
|
127
|
+
const entityKey = getEntityKey(compiledEntity);
|
|
128
|
+
const actualId = getId(f);
|
|
129
|
+
|
|
130
|
+
if (compiledEntity.id && compiledEntity.id !== actualId) {
|
|
131
|
+
throw new Error(`Entity type '${compiledEntity.type}' with id '${actualId}' and
|
|
132
|
+
name '${compiledEntity.name}' has a non-unique entityKey! This means you have two or more
|
|
133
|
+
entities of type '${compiledEntity.type}' that are too similar. The easiest way to avoid
|
|
134
|
+
this issue is to use unique names for your entities.`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
compiledEntity.id = actualId;
|
|
138
|
+
_registeredIds.set(entityKey, compiledEntity.id);
|
|
139
|
+
parseDescriptionData(compiledEntity);
|
|
140
|
+
registerEntity(compiledEntity);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return _registeredEntities;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function InitEntityCollection(entity: any, property: string) {
|
|
148
|
+
if (_gameCollections.indexOf(property) === -1) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const collection = entity[property] || [];
|
|
153
|
+
|
|
154
|
+
Object.defineProperty(entity, property, {
|
|
155
|
+
enumerable: true,
|
|
156
|
+
get: function () {
|
|
157
|
+
return collection;
|
|
158
|
+
},
|
|
159
|
+
set: function () {
|
|
160
|
+
const message = entity.type ? `Cannot set collection ${property} on type ${entity.type}!` : `Cannot set collection ${property}!`;
|
|
161
|
+
throw new Error(message);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (_entityCollections.indexOf(property) > -1 && !collection.add.isProxy) {
|
|
166
|
+
Object.defineProperty(collection, 'add', {
|
|
167
|
+
writable: true,
|
|
168
|
+
value: collection.add.proxy((originalScope: any, originalFunction: any, addedEntity: any) =>
|
|
169
|
+
pushEntity(originalScope, originalFunction, entity, property, addedEntity))
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
Object.defineProperty(collection, 'delete', {
|
|
173
|
+
writable: true,
|
|
174
|
+
value: collection.delete.proxy((originalScope: any, originalFunction: any, deletedEntity: any) =>
|
|
175
|
+
removeEntity(originalScope, originalFunction, entity, property, deletedEntity))
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
gameEvents.register(`add-${entity.type}-${property}`);
|
|
179
|
+
gameEvents.register(`delete-${entity.type}-${property}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function setDestination(destination: IDestination) {
|
|
184
|
+
// Set the barrier selected actions to the first one available for each barrier.
|
|
185
|
+
// Further, replace combine functions with their target ids.
|
|
186
|
+
destination.target = getId(destination.target);
|
|
187
|
+
|
|
188
|
+
if (destination.barriers) {
|
|
189
|
+
destination.barriers.forEach(([_, b]) => {
|
|
190
|
+
if (b.key) {
|
|
191
|
+
const key = b.key;
|
|
192
|
+
b.key = getId(key);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (b.combinations?.combine) {
|
|
196
|
+
for (const n in b.combinations.combine) {
|
|
197
|
+
const combination = b.combinations.combine[n];
|
|
198
|
+
combination.tool = <any>getId(<any>combination.tool);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function getBasicFeatureData(location: ICompiledLocation, node: HTMLElement): IFeature {
|
|
206
|
+
const nameAttribute = node.attributes['name']?.nodeValue?.toLowerCase();
|
|
207
|
+
|
|
208
|
+
if (!nameAttribute) {
|
|
209
|
+
throw new Error('There is no name attribute for a feature node for location ' + location.id + '.');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// The second part of this line is a workaround for features that are initialized inline. When building locations
|
|
213
|
+
// from the location definitions, their ids get set only after the location's visual features have been processed.
|
|
214
|
+
const feature = location.features.get(nameAttribute) ?? location.features.filter(f => getIdFromName(f) === nameAttribute)[0];
|
|
215
|
+
|
|
216
|
+
// This is a workaround to restore the description for features that originally have only a placeholder in the
|
|
217
|
+
// location description and are added later to the location's feature collection. As descriptions are not saved,
|
|
218
|
+
// the description is lost when the browser refreshes.
|
|
219
|
+
if (feature && !feature.description && _registeredEntities.features) {
|
|
220
|
+
const pristineFeature = Object.values(_registeredEntities.features).get(feature.id);
|
|
221
|
+
|
|
222
|
+
if (pristineFeature?.description) {
|
|
223
|
+
feature.description = pristineFeature.description;
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return feature;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function getParsedDocument(tag: string, value?: string, wrapIfNotFound?: boolean) {
|
|
232
|
+
if (!value) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
let htmlDoc = parseHtmlDocumentFromString(value);
|
|
237
|
+
let elements = htmlDoc.getElementsByTagName(tag);
|
|
238
|
+
|
|
239
|
+
if (!elements.length && wrapIfNotFound) {
|
|
240
|
+
value = `<${tag}>${value}</${tag}>`;
|
|
241
|
+
htmlDoc = parseHtmlDocumentFromString(value);
|
|
242
|
+
elements = htmlDoc.getElementsByTagName(tag);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return elements;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function registerEntity(entity: any): void {
|
|
249
|
+
const type = getPlural(entity.type);
|
|
250
|
+
_registeredEntities[type] ??= {};
|
|
251
|
+
|
|
252
|
+
if (!_registeredEntities[type][entity.id]) {
|
|
253
|
+
_registeredEntities[type][entity.id] = entity;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function Create(type: string, entity: any, id?: string) {
|
|
258
|
+
switch (type) {
|
|
259
|
+
case 'location':
|
|
260
|
+
return createLocation(entity);
|
|
261
|
+
case 'map':
|
|
262
|
+
return createMap(entity);
|
|
263
|
+
case 'enemy':
|
|
264
|
+
return EnemyBase(entity, 'enemy', id);
|
|
265
|
+
case 'person':
|
|
266
|
+
return createPerson(entity, id);
|
|
267
|
+
case 'item':
|
|
268
|
+
return createItem(entity, id);
|
|
269
|
+
case 'feature':
|
|
270
|
+
return createFeature(entity, id);
|
|
271
|
+
case 'quest':
|
|
272
|
+
return CreateObject(entity, 'quest', id);
|
|
273
|
+
case 'trade':
|
|
274
|
+
return CreateObject(entity, 'trade', id);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function createLocation(entity: ILocation) {
|
|
279
|
+
const location = CreateObject(entity, 'location');
|
|
280
|
+
|
|
281
|
+
if (location.destinations) {
|
|
282
|
+
location.destinations.forEach(d => {
|
|
283
|
+
d.barriers?.forEach(([_, b]) => {
|
|
284
|
+
if (b.key) {
|
|
285
|
+
b.key = getId(b.key);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
d.target = getId(d.target);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (!location.destinations) {
|
|
294
|
+
console.log('No destinations specified for location ' + location.name);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
initCollection(location, 'actions');
|
|
298
|
+
initCollection(location, 'combatActions');
|
|
299
|
+
initCollection(location, 'destinations');
|
|
300
|
+
initCollection(location, 'features');
|
|
301
|
+
initCollection(location, 'trade');
|
|
302
|
+
initCollection(location, 'items');
|
|
303
|
+
initCollection(location, 'enemies');
|
|
304
|
+
initCollection(location, 'persons');
|
|
305
|
+
initCollection(location, 'enterEvents');
|
|
306
|
+
initCollection(location, 'leaveEvents');
|
|
307
|
+
initCollection(location, 'triggeredEvents');
|
|
308
|
+
return location;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function createMap(entity: IMap, id?: string) {
|
|
312
|
+
const map = CreateObject(entity, 'map', id);
|
|
313
|
+
|
|
314
|
+
map.locations.forEach(l => {
|
|
315
|
+
l.location = getId(l.location);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
return map;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function createPerson(entity: IPerson, id?: string) {
|
|
322
|
+
const person = EnemyBase(entity, 'person', id);
|
|
323
|
+
initCollection(person, 'quests');
|
|
324
|
+
return person;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function createItem(entity: IItem, id?: string) {
|
|
328
|
+
const item = CreateObject(entity, 'item', id);
|
|
329
|
+
compileCombinations(item);
|
|
330
|
+
|
|
331
|
+
const groupableItem = item as IGroupableItem<IItem>;
|
|
332
|
+
|
|
333
|
+
if (groupableItem.groupTypes) {
|
|
334
|
+
groupableItem.groupTypes = groupableItem.groupTypes.map(t => getId(t));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return item;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function createFeature(entity: IFeature, id?: string) {
|
|
341
|
+
const feature = CreateObject(entity, 'feature', id);
|
|
342
|
+
compileCombinations(feature);
|
|
343
|
+
return feature;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function EnemyBase<T extends IEnemy>(entity: T, type: string, id?: string): T {
|
|
347
|
+
const enemy = CreateObject(entity, type, id);
|
|
348
|
+
compileCombinations(enemy);
|
|
349
|
+
initCollection(enemy, 'items');
|
|
350
|
+
return enemy;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function CreateObject<T>(entity: T, type: string, id?: string) {
|
|
354
|
+
if (typeof entity === 'function') {
|
|
355
|
+
id = getId(entity);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const compiledEntity = getCompiledEntity(entity, type);
|
|
359
|
+
const entityKey = getEntityKey(compiledEntity);
|
|
360
|
+
|
|
361
|
+
checkInlineConflict(id, entityKey);
|
|
362
|
+
|
|
363
|
+
if (!id && _registeredIds.has(entityKey)) {
|
|
364
|
+
id = _registeredIds.get(entityKey);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
if (id) {
|
|
368
|
+
compiledEntity.id = id;
|
|
369
|
+
parseDescriptionData(compiledEntity);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return <T><unknown>compiledEntity;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function parseDescriptionData(entity: any) {
|
|
376
|
+
if (entity.description) {
|
|
377
|
+
loadPictureFromDescription(entity, entity.description);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if (entity.type === 'location') {
|
|
381
|
+
processVisualFeatures(entity);
|
|
382
|
+
loadDescriptions(entity);
|
|
383
|
+
setDestinations(entity);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function loadPictureFromDescription(entity: any, description: string): void {
|
|
388
|
+
const htmlDoc = parseHtmlDocumentFromString(description);
|
|
389
|
+
const pictureElement = htmlDoc.getElementsByClassName('picture')[0];
|
|
390
|
+
const pictureSrc = pictureElement?.getAttribute('src');
|
|
391
|
+
|
|
392
|
+
if (pictureSrc) {
|
|
393
|
+
entity.picture = pictureSrc;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function loadDescriptions(location: ICompiledLocation): void {
|
|
398
|
+
location.descriptions = {};
|
|
399
|
+
const nodes = getParsedDocument(DescriptionProperty, location.description);
|
|
400
|
+
|
|
401
|
+
for (const element of nodes) {
|
|
402
|
+
const nameAttribute = element.attributes['name']?.nodeValue;
|
|
403
|
+
const name = nameAttribute || 'default';
|
|
404
|
+
|
|
405
|
+
if (location.descriptions[name]) {
|
|
406
|
+
throw new Error('There is already a description with name ' + name + ' for location ' + location.id + '.');
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
location.descriptions[name] = element.innerHTML;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
location.description = null;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function processVisualFeatures(location: ICompiledLocation): void {
|
|
416
|
+
const visualFeatureNode = getParsedDocument('visual-features', location.description)[0]
|
|
417
|
+
|
|
418
|
+
if (visualFeatureNode) {
|
|
419
|
+
location.features ??= [];
|
|
420
|
+
location.features.collectionPicture = visualFeatureNode.attributes['img']?.nodeValue;
|
|
421
|
+
|
|
422
|
+
if (location.features.length > 0) {
|
|
423
|
+
const areaNodes = visualFeatureNode.getElementsByTagName('area');
|
|
424
|
+
|
|
425
|
+
for (const element of areaNodes) {
|
|
426
|
+
const feature = getBasicFeatureData(location, element);
|
|
427
|
+
|
|
428
|
+
if (feature) {
|
|
429
|
+
feature.coords ??= element.attributes['coords']?.nodeValue;
|
|
430
|
+
feature.shape ??= element.attributes['shape']?.nodeValue;
|
|
431
|
+
feature.picture ??= element.attributes['img']?.nodeValue;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
visualFeatureNode.parentNode.removeChild(visualFeatureNode);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function setDestinations(location: ICompiledLocation): void {
|
|
441
|
+
if (location.destinations) {
|
|
442
|
+
location.destinations.forEach(destination => {
|
|
443
|
+
setDestination(destination);
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function initCollection(entity: any, property: string) {
|
|
449
|
+
if (_gameCollections.indexOf(property) === -1) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const collection = entity[property] || [];
|
|
454
|
+
|
|
455
|
+
if ((property === 'features' || property === 'trade') && collection.length) {
|
|
456
|
+
const inlineCollection = collection.map((e: { type: string, name: string }) => {
|
|
457
|
+
// Initialize features that have been declared inline. Check for the existence of a
|
|
458
|
+
// type property to determine whether the object is already initialized.
|
|
459
|
+
if (e.type) {
|
|
460
|
+
return e;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const typeName = getSingular(property);
|
|
464
|
+
return Create(typeName, e, getIdFromName(e));
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
collection.length = 0;
|
|
468
|
+
|
|
469
|
+
inlineCollection.forEach((e: any) => {
|
|
470
|
+
collection.push(e);
|
|
471
|
+
|
|
472
|
+
if (e.id) {
|
|
473
|
+
registerEntity(e);
|
|
474
|
+
}
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
InitEntityCollection(entity, property);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function checkInlineConflict(id: string, entityKey: string) {
|
|
482
|
+
let inlineConflict = false;
|
|
483
|
+
|
|
484
|
+
if (id) {
|
|
485
|
+
_registeredIds.forEach((v, k) => {
|
|
486
|
+
if (v === id && entityKey !== k) {
|
|
487
|
+
inlineConflict = true;
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
if (inlineConflict) {
|
|
492
|
+
throw new Error('Duplicate id detected: ' + id + '. You cannot use names for entities declared inline that are the same as the names of stand-alone entities.');
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function getCompiledEntity(entity: any, type: string): { id: string, type: string, description?: string } {
|
|
498
|
+
let compiledEntity: { id: string, type: string };
|
|
499
|
+
|
|
500
|
+
if (typeof entity === 'function') {
|
|
501
|
+
compiledEntity = entity();
|
|
502
|
+
} else {
|
|
503
|
+
compiledEntity = entity;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (compiledEntity.id) {
|
|
507
|
+
throw new Error('Property \'id\' is used by StoryScript. Don\'t use it on your own types.');
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (compiledEntity.type && compiledEntity.type !== type) {
|
|
511
|
+
throw new Error('Property \'type\' is used by StoryScript. Don\'t use it on your own types.');
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Add the type to the object, so we can distinguish between them in the combine functionality.
|
|
515
|
+
compiledEntity.type = type;
|
|
516
|
+
return compiledEntity;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function getEntityKey(entity: object): string {
|
|
520
|
+
return Object.getOwnPropertyNames(entity).sort((a, b) => a.localeCompare(b)).map(p => {
|
|
521
|
+
const value = entity[p];
|
|
522
|
+
const type = typeof value;
|
|
523
|
+
let text: string;
|
|
524
|
+
|
|
525
|
+
if (p === DescriptionProperty || Array.isArray(value)) {
|
|
526
|
+
text = undefined;
|
|
527
|
+
} else if (type === 'object') {
|
|
528
|
+
text = p.toString();
|
|
529
|
+
} else if (type === 'function') {
|
|
530
|
+
text = getId(entity[p]);
|
|
531
|
+
} else if (type !== "undefined") {
|
|
532
|
+
text = p.toString() + '|' + entity[p].toString();
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return text;
|
|
536
|
+
}).filter(e => e).join('|');
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function compileCombinations(entry: ICombinable) {
|
|
540
|
+
if (entry.combinations) {
|
|
541
|
+
const combines = <ICombine<ICombinable>[]>[];
|
|
542
|
+
const failText = entry.combinations.failText;
|
|
543
|
+
|
|
544
|
+
entry.combinations.combine.forEach((combine: ICombine<ICombinable>) => {
|
|
545
|
+
const compiled = combine;
|
|
546
|
+
(<any>compiled).tool = compiled.tool?.name;
|
|
547
|
+
combines.push(compiled);
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
entry.combinations.combine = combines;
|
|
551
|
+
entry.combinations.failText = failText;
|
|
552
|
+
initCollection(entry.combinations, 'combine');
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function pushEntity(originalScope: any, originalFunction: any, entity: any, property: string, addedEntity: any) {
|
|
557
|
+
addedEntity = typeof addedEntity === 'function' ? addedEntity() : addedEntity;
|
|
558
|
+
|
|
559
|
+
if (!addedEntity.id && addedEntity.name) {
|
|
560
|
+
addedEntity.id = getIdFromName(addedEntity);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
originalFunction.apply(originalScope, [addedEntity]);
|
|
564
|
+
gameEvents.publish(`add-${entity.type}-${property}`, {
|
|
565
|
+
type: `add-${addedEntity.type}`,
|
|
566
|
+
[entity.type]: entity,
|
|
567
|
+
[addedEntity.type]: addedEntity
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function removeEntity(originalScope: any, originalFunction: any, entity: any, property: string, deletedEntity: any) {
|
|
572
|
+
let deleted = originalFunction.apply(originalScope, [deletedEntity]);
|
|
573
|
+
deleted ??= deletedEntity;
|
|
574
|
+
gameEvents.publish(`delete-${entity.type}-${property}`, {
|
|
575
|
+
type: `delete-${deleted.type}`,
|
|
576
|
+
[entity.type]: entity,
|
|
577
|
+
[deleted.type]: deleted
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
function getIdFromName<T extends { name: string, id?: string }>(entity: T): string {
|
|
582
|
+
return entity.name.toLowerCase().replace(/\s/g, '');
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function extend<T>(target: T, source: {}) {
|
|
586
|
+
const keys = Object.keys(source);
|
|
587
|
+
|
|
588
|
+
for (const key of keys) {
|
|
589
|
+
const value = source[key];
|
|
590
|
+
const isArray = Array.isArray(value);
|
|
591
|
+
|
|
592
|
+
if (isArray) {
|
|
593
|
+
value.forEach(e => target[key].push(e));
|
|
594
|
+
} else if (typeof value === 'object') {
|
|
595
|
+
target[key] = extend(target[key], value);
|
|
596
|
+
} else {
|
|
597
|
+
target[key] = value;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return target;
|
|
602
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { IGame } from './game';
|
|
2
|
+
import { ActionType } from './enumerations/actionType';
|
|
3
|
+
import { ActionStatus } from './enumerations/actionStatus';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Actions available to the player when exploring the location.
|
|
7
|
+
*/
|
|
8
|
+
export interface IAction {
|
|
9
|
+
/**
|
|
10
|
+
* The text shown for this action (e.g. 'Search').
|
|
11
|
+
*/
|
|
12
|
+
text?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* How to visually identify this action to the player.
|
|
16
|
+
*/
|
|
17
|
+
actionType?: ActionType;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The action status or a function that returns an action status to set the status dynamically.
|
|
21
|
+
*/
|
|
22
|
+
status?: ActionStatus | ((game: IGame) => ActionStatus);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The function to execute or game event to raise when the player selects the action. Return
|
|
26
|
+
* true if the action should be allowed to execute more than once. When an event is raised
|
|
27
|
+
* the action is considered to be allowed to execute more than once.
|
|
28
|
+
*/
|
|
29
|
+
execute: string | ((game: IGame) => boolean | void);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* If the player should confirm executing the action, specify a text to ask for confirmation here.
|
|
33
|
+
* The player will then be asked to confirm before the action is executed, and he'll have the
|
|
34
|
+
* option to cancel.
|
|
35
|
+
*/
|
|
36
|
+
confirmationText?: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* When this flag is set to true, the action is not shown to the player. Useful to only conditionally
|
|
40
|
+
* make actions present on a location.
|
|
41
|
+
*/
|
|
42
|
+
inactive?: boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {IGame} from 'storyScript';
|
|
2
|
+
|
|
3
|
+
export interface IAutoplayStep {
|
|
4
|
+
/**
|
|
5
|
+
* The action to execute for this step.
|
|
6
|
+
*/
|
|
7
|
+
action: (game: IGame) => void;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The number of milliseconds to wait before executing this step.
|
|
11
|
+
*/
|
|
12
|
+
delay: number;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IKey } from './key';
|
|
2
|
+
import { IBarrierAction } from './barrierAction';
|
|
3
|
+
import { ICombinable } from './combinations/combinable';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The base properties for barriers that block a player from moving between one world location to the next.
|
|
7
|
+
*/
|
|
8
|
+
export interface IBarrier extends ICombinable {
|
|
9
|
+
/**
|
|
10
|
+
* The actions the player can perform on the barrier (e.g. inspect or open).
|
|
11
|
+
*/
|
|
12
|
+
actions?: [string, IBarrierAction][];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The key to use to remove this barrier.
|
|
16
|
+
*/
|
|
17
|
+
key?: (() => IKey) | string;
|
|
18
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IGame } from './game';
|
|
2
|
+
import { IBarrier } from './barrier';
|
|
3
|
+
import { IDestination } from './destination';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Actions that can be performed on barriers, like opening doors or rowing across rivers.
|
|
7
|
+
*/
|
|
8
|
+
export interface IBarrierAction {
|
|
9
|
+
/**
|
|
10
|
+
* The name of the barrier action as show to the player.
|
|
11
|
+
*/
|
|
12
|
+
text: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The function to execute when the player selects this action.
|
|
16
|
+
* @param game The game object
|
|
17
|
+
* @param barrier The barrier
|
|
18
|
+
* @param destination The destination the barrier is for
|
|
19
|
+
*/
|
|
20
|
+
execute(game: IGame, barrier: [string, IBarrier], destination: IDestination): void;
|
|
21
|
+
}
|