@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,220 @@
|
|
|
1
|
+
import {computed, onUpdated, Ref, ref, watch} from "vue";
|
|
2
|
+
import {useStateStore} from "ui/StateStore";
|
|
3
|
+
import {storeToRefs} from "pinia";
|
|
4
|
+
import {isTouchDevice} from 'src/constants';
|
|
5
|
+
|
|
6
|
+
const prepareLoadedImages = (locationImagesRef: HTMLImageElement[]) => {
|
|
7
|
+
const loadedImages: { element: HTMLImageElement, loadPromise: Promise<void> }[] = [];
|
|
8
|
+
|
|
9
|
+
locationImagesRef.forEach(l => {
|
|
10
|
+
let promiseResolve: () => {};
|
|
11
|
+
|
|
12
|
+
const loadPromise = new Promise<void>((r: any): void => {
|
|
13
|
+
promiseResolve = r;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
l.onload = promiseResolve;
|
|
17
|
+
|
|
18
|
+
if (l.naturalWidth > 0) {
|
|
19
|
+
promiseResolve();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
loadedImages.push({
|
|
23
|
+
element: l,
|
|
24
|
+
loadPromise: loadPromise
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return loadedImages;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function useVisualFeatures(imageRef: Ref<HTMLDivElement>) {
|
|
32
|
+
const store = useStateStore();
|
|
33
|
+
const {
|
|
34
|
+
game,
|
|
35
|
+
defaultCombination,
|
|
36
|
+
combinationCursor
|
|
37
|
+
} = storeToRefs(store);
|
|
38
|
+
|
|
39
|
+
const locationFeatures = imageRef;
|
|
40
|
+
const locationImageOriginalWidth = new Map<string, number>();
|
|
41
|
+
const featureImageOriginalDimensions = new Map<string, [number, number]>();
|
|
42
|
+
const areaOriginalCoordinates = new Map<string, string>();
|
|
43
|
+
const factor = ref(1);
|
|
44
|
+
const locationId = computed(() => game.value.currentLocation.id);
|
|
45
|
+
const combinationPicture = computed(() => game.value.combinations.activeCombination?.selectedCombinationAction?.picture ?? defaultCombination.value?.picture);
|
|
46
|
+
|
|
47
|
+
const calculateFactor = () => {
|
|
48
|
+
if (!locationFeatures.value) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const mainImage = locationFeatures.value.querySelector('img');
|
|
53
|
+
factor.value = mainImage.width / locationImageOriginalWidth.get(game.value.currentLocation.id);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
window.onresize = () => {
|
|
57
|
+
const oldFactor = factor.value;
|
|
58
|
+
calculateFactor();
|
|
59
|
+
|
|
60
|
+
if (factor.value !== oldFactor) {
|
|
61
|
+
prepareFeatures();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
onUpdated(() => {
|
|
66
|
+
prepareFeatures();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
watch(() => game.value.combinations.activeCombination, () => setCombinationSymbols());
|
|
70
|
+
|
|
71
|
+
const initFeatures = () => {
|
|
72
|
+
const mainImage = locationFeatures.value?.querySelector('img');
|
|
73
|
+
|
|
74
|
+
if (!locationImageOriginalWidth.has(locationId.value)) {
|
|
75
|
+
locationImageOriginalWidth.set(locationId.value, mainImage.naturalWidth);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
calculateFactor();
|
|
79
|
+
prepareFeatures();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const prepareFeatures = () => {
|
|
83
|
+
if (!locationFeatures.value) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const locationImages = Array.from(locationFeatures.value.querySelectorAll('img.feature-picture') ?? []) as HTMLImageElement[];
|
|
88
|
+
const loadedImages = prepareLoadedImages(locationImages);
|
|
89
|
+
const allPromises = loadedImages.map(i => i.loadPromise);
|
|
90
|
+
|
|
91
|
+
Promise.all(allPromises).then(() => {
|
|
92
|
+
// Resize item images
|
|
93
|
+
loadedImages.map(l => l.element).forEach(i => {
|
|
94
|
+
const featureId = i.id.split('-')[1];
|
|
95
|
+
const imageKey = `${locationId.value}-${featureId}`;
|
|
96
|
+
|
|
97
|
+
if (!featureImageOriginalDimensions.has(imageKey)) {
|
|
98
|
+
featureImageOriginalDimensions.set(imageKey, [i.naturalWidth, i.naturalHeight]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const originalDimensions = featureImageOriginalDimensions.get(imageKey);
|
|
102
|
+
i.width = i.dataset.spriteWidth ? Number.parseInt(i.dataset.spriteWidth) * factor.value : Math.round(originalDimensions[0] * factor.value);
|
|
103
|
+
i.height = i.dataset.spriteHeight ? Number.parseInt(i.dataset.spriteHeight) * factor.value : Math.round(originalDimensions[1] * factor.value);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Reposition areas and images for features and add symbols for active combination.
|
|
107
|
+
const areas = Array.from(locationFeatures.value.querySelectorAll('area'));
|
|
108
|
+
|
|
109
|
+
areas.forEach(a => {
|
|
110
|
+
const featureId = a.id.split('-')[2];
|
|
111
|
+
const areaKey = `${locationId.value}-${featureId}`;
|
|
112
|
+
|
|
113
|
+
if (!areaOriginalCoordinates.has(areaKey)) {
|
|
114
|
+
areaOriginalCoordinates.set(areaKey, a.coords);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const originalCoords = areaOriginalCoordinates.get(areaKey);
|
|
118
|
+
const calculatedCoords = originalCoords.split(',').map(c => Math.round(parseInt(c.trim()) * factor.value));
|
|
119
|
+
a.coords = calculatedCoords.join(',');
|
|
120
|
+
|
|
121
|
+
// Calculate the center of the area to place a symbol later on.
|
|
122
|
+
let totalX = 0, totalY = 0;
|
|
123
|
+
|
|
124
|
+
calculatedCoords.forEach((c, i) => {
|
|
125
|
+
(i + 1) % 2 !== 0 ? totalX += c : totalY += c;
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const avgX = Math.round(totalX / (calculatedCoords.length / 2));
|
|
129
|
+
const avgY = Math.round(totalY / (calculatedCoords.length / 2));
|
|
130
|
+
a.dataset.imageCoords = `${avgX},${avgY}`;
|
|
131
|
+
positionFeatureImage(featureId, avgX, avgY);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// We need a timeout here to allow the DOM to update so we can get the updated coordinates for
|
|
135
|
+
// the symbols from the area data attributes.
|
|
136
|
+
setTimeout(() => {
|
|
137
|
+
setCombinationSymbols();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const positionFeatureImage = (featureId: string, x: number, y: number) => {
|
|
143
|
+
const feature = game.value.currentLocation.features.get(featureId);
|
|
144
|
+
|
|
145
|
+
if (!feature?.picture && !feature?.animation) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const featureImage = Array.from(locationFeatures.value.querySelectorAll('img.feature-picture'))
|
|
150
|
+
.find(a => a.id.split('-')[1] === featureId) as HTMLImageElement;
|
|
151
|
+
|
|
152
|
+
if (!featureImage) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const featureHeight = feature.animation ? feature.animation.height * factor.value : featureImage.height;
|
|
157
|
+
const featureWidth = feature.animation ? feature.animation.width * factor.value : featureImage.width;
|
|
158
|
+
const top = Math.round(y - featureHeight / 2);
|
|
159
|
+
const left = Math.round(x - featureWidth / 2);
|
|
160
|
+
featureImage.style.top = top + 'px';
|
|
161
|
+
featureImage.style.left = left + 'px';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const setCombinationSymbols = () => {
|
|
165
|
+
if (!isTouchDevice) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const areas = Array.from(locationFeatures.value?.querySelectorAll('area'));
|
|
170
|
+
const existingSymbols = Array.from(imageRef.value?.querySelectorAll('.combination-symbol'));
|
|
171
|
+
|
|
172
|
+
existingSymbols?.forEach(s => {
|
|
173
|
+
const symbolImage = s as HTMLImageElement;
|
|
174
|
+
symbolImage.onclick = null;
|
|
175
|
+
imageRef.value.removeChild(symbolImage);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (!combinationPicture.value) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
areas?.forEach(a => {
|
|
183
|
+
const coords = a.dataset.imageCoords?.split(',').map(c => parseInt(c));
|
|
184
|
+
|
|
185
|
+
if (!coords || !coords.length) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const featureId = a.id.split('-')[2];
|
|
190
|
+
const feature = game.value.currentLocation.features.get(featureId);
|
|
191
|
+
|
|
192
|
+
if (!feature || feature.interactive === false) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const image = document.createElement('img');
|
|
197
|
+
image.src = `resources/${combinationPicture.value}`;
|
|
198
|
+
const imageWidth = Math.round(combinationCursor.value.dimensions.width * factor.value);
|
|
199
|
+
const imageHeight = Math.round(combinationCursor.value.dimensions.height * factor.value);
|
|
200
|
+
const imagePosX = Math.round(coords[0] - imageWidth / 2);
|
|
201
|
+
const imagePosY = Math.round(coords[1] - imageHeight / 2);
|
|
202
|
+
|
|
203
|
+
image.style.position = 'absolute';
|
|
204
|
+
image.style.width = imageWidth + 'px';
|
|
205
|
+
image.style.height = imageHeight + 'px';
|
|
206
|
+
image.style.top = `${imagePosY}px`;
|
|
207
|
+
image.style.left = `${imagePosX}px`;
|
|
208
|
+
image.classList.add('combination-symbol');
|
|
209
|
+
image.onclick = () => game.value.combinations.tryCombine(feature);
|
|
210
|
+
imageRef.value.appendChild(image);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
locationFeatures,
|
|
216
|
+
factor,
|
|
217
|
+
initFeatures,
|
|
218
|
+
prepareFeatures
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useCustomCursor } from './CustomCursor';
|
|
2
|
+
import { useLocationMap } from './LocationMap';
|
|
3
|
+
import { usePlayStateWatch } from './playStateWatch';
|
|
4
|
+
import { useSound } from './Sound';
|
|
5
|
+
import { useTextFeatures } from './TextFeatures';
|
|
6
|
+
import { useVisualFeatures } from './VisualFeatures';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
useCustomCursor,
|
|
10
|
+
useLocationMap,
|
|
11
|
+
usePlayStateWatch,
|
|
12
|
+
useSound,
|
|
13
|
+
useTextFeatures,
|
|
14
|
+
useVisualFeatures
|
|
15
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Ref} from "vue";
|
|
2
|
+
import {useStateStore} from "ui/StateStore";
|
|
3
|
+
import {storeToRefs} from "pinia";
|
|
4
|
+
import {PlayState} from 'storyScript';
|
|
5
|
+
|
|
6
|
+
const saveStates = [PlayState.Combat, PlayState.Conversation, PlayState.Trade];
|
|
7
|
+
|
|
8
|
+
export function usePlayStateWatch(uiRoot: Ref<HTMLElement>) {
|
|
9
|
+
const rootElement = uiRoot;
|
|
10
|
+
const store = useStateStore();
|
|
11
|
+
const {game} = storeToRefs(store);
|
|
12
|
+
const {gameService, dataService} = store.services;
|
|
13
|
+
|
|
14
|
+
gameService.watchPlayState((_, newState, oldState) => {
|
|
15
|
+
stopAutoplay();
|
|
16
|
+
|
|
17
|
+
if (newState === null && saveStates.includes(oldState)) {
|
|
18
|
+
// Save the game after finishing conversations, trade and combat.
|
|
19
|
+
dataService.saveGame(game.value);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const stopAutoplay = () => {
|
|
24
|
+
if (!rootElement.value) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const mediaElements = rootElement.value.querySelectorAll('audio:not(.storyscript-player), video:not(.storyscript-player)');
|
|
29
|
+
mediaElements.forEach((m: Element) => (m as HTMLMediaElement).pause());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import {defineStore} from "pinia";
|
|
2
|
+
import {App, computed, Ref, ref} from 'vue';
|
|
3
|
+
|
|
4
|
+
import {ServiceFactory} from "src/Engine/ServiceFactory";
|
|
5
|
+
import {Error} from "ui/error";
|
|
6
|
+
import {isDevelopment} from 'src/constants';
|
|
7
|
+
import {
|
|
8
|
+
ActionType,
|
|
9
|
+
IAction,
|
|
10
|
+
ICharacter,
|
|
11
|
+
ICombinationAction,
|
|
12
|
+
ICompiledLocation,
|
|
13
|
+
ICustomCursor,
|
|
14
|
+
IGame,
|
|
15
|
+
IInterfaceTexts,
|
|
16
|
+
IPerson,
|
|
17
|
+
IRules,
|
|
18
|
+
ITrade
|
|
19
|
+
} from "src/Engine";
|
|
20
|
+
import {
|
|
21
|
+
IAutoplayService,
|
|
22
|
+
ICharacterService,
|
|
23
|
+
ICombatService,
|
|
24
|
+
ICombinationService,
|
|
25
|
+
ICommandService,
|
|
26
|
+
IConversationService,
|
|
27
|
+
IDataService,
|
|
28
|
+
IGameService,
|
|
29
|
+
IItemService,
|
|
30
|
+
ISoundService,
|
|
31
|
+
ITradeService
|
|
32
|
+
} from "src/Engine/Interfaces/services";
|
|
33
|
+
|
|
34
|
+
export const useStateStore = defineStore('appState', () => {
|
|
35
|
+
let serviceFactory: ServiceFactory;
|
|
36
|
+
|
|
37
|
+
const error = ref<Error>(null);
|
|
38
|
+
const availableLocations = ref<{ id: string, name: string }[]>();
|
|
39
|
+
|
|
40
|
+
const game = ref<IGame>(<IGame>{});
|
|
41
|
+
|
|
42
|
+
const useBackpack = ref(false);
|
|
43
|
+
const useGround = ref(false);
|
|
44
|
+
const useEquipment = ref(false);
|
|
45
|
+
const useCharacterSheet = ref(false);
|
|
46
|
+
const useQuests = ref(false);
|
|
47
|
+
|
|
48
|
+
const enemiesPresent = computed(() => game.value.currentLocation?.enemies.filter(e => !e.inactive).length > 0);
|
|
49
|
+
const activePersons = computed(() => game.value.currentLocation?.persons.filter(e => !e.inactive) || []);
|
|
50
|
+
const activeEnemies = computed(() => game.value.currentLocation?.enemies.filter(e => !e.inactive) || []);
|
|
51
|
+
const activeItems = computed(() => game.value.currentLocation?.items.filter(e => !e.inactive) || []);
|
|
52
|
+
const activeActions = computed(() => game.value.currentLocation?.actions.filter(i => !i[1].inactive) || []);
|
|
53
|
+
const activeDestinations = computed(() => game.value.currentLocation?.destinations.filter(e => !e.inactive) || []);
|
|
54
|
+
|
|
55
|
+
const defaultCombination = ref<ICombinationAction>(null);
|
|
56
|
+
const customCursor = ref<ICustomCursor>(null);
|
|
57
|
+
const combinationCursor = ref<ICustomCursor>(null);
|
|
58
|
+
|
|
59
|
+
const services = {
|
|
60
|
+
soundService: <ISoundService>null,
|
|
61
|
+
itemService: <IItemService>null,
|
|
62
|
+
combatService: <ICombatService>null,
|
|
63
|
+
characterService: <ICharacterService>null,
|
|
64
|
+
combinationService: <ICombinationService>null,
|
|
65
|
+
gameService: <IGameService>null,
|
|
66
|
+
conversationService: <IConversationService>null,
|
|
67
|
+
tradeService: <ITradeService>null,
|
|
68
|
+
dataService: <IDataService>null,
|
|
69
|
+
autoplayService: <IAutoplayService>null,
|
|
70
|
+
commandService: <ICommandService>null,
|
|
71
|
+
texts: <IInterfaceTexts>null,
|
|
72
|
+
rules: <IRules>null
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const initErrorHandling = (app: App<Element>) => {
|
|
76
|
+
addEventListener("error", event => {
|
|
77
|
+
error.value = {message: event.message, stackTrace: event.error.stack};
|
|
78
|
+
event.stopPropagation();
|
|
79
|
+
});
|
|
80
|
+
addEventListener("unhandledrejection", event => {
|
|
81
|
+
error.value = {message: event.reason.message, stackTrace: event.reason.stack};
|
|
82
|
+
event.stopPropagation();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (!isDevelopment) {
|
|
86
|
+
app.config.errorHandler = (e: any, vm, info) => error.value = {
|
|
87
|
+
message: e.message,
|
|
88
|
+
info: info,
|
|
89
|
+
stackTrace: e.stack
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const setStoreData = (factory: ServiceFactory) => {
|
|
95
|
+
serviceFactory = factory;
|
|
96
|
+
|
|
97
|
+
// THIS LINE IS CRUCIAL! It ensures the proxy object created by Vue is used throughout the application.
|
|
98
|
+
// Without this, reactivity doesn't work!
|
|
99
|
+
serviceFactory.init(game.value);
|
|
100
|
+
|
|
101
|
+
services.texts = serviceFactory.GetTexts();
|
|
102
|
+
services.rules = serviceFactory.GetRules();
|
|
103
|
+
services.soundService = serviceFactory.GetSoundService();
|
|
104
|
+
services.itemService = serviceFactory.GetItemService();
|
|
105
|
+
services.combatService = serviceFactory.GetCombatService();
|
|
106
|
+
services.characterService = serviceFactory.GetCharacterService();
|
|
107
|
+
services.combinationService = serviceFactory.GetCombinationService();
|
|
108
|
+
services.gameService = serviceFactory.GetGameService();
|
|
109
|
+
services.conversationService = serviceFactory.GetConversationService();
|
|
110
|
+
services.tradeService = serviceFactory.GetTradeService();
|
|
111
|
+
services.dataService = serviceFactory.GetDataService();
|
|
112
|
+
services.autoplayService = serviceFactory.GetAutoplayService();
|
|
113
|
+
services.commandService = serviceFactory.GetCommandService();
|
|
114
|
+
availableLocations.value = serviceFactory.AvailableLocations.sort((a, b) => a.name.localeCompare(b.name));
|
|
115
|
+
|
|
116
|
+
initCombinations();
|
|
117
|
+
|
|
118
|
+
if (services.rules.setup?.customCursorImage) {
|
|
119
|
+
initCustomCursor(services.rules.setup.customCursorImage, customCursor)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const setActiveCharacter = (character: ICharacter) => {
|
|
124
|
+
game.value.activeCharacter = character;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const trade = (location: ICompiledLocation, trade: IPerson | ITrade): boolean => {
|
|
128
|
+
const locationTrade = <ITrade>trade;
|
|
129
|
+
|
|
130
|
+
if (locationTrade && !(<any>locationTrade).type && Array.isArray(locationTrade)) {
|
|
131
|
+
trade = location.trade.find(t => t.id === locationTrade[0]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
services.tradeService.trade(trade);
|
|
135
|
+
|
|
136
|
+
// Return true to keep the action button for trade locations.
|
|
137
|
+
return true;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const showEquipment = (character: ICharacter): boolean =>
|
|
141
|
+
useEquipment
|
|
142
|
+
&& character?.equipment
|
|
143
|
+
&& Object.keys(character.equipment)
|
|
144
|
+
.some(k => (<any>character.equipment)[k] !== undefined);
|
|
145
|
+
|
|
146
|
+
const showDescription = (type: string, item: any, title: string): void => {
|
|
147
|
+
game.value.currentDescription = {title: title, type: type, item: item};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const startCombat = (location: ICompiledLocation, person?: IPerson): void => {
|
|
151
|
+
if (person) {
|
|
152
|
+
// The person becomes an enemy when attacked!
|
|
153
|
+
location.persons.delete(person);
|
|
154
|
+
location.enemies.add(person);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
services.combatService.initCombat();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const getButtonClass = (action: [string, IAction]): string => {
|
|
161
|
+
const type = action[1].actionType || ActionType.Regular;
|
|
162
|
+
let buttonClass = 'btn-';
|
|
163
|
+
|
|
164
|
+
switch (type) {
|
|
165
|
+
case ActionType.Regular:
|
|
166
|
+
buttonClass += 'info'
|
|
167
|
+
break;
|
|
168
|
+
case ActionType.Check:
|
|
169
|
+
buttonClass += 'warning';
|
|
170
|
+
break;
|
|
171
|
+
case ActionType.Combat:
|
|
172
|
+
buttonClass += 'danger';
|
|
173
|
+
break;
|
|
174
|
+
case ActionType.Trade:
|
|
175
|
+
buttonClass += 'secondary';
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return buttonClass;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const initCombinations = () => {
|
|
183
|
+
const combinations = services.rules.combinations;
|
|
184
|
+
|
|
185
|
+
if (!combinations) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
defaultCombination.value = combinations.combinationActions.find(c => c.isDefault);
|
|
190
|
+
const defaultCombinationSymbol = combinations.combinationActions.find(c => c.picture)?.picture?.toLowerCase();
|
|
191
|
+
|
|
192
|
+
if (defaultCombinationSymbol) {
|
|
193
|
+
initCustomCursor(defaultCombinationSymbol, combinationCursor, 'default.png');
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const initCustomCursor = (cursorImage: string, cursorRef: Ref<ICustomCursor>, placeholder?: string): void => {
|
|
198
|
+
const image = document.createElement('img');
|
|
199
|
+
image.src = `resources/${cursorImage}`;
|
|
200
|
+
image.onload = () => {
|
|
201
|
+
cursorRef.value = {
|
|
202
|
+
image: cursorImage,
|
|
203
|
+
dimensions: {width: image.naturalWidth, height: image.naturalHeight},
|
|
204
|
+
style: `url(resources/${placeholder ?? cursorImage}) ${image.naturalWidth / 2} ${image.naturalHeight / 2}, auto`
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
error,
|
|
211
|
+
game,
|
|
212
|
+
useGround,
|
|
213
|
+
useBackpack,
|
|
214
|
+
useEquipment,
|
|
215
|
+
useCharacterSheet,
|
|
216
|
+
useQuests,
|
|
217
|
+
services,
|
|
218
|
+
availableLocations,
|
|
219
|
+
enemiesPresent,
|
|
220
|
+
activePersons,
|
|
221
|
+
activeEnemies,
|
|
222
|
+
activeItems,
|
|
223
|
+
activeActions,
|
|
224
|
+
activeDestinations,
|
|
225
|
+
defaultCombination,
|
|
226
|
+
combinationCursor,
|
|
227
|
+
customCursor,
|
|
228
|
+
initErrorHandling,
|
|
229
|
+
setStoreData,
|
|
230
|
+
setActiveCharacter,
|
|
231
|
+
showEquipment,
|
|
232
|
+
showDescription,
|
|
233
|
+
getButtonClass,
|
|
234
|
+
trade,
|
|
235
|
+
startCombat
|
|
236
|
+
}
|
|
237
|
+
});
|
package/src/UI/error.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {entityTypeRegex, IDefinitions, IGame} from 'storyScript';
|
|
2
|
+
import {parseHtmlDocumentFromString} from "src/Engine/utilityFunctions";
|
|
3
|
+
|
|
4
|
+
export function getDefinitions(assets: Record<string, unknown>){
|
|
5
|
+
const definitions = <IDefinitions>{};
|
|
6
|
+
|
|
7
|
+
// Loop over all found files to register the assets with the proper type.
|
|
8
|
+
for (const path in assets) {
|
|
9
|
+
const asset = assets[path];
|
|
10
|
+
const entityType = entityTypeRegex.exec(path)?.[0];
|
|
11
|
+
|
|
12
|
+
if (!entityType) {
|
|
13
|
+
throw new Error(`'${path}' is not a valid entity type path!`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const property = Object.getOwnPropertyNames(asset)[0];
|
|
17
|
+
const entityFunc = asset[property];
|
|
18
|
+
|
|
19
|
+
// Add the entity function to the definitions object for creating entities at run-time.
|
|
20
|
+
definitions[entityType] = definitions[entityType] || [];
|
|
21
|
+
|
|
22
|
+
if (definitions[entityType].indexOf(entityFunc) === -1) {
|
|
23
|
+
definitions[entityType].push(entityFunc);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return definitions;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function checkAutoplay(game: IGame, value: string) {
|
|
31
|
+
if (!value) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const htmlDocumentFromString = parseHtmlDocumentFromString(value).body;
|
|
36
|
+
value = htmlDocumentFromString.innerHTML;
|
|
37
|
+
value = checkAutoplayProperties(value, htmlDocumentFromString.getElementsByTagName('audio'), game.sounds.playedAudio);
|
|
38
|
+
value = checkAutoplayProperties(value, htmlDocumentFromString.getElementsByTagName('video'), game.sounds.playedAudio);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const autoplayAttribute = 'autoplay';
|
|
43
|
+
const sourceAttribute = 'src';
|
|
44
|
+
|
|
45
|
+
function checkAutoplayProperties(value: string, elements: HTMLCollectionOf<HTMLElement>, playedAudio: string[]) {
|
|
46
|
+
Array.from(elements).forEach(e => {
|
|
47
|
+
const originalText = e.outerHTML;
|
|
48
|
+
const source = e.getElementsByTagName('source')[0]?.getAttribute(sourceAttribute)?.toLowerCase()
|
|
49
|
+
?? e.getAttribute(sourceAttribute)?.toLowerCase();
|
|
50
|
+
|
|
51
|
+
if (originalText && source && e.hasAttribute(autoplayAttribute)) {
|
|
52
|
+
if (playedAudio.indexOf(source) < 0) {
|
|
53
|
+
playedAudio.push(source);
|
|
54
|
+
} else {
|
|
55
|
+
e.removeAttribute(autoplayAttribute);
|
|
56
|
+
value = value.replace(originalText, e.outerHTML);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return value;
|
|
62
|
+
}
|
package/src/UI/index.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {useStateStore} from "./StateStore";
|
|
2
|
+
import {startup} from "./startup";
|
|
3
|
+
import { default as ModalDialog } from "./Components/Common/ModalDialog.vue";
|
|
4
|
+
import {checkAutoplay} from "ui/helpers";
|
|
5
|
+
|
|
6
|
+
export * from './Composables'
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
useStateStore,
|
|
10
|
+
ModalDialog,
|
|
11
|
+
startup,
|
|
12
|
+
checkAutoplay
|
|
13
|
+
}
|
package/src/UI/main.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addArrayExtensions,
|
|
3
|
+
addFunctionExtensions,
|
|
4
|
+
startup
|
|
5
|
+
} from "storyScript";
|
|
6
|
+
import 'game/ui/styles/game.css'
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
import('storyscript/styles');
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
import {Rules} from 'game/rules';
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
import {CustomTexts} from 'game/customTexts';
|
|
13
|
+
import {currentGameName} from "../../currentGameName";
|
|
14
|
+
|
|
15
|
+
addFunctionExtensions();
|
|
16
|
+
addArrayExtensions();
|
|
17
|
+
const assets = importAssets();
|
|
18
|
+
const components = getComponents();
|
|
19
|
+
|
|
20
|
+
startup(components, assets, currentGameName, Rules(), CustomTexts());
|
|
21
|
+
|
|
22
|
+
export function importAssets(): Record<string, unknown> {
|
|
23
|
+
return import.meta.glob([
|
|
24
|
+
'game/actions/**/*.ts',
|
|
25
|
+
'game/features/**/*.ts',
|
|
26
|
+
'game/items/**/*.ts',
|
|
27
|
+
'game/enemies/**/*.ts',
|
|
28
|
+
'game/persons/**/*.ts',
|
|
29
|
+
'game/quests/**/*.ts',
|
|
30
|
+
'game/locations/**/*.ts',
|
|
31
|
+
'game/maps/**/*.ts'
|
|
32
|
+
], {eager: true, caseSensitive: false});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function getComponents(): Map<string, any> {
|
|
36
|
+
const combinedTemplates = new Map<string, any>();
|
|
37
|
+
const defaultTemplates = import.meta.glob('./Components/**/*.vue', {eager: true, caseSensitive: false});
|
|
38
|
+
const customTemplates = import.meta.glob('game/ui/**/*.vue', {eager: true, caseSensitive: false});
|
|
39
|
+
|
|
40
|
+
Object.keys(customTemplates).forEach(t => {
|
|
41
|
+
const key = getKey(t);
|
|
42
|
+
|
|
43
|
+
if (key) {
|
|
44
|
+
combinedTemplates.set(getKey(t), customTemplates[t]);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
Object.keys(defaultTemplates).forEach(t => {
|
|
49
|
+
const key = getKey(t);
|
|
50
|
+
|
|
51
|
+
if (key && !combinedTemplates.has(key)) {
|
|
52
|
+
combinedTemplates.set(key, defaultTemplates[t]);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return combinedTemplates;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function getKey(path: string) {
|
|
60
|
+
const capture = path.match(/([a-zA-Z]{1,}).vue$/);
|
|
61
|
+
return capture ? capture[1] : null;
|
|
62
|
+
}
|