@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,315 @@
|
|
|
1
|
+
import {useStateStore} from "ui/StateStore";
|
|
2
|
+
import {storeToRefs} from "pinia";
|
|
3
|
+
import {computed, onMounted, onUpdated, Ref, ref, watch} from "vue";
|
|
4
|
+
import {IMap} from 'storyScript';
|
|
5
|
+
import {isTouchDevice} from 'src/constants';
|
|
6
|
+
|
|
7
|
+
export function useLocationMap(mapImageRef: Ref<HTMLImageElement>, mapDialogRef: Ref<HTMLDialogElement>) {
|
|
8
|
+
const visible: string = 'visible';
|
|
9
|
+
const hidden: string = 'hidden';
|
|
10
|
+
const reachable: string = 'reachable';
|
|
11
|
+
const visited: string = 'visited';
|
|
12
|
+
const labelClass: string = 'map-location-label';
|
|
13
|
+
const imageClass: string = 'map-location-image';
|
|
14
|
+
|
|
15
|
+
const store = useStateStore();
|
|
16
|
+
const {game} = storeToRefs(store);
|
|
17
|
+
const {texts} = store.services;
|
|
18
|
+
|
|
19
|
+
const map = computed(() => game.value.currentMap);
|
|
20
|
+
const location = computed(() => game.value.currentLocation);
|
|
21
|
+
|
|
22
|
+
const fullScreen = ref(false);
|
|
23
|
+
const firstShowFullScreen = ref(true);
|
|
24
|
+
const touchMarkersVisible = ref(false);
|
|
25
|
+
const mapDialog = mapDialogRef;
|
|
26
|
+
const currentMap = mapImageRef;
|
|
27
|
+
const currentFullScreenMap = ref<HTMLImageElement>(null);
|
|
28
|
+
|
|
29
|
+
watch(() => location.value, () => {
|
|
30
|
+
navigateMap(map.value, currentMap.value, false);
|
|
31
|
+
|
|
32
|
+
if (fullScreen.value) {
|
|
33
|
+
navigateMap(map.value, currentFullScreenMap.value, false);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
onMounted(() => {
|
|
38
|
+
prepareMap(map.value, false);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
onUpdated(() => {
|
|
42
|
+
prepareMap(map.value, true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const toggleTouchMarkersVisible = () => {
|
|
46
|
+
if (!isTouchDevice) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
touchMarkersVisible.value = !touchMarkersVisible.value;
|
|
51
|
+
|
|
52
|
+
if (map.value.showMarkersOnKeyPress) {
|
|
53
|
+
const mapContainer = (fullScreen.value ? currentFullScreenMap.value : currentMap.value).parentElement;
|
|
54
|
+
const labelElements = mapContainer.getElementsByClassName(labelClass);
|
|
55
|
+
const markerElements = mapContainer.getElementsByClassName(imageClass);
|
|
56
|
+
setMarkerVisibility(labelElements, markerElements, touchMarkersVisible.value ? visible : hidden);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function toggleFullScreen() {
|
|
61
|
+
fullScreen.value = !fullScreen.value;
|
|
62
|
+
|
|
63
|
+
if (fullScreen.value) {
|
|
64
|
+
mapDialog.value.showModal();
|
|
65
|
+
navigateMap(map.value, currentFullScreenMap.value, firstShowFullScreen.value);
|
|
66
|
+
firstShowFullScreen.value = false;
|
|
67
|
+
currentFullScreenMap.value.focus();
|
|
68
|
+
} else {
|
|
69
|
+
mapDialog.value.close();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function prepareMap(newMap: IMap, cleanup: boolean) {
|
|
74
|
+
if (!newMap) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const mapContainer = currentMap.value.parentElement;
|
|
79
|
+
|
|
80
|
+
if (cleanup) {
|
|
81
|
+
firstShowFullScreen.value = true;
|
|
82
|
+
currentMap.value.onload = null;
|
|
83
|
+
mapContainer.onkeydown = null;
|
|
84
|
+
mapContainer.onkeyup = null;
|
|
85
|
+
const labelElements = Array.prototype.slice.call(mapContainer.getElementsByClassName(labelClass));
|
|
86
|
+
labelElements.forEach(l => l.remove());
|
|
87
|
+
const markerElements = Array.prototype.slice.call(mapContainer.getElementsByClassName(imageClass));
|
|
88
|
+
markerElements.forEach(l => l.remove());
|
|
89
|
+
mapDialog.value.onkeydown = null;
|
|
90
|
+
mapDialog.value.onkeyup = null;
|
|
91
|
+
mapDialog.value.replaceChildren();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (newMap.toggleFullScreen === true) {
|
|
95
|
+
let fullScreenMap = getMapElement(mapDialog.value);
|
|
96
|
+
|
|
97
|
+
if (!fullScreenMap) {
|
|
98
|
+
for (const n in Object.keys(mapContainer.children)) {
|
|
99
|
+
const child = mapContainer.children[n];
|
|
100
|
+
mapDialog.value.appendChild(child.cloneNode(true));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const closeToggle = mapDialog.value.getElementsByClassName('map-full-screen-toggle')[0] as HTMLSpanElement;
|
|
104
|
+
closeToggle.innerText = texts.closeFullScreenMap;
|
|
105
|
+
closeToggle.onclick = () => toggleFullScreen();
|
|
106
|
+
|
|
107
|
+
const showMarkersToggle = (mapDialog.value.querySelector('.show-marker-instructions') as HTMLElement);
|
|
108
|
+
showMarkersToggle.onclick = () => toggleTouchMarkersVisible();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
currentFullScreenMap.value = getMapElement(mapDialog.value);
|
|
112
|
+
initMap(currentFullScreenMap.value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
initMap(currentMap.value);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function initMap(mapElement: HTMLElement) {
|
|
119
|
+
if (!map) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
mapElement.onkeydown = null;
|
|
124
|
+
mapElement.onkeyup = null;
|
|
125
|
+
|
|
126
|
+
map.value.locations.forEach(l => {
|
|
127
|
+
const textLabel = l.markerImage ? null : l.textLabel ?? (map.value.locationNamesAsTextMarkers ? game.value.locations[l.location as string].name : null);
|
|
128
|
+
const id = l.location as string;
|
|
129
|
+
|
|
130
|
+
if (textLabel) {
|
|
131
|
+
l.markerElement = addElement(mapElement, l.coords, id, labelClass, 'span', textLabel);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const markerImage = l.markerImage ?? map.value.locationMarkerImage;
|
|
135
|
+
|
|
136
|
+
if (markerImage) {
|
|
137
|
+
l.markerElement = addElement(mapElement, l.coords, id, imageClass, 'img', markerImage);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (map.value.showMarkersOnKeyPress) {
|
|
142
|
+
const mapContainer = mapElement.parentElement;
|
|
143
|
+
const labelElements = mapElement.parentElement.getElementsByClassName(labelClass);
|
|
144
|
+
const markerElements = mapElement.parentElement.getElementsByClassName(imageClass);
|
|
145
|
+
|
|
146
|
+
mapContainer.onkeydown = e => {
|
|
147
|
+
if (e.key === map.value.showMarkersOnKeyPress) {
|
|
148
|
+
setMarkerVisibility(labelElements, markerElements, visible);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
mapContainer.onkeyup = e => {
|
|
153
|
+
if (e.key === map.value.showMarkersOnKeyPress) {
|
|
154
|
+
setMarkerVisibility(labelElements, markerElements, hidden);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function showMap() {
|
|
161
|
+
navigateMap(map.value, currentMap.value, true);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function navigateMap(map: IMap, mapElement: HTMLElement, show: boolean) {
|
|
165
|
+
const parentElement = mapElement.parentElement;
|
|
166
|
+
const coordString = map.locations.find(l => l.location === location.value.id)?.coords;
|
|
167
|
+
const avatar = parentElement.getElementsByClassName('avatar-image')[0] as HTMLImageElement;
|
|
168
|
+
let mapMargins: { x: number, y: number };
|
|
169
|
+
|
|
170
|
+
if (coordString) {
|
|
171
|
+
const coords = getCoords(coordString);
|
|
172
|
+
mapMargins = {
|
|
173
|
+
x: getMapMargin(mapElement, coords.x, 'width'),
|
|
174
|
+
y: getMapMargin(mapElement, coords.y, 'height')
|
|
175
|
+
};
|
|
176
|
+
mapElement.style.marginLeft = `-${mapMargins.x}px`;
|
|
177
|
+
mapElement.style.marginTop = `-${mapMargins.y}px`;
|
|
178
|
+
|
|
179
|
+
if (avatar) {
|
|
180
|
+
const avatarLeft = coords.x - mapMargins.x - avatar.width / 2;
|
|
181
|
+
const avatarTop = coords.y - mapMargins.y - avatar.height / 2;
|
|
182
|
+
setCoordinates(avatar, avatarLeft, avatarTop);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const labelElements = parentElement.getElementsByClassName(labelClass);
|
|
187
|
+
const markerElements = parentElement.getElementsByClassName(imageClass);
|
|
188
|
+
moveMarker(labelElements, mapMargins);
|
|
189
|
+
moveMarker(markerElements, mapMargins);
|
|
190
|
+
|
|
191
|
+
if (show) {
|
|
192
|
+
showElements(avatar, labelElements, markerElements);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
parentElement.focus();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function setCoordinates(element: HTMLElement, left: number, top: number) {
|
|
199
|
+
element.style.top = `${top}px`;
|
|
200
|
+
element.style.left = `${left}px`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function addElement(mapElement: HTMLElement, coordsString: string, location: string, className: string, elementType: string, elementValue: string): HTMLElement {
|
|
204
|
+
const coords = getCoords(coordsString);
|
|
205
|
+
const labelElement = document.createElement("div");
|
|
206
|
+
labelElement.setAttribute("class", className);
|
|
207
|
+
labelElement.style.visibility = hidden;
|
|
208
|
+
labelElement.setAttribute("data-top", coords.x.toString());
|
|
209
|
+
labelElement.setAttribute("data-left", coords.y.toString());
|
|
210
|
+
labelElement.setAttribute("data-locationid", location);
|
|
211
|
+
const valueElement = document.createElement(elementType);
|
|
212
|
+
|
|
213
|
+
if (elementType === 'span') {
|
|
214
|
+
(<HTMLSpanElement>valueElement).innerText = elementValue;
|
|
215
|
+
} else if (elementType === 'img') {
|
|
216
|
+
(<HTMLImageElement>valueElement).src = `resources/${elementValue}`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
labelElement.appendChild(valueElement);
|
|
220
|
+
mapElement.parentElement.appendChild(labelElement);
|
|
221
|
+
return labelElement;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function moveMarker(markerElements: HTMLCollection, mapMargins: { x: number, y: number }) {
|
|
225
|
+
if (!mapMargins) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const n in Object.keys(markerElements)) {
|
|
230
|
+
const markerElement = markerElements[n] as HTMLElement;
|
|
231
|
+
const currentLeft = parseInt(markerElement.dataset.top) - markerElement.clientWidth / 2 - mapMargins.x;
|
|
232
|
+
const currentTop = parseInt(markerElement.dataset.left) - markerElement.clientHeight / 2 - mapMargins.y;
|
|
233
|
+
const locationId = markerElement.dataset.locationid;
|
|
234
|
+
setCoordinates(markerElement, currentLeft, currentTop);
|
|
235
|
+
|
|
236
|
+
const isVisited = game.value.locations.get(locationId)?.hasVisited;
|
|
237
|
+
markerElement.classList.remove(visited);
|
|
238
|
+
|
|
239
|
+
if (isVisited) {
|
|
240
|
+
markerElement.classList.add(visited);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (map.value.clickable === true) {
|
|
244
|
+
const isReachable = location.value.destinations.find(d => d.target === locationId);
|
|
245
|
+
|
|
246
|
+
markerElement.onclick = null;
|
|
247
|
+
markerElement.classList.remove(reachable);
|
|
248
|
+
|
|
249
|
+
if (isReachable) {
|
|
250
|
+
markerElement.classList.add(reachable);
|
|
251
|
+
markerElement.onclick = () => {
|
|
252
|
+
game.value.commands.go(locationId);
|
|
253
|
+
}
|
|
254
|
+
} else if (location.value.id === locationId) {
|
|
255
|
+
markerElement.classList.add(reachable);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function showElements(avatar: HTMLElement, labelElements: HTMLCollection, markerElements: HTMLCollection) {
|
|
262
|
+
setTimeout(() => {
|
|
263
|
+
if (avatar) {
|
|
264
|
+
avatar.style.visibility = visible;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (!map.value.showMarkersOnKeyPress) {
|
|
268
|
+
setMarkerVisibility(labelElements, markerElements, visible);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
}, map.value.transitionTime ?? 1000);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function setMarkerVisibility(labelElements: HTMLCollection, markerElements: HTMLCollection, visibility: string) {
|
|
275
|
+
for (const n in Object.keys(labelElements)) {
|
|
276
|
+
const labelElement = labelElements[n] as HTMLElement;
|
|
277
|
+
labelElement.style.visibility = visibility;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
for (const n in Object.keys(markerElements)) {
|
|
281
|
+
const markerElement = markerElements[n] as HTMLElement;
|
|
282
|
+
markerElement.style.visibility = visibility;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function getCoords(coordString: string) {
|
|
287
|
+
const coords = coordString.split(',');
|
|
288
|
+
const coordLeft = parseInt(coords[0]);
|
|
289
|
+
const coordTop = parseInt(coords[1]);
|
|
290
|
+
return {x: coordLeft, y: coordTop};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function getMapMargin(mapImage: any, coord: number, dimension: string): number {
|
|
294
|
+
const mapContainer = mapImage.parentElement;
|
|
295
|
+
const clientDimension = 'client' + dimension.substring(0, 1).toUpperCase() + dimension.substring(1)
|
|
296
|
+
const mapDimension = mapContainer[clientDimension];
|
|
297
|
+
const viewPortCenter = mapDimension / 2;
|
|
298
|
+
const maxMargin = mapImage[dimension] - mapDimension;
|
|
299
|
+
let mapMargin = coord > viewPortCenter ? coord - viewPortCenter : 0;
|
|
300
|
+
mapMargin = mapMargin > maxMargin ? maxMargin : mapMargin;
|
|
301
|
+
return mapMargin;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getMapElement(parentElement: HTMLElement): HTMLImageElement {
|
|
305
|
+
return parentElement.getElementsByClassName('map-image')[0] as HTMLImageElement;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
map,
|
|
310
|
+
prepareMap,
|
|
311
|
+
showMap,
|
|
312
|
+
toggleFullScreen,
|
|
313
|
+
toggleTouchMarkersVisible
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {useStateStore} from "ui/StateStore";
|
|
2
|
+
import {Ref, ref, watch} from "vue";
|
|
3
|
+
import {storeToRefs} from "pinia";
|
|
4
|
+
|
|
5
|
+
export function useSound(musicPlayerRef: Ref<HTMLAudioElement>) {
|
|
6
|
+
const store = useStateStore();
|
|
7
|
+
const {game} = storeToRefs(store);
|
|
8
|
+
const {rules, soundService} = store.services;
|
|
9
|
+
|
|
10
|
+
const musicPlayer = musicPlayerRef;
|
|
11
|
+
|
|
12
|
+
const canPlay = ref<boolean>(null);
|
|
13
|
+
const fadeInterval = ref<NodeJS.Timeout>(null);
|
|
14
|
+
const fadingMusic = ref(false);
|
|
15
|
+
const currentMusic = ref<string>(null);
|
|
16
|
+
const currentVolume = ref(1);
|
|
17
|
+
|
|
18
|
+
let audioContext: AudioContext;
|
|
19
|
+
const soundQueue: [number, string][] = [];
|
|
20
|
+
|
|
21
|
+
document.addEventListener('click', async () => {
|
|
22
|
+
if (!audioContext) {
|
|
23
|
+
audioContext = new window.AudioContext();
|
|
24
|
+
canPlay.value = true;
|
|
25
|
+
|
|
26
|
+
if (musicPlayer.value) {
|
|
27
|
+
await musicPlayer.value.play();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}, { once: true });
|
|
31
|
+
|
|
32
|
+
watch(musicPlayerRef, (newValue) => {
|
|
33
|
+
if (newValue && canPlay.value === null) {
|
|
34
|
+
canPlay.value = Boolean(audioContext);
|
|
35
|
+
}
|
|
36
|
+
}, { immediate: true });
|
|
37
|
+
|
|
38
|
+
const getSoundQueue = (): [number, string][] => {
|
|
39
|
+
Array.from(game.value.sounds.soundQueue).forEach(e => {
|
|
40
|
+
if (!e[1].playing) {
|
|
41
|
+
soundQueue.push([e[0], e[1].value]);
|
|
42
|
+
e[1].playing = true;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return soundQueue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const getCurrentMusic = (): string => {
|
|
50
|
+
const music = soundService.getCurrentMusic();
|
|
51
|
+
|
|
52
|
+
if (rules.setup.fadeMusicInterval) {
|
|
53
|
+
|
|
54
|
+
if (!currentMusic.value) {
|
|
55
|
+
currentMusic.value = music;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!fadingMusic.value && music != currentMusic.value) {
|
|
59
|
+
fadingMusic.value = true;
|
|
60
|
+
fadeInterval.value = setInterval(() => fade(music), rules.setup.fadeMusicInterval);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return currentMusic.value;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return music;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const soundCompleted = (soundKey: number) => {
|
|
70
|
+
const sound = game.value.sounds.soundQueue.get(soundKey);
|
|
71
|
+
|
|
72
|
+
if (sound) {
|
|
73
|
+
sound.completeCallBack?.();
|
|
74
|
+
game.value.sounds.soundQueue.delete(soundKey);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const queueEntry = soundQueue.find(([k, _]) => soundKey === k);
|
|
78
|
+
|
|
79
|
+
if (!queueEntry) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const index = soundQueue.indexOf(queueEntry);
|
|
84
|
+
|
|
85
|
+
if (index > -1) {
|
|
86
|
+
soundQueue.splice(index, 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const fade = (newMusic: string) => {
|
|
91
|
+
const newVolume = currentVolume.value - 0.1;
|
|
92
|
+
|
|
93
|
+
if (newVolume >= 0) {
|
|
94
|
+
currentVolume.value = newVolume;
|
|
95
|
+
} else {
|
|
96
|
+
clearInterval(fadeInterval.value);
|
|
97
|
+
currentVolume.value = 1;
|
|
98
|
+
currentMusic.value = newMusic;
|
|
99
|
+
fadingMusic.value = false;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
musicPlayer.value.volume = currentVolume.value;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
canPlay,
|
|
107
|
+
getSoundQueue,
|
|
108
|
+
getCurrentMusic,
|
|
109
|
+
soundCompleted
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import {addHtmlSpaces} from "src/Engine/utilityFunctions";
|
|
2
|
+
import {IFeature} from 'storyScript';
|
|
3
|
+
import {useStateStore} from "ui/StateStore";
|
|
4
|
+
import {Ref, watch} from "vue";
|
|
5
|
+
import {storeToRefs} from "pinia";
|
|
6
|
+
import {isTouchDevice} from 'src/constants';
|
|
7
|
+
|
|
8
|
+
export function useTextFeatures(descriptionRef: Ref<HTMLDivElement>) {
|
|
9
|
+
const activeTriggerClass = 'trigger-active';
|
|
10
|
+
|
|
11
|
+
const store = useStateStore();
|
|
12
|
+
const {game} = storeToRefs(store);
|
|
13
|
+
const {combinationService} = store.services;
|
|
14
|
+
|
|
15
|
+
const description = descriptionRef;
|
|
16
|
+
|
|
17
|
+
watch(() => game.value.combinations.activeCombination?.selectedTool, () => {
|
|
18
|
+
refreshFeatures();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const refreshFeatures = () => {
|
|
22
|
+
// Show the text of added features.
|
|
23
|
+
const featureArray = Array.from(description.value?.getElementsByTagName('feature'));
|
|
24
|
+
|
|
25
|
+
if (featureArray.length === 0) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
featureArray.filter(e => e.innerHTML.trim() === '')
|
|
30
|
+
.forEach((e) => {
|
|
31
|
+
const feature = game.value.currentLocation.features.get(e.getAttribute('name'));
|
|
32
|
+
|
|
33
|
+
if (feature) {
|
|
34
|
+
game.value.currentLocation.description = game.value.currentLocation.description.replace(new RegExp('<feature name="' + feature.id + '">\s*<\/feature>', 'i'), '<feature name="' + feature.id + '">' + addHtmlSpaces(feature.description) + '<\/feature>');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Remove the text of deleted features.
|
|
39
|
+
featureArray.filter(e => e.innerHTML.trim() !== '')
|
|
40
|
+
.forEach((e) => {
|
|
41
|
+
const featureName = e.getAttribute('name')?.toLowerCase();
|
|
42
|
+
|
|
43
|
+
if (featureName && game.value.combinations.combinationResult.featuresToRemove.find(f => f === featureName)) {
|
|
44
|
+
e.innerHTML = '';
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
featureArray.forEach((e) => {
|
|
49
|
+
const feature = game.value.currentLocation.features.get(e.getAttribute('name'));
|
|
50
|
+
|
|
51
|
+
if (feature && game.value.combinations.activeCombination?.selectedTool?.id === feature.id) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
e.classList.remove('combine-active-selected', 'combine-selectable', 'feature-cursor');
|
|
56
|
+
e.classList.add('feature-cursor');
|
|
57
|
+
|
|
58
|
+
if (game.value.combinations.activeCombination) {
|
|
59
|
+
e.classList.add('combine-selectable');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const click = (ev: PointerEvent) => {
|
|
65
|
+
const triggerElement = getTriggerElement(ev.target as HTMLElement);
|
|
66
|
+
|
|
67
|
+
if (triggerElement && isTouchDevice) {
|
|
68
|
+
const activate = !triggerElement.classList.contains(activeTriggerClass);
|
|
69
|
+
|
|
70
|
+
Array.from(description.value.querySelectorAll('[data-trigger]')).forEach((el) => {
|
|
71
|
+
toggleTrigger(el as any, false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
toggleTrigger(triggerElement, activate);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const feature = getFeature(ev);
|
|
78
|
+
|
|
79
|
+
if (feature) {
|
|
80
|
+
const result = game.value.combinations.tryCombine(feature);
|
|
81
|
+
const className = combinationService.getCombineClass(feature);
|
|
82
|
+
|
|
83
|
+
if (className) {
|
|
84
|
+
const featureElement = getFeatureElement(ev);
|
|
85
|
+
featureElement.classList.add(className);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (result.success) {
|
|
89
|
+
refreshFeatures();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const mouseOver = (ev: MouseEvent) => {
|
|
95
|
+
if (isTouchDevice) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
toggleTrigger(getTriggerElement(ev?.target as HTMLElement), true);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const mouseOut = (ev: MouseEvent) => {
|
|
103
|
+
if (isTouchDevice) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
toggleTrigger(getTriggerElement(ev?.target as HTMLElement), false);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const toggleTrigger = (element: HTMLElement, active: boolean) => {
|
|
111
|
+
if (!element) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const data = element.dataset
|
|
116
|
+
const event = game.value.currentLocation.triggeredActions?.find(([k, _]) => k === data.trigger)?.[1];
|
|
117
|
+
|
|
118
|
+
if (active) {
|
|
119
|
+
element.classList.add(activeTriggerClass);
|
|
120
|
+
event?.(game.value, active, data);
|
|
121
|
+
} else {
|
|
122
|
+
element.classList.remove(activeTriggerClass);
|
|
123
|
+
event?.(game.value, active, data);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const getTriggerElement = (element: HTMLElement): HTMLElement => {
|
|
128
|
+
return element?.closest('[data-trigger]') as HTMLElement;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const getFeatureElement = (ev: MouseEvent) => {
|
|
132
|
+
return (ev.target as HTMLElement).closest('feature');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const getFeature = (ev: MouseEvent): IFeature => {
|
|
136
|
+
const featureElement = getFeatureElement(ev);
|
|
137
|
+
const featureName = featureElement?.getAttribute('name');
|
|
138
|
+
return featureName ? game.value.currentLocation.features.get(featureName) : null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
description,
|
|
143
|
+
refreshFeatures,
|
|
144
|
+
click,
|
|
145
|
+
mouseOver,
|
|
146
|
+
mouseOut
|
|
147
|
+
}
|
|
148
|
+
}
|