@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,554 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DefaultTexts,
|
|
3
|
+
GameState,
|
|
4
|
+
ICharacterService,
|
|
5
|
+
ICombinable,
|
|
6
|
+
ICombinationService,
|
|
7
|
+
ICombineResult,
|
|
8
|
+
ICreateCharacter,
|
|
9
|
+
IDataService,
|
|
10
|
+
IDemoMode,
|
|
11
|
+
IEquipment,
|
|
12
|
+
IFeature,
|
|
13
|
+
IGame,
|
|
14
|
+
IGameService,
|
|
15
|
+
IInterfaceTexts,
|
|
16
|
+
IItem,
|
|
17
|
+
ILocationService,
|
|
18
|
+
IParty,
|
|
19
|
+
IRules,
|
|
20
|
+
ISaveGame,
|
|
21
|
+
ISoundService,
|
|
22
|
+
PlayState,
|
|
23
|
+
ScoreEntry,
|
|
24
|
+
InitEntityCollection
|
|
25
|
+
} from 'storyScript';
|
|
26
|
+
import {Characters, GameStateSave, HighScores, Items, Quests, SaveGamePrefix} from 'src/constants';
|
|
27
|
+
|
|
28
|
+
export class GameService implements IGameService {
|
|
29
|
+
constructor
|
|
30
|
+
(
|
|
31
|
+
private readonly _dataService: IDataService,
|
|
32
|
+
private readonly _locationService: ILocationService,
|
|
33
|
+
private readonly _characterService: ICharacterService,
|
|
34
|
+
private readonly _combinationService: ICombinationService,
|
|
35
|
+
private readonly _soundService: ISoundService,
|
|
36
|
+
private readonly _rules: IRules,
|
|
37
|
+
private readonly _game: IGame,
|
|
38
|
+
private readonly _texts: IInterfaceTexts,
|
|
39
|
+
) {
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
initDemo = (demoConfig: IDemoMode) => {
|
|
43
|
+
const party = structuredClone(demoConfig.party);
|
|
44
|
+
|
|
45
|
+
this._game.statistics = {};
|
|
46
|
+
this._game.worldProperties = {};
|
|
47
|
+
this._game.locations = null;
|
|
48
|
+
this._game.maps = null;
|
|
49
|
+
this._game.party = party;
|
|
50
|
+
|
|
51
|
+
this._rules.setup?.initGame?.(this._game);
|
|
52
|
+
this.initGame([]);
|
|
53
|
+
this.initTexts();
|
|
54
|
+
this.resume('Start');
|
|
55
|
+
|
|
56
|
+
this._game.autoplay.startDemoMode(demoConfig, () => this.initDemo(demoConfig));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
init = (restart?: boolean, skipIntro?: boolean): void => {
|
|
60
|
+
this._game.started = true;
|
|
61
|
+
|
|
62
|
+
const gameState = this._dataService.load<ISaveGame>(GameStateSave);
|
|
63
|
+
this._game.highScores = this._dataService.load<ScoreEntry[]>(HighScores);
|
|
64
|
+
this._game.party = gameState?.party;
|
|
65
|
+
this._game.locations = gameState?.world;
|
|
66
|
+
this._game.maps = gameState?.maps;
|
|
67
|
+
this._game.worldProperties = gameState?.worldProperties ?? {};
|
|
68
|
+
this._game.statistics = gameState?.statistics ?? this._game.statistics ?? {};
|
|
69
|
+
const playedAudio = gameState?.playedAudio ?? [];
|
|
70
|
+
|
|
71
|
+
if (restart) {
|
|
72
|
+
this._game.statistics = {};
|
|
73
|
+
this._game.worldProperties = {};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this._rules.setup?.initGame?.(this._game);
|
|
77
|
+
this.initGame(playedAudio);
|
|
78
|
+
this.initTexts();
|
|
79
|
+
|
|
80
|
+
// Use the afterSave hook here to combine the initialized world with other saved data.
|
|
81
|
+
if (gameState && this._rules.general?.afterSave) {
|
|
82
|
+
this._rules.general.afterSave(this._game);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!this._game.party && this._rules.setup.intro && !skipIntro) {
|
|
86
|
+
this._game.state = GameState.Intro;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (this._game.party) {
|
|
91
|
+
const locationName = this._game.party?.currentLocationId ?? 'Start';
|
|
92
|
+
this.resume(locationName);
|
|
93
|
+
|
|
94
|
+
if (this._rules.setup.continueGame) {
|
|
95
|
+
this._rules.setup.continueGame(this._game);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const characterSheet = this._rules.character.getCreateCharacterSheet?.();
|
|
102
|
+
const hasCreateCharacterSteps = characterSheet?.steps?.length > 0;
|
|
103
|
+
|
|
104
|
+
this._game.party = <IParty>{
|
|
105
|
+
type: 'party',
|
|
106
|
+
characters: [],
|
|
107
|
+
quests: [],
|
|
108
|
+
score: 0
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
if (!hasCreateCharacterSteps) {
|
|
112
|
+
this.startNewGame(<ICreateCharacter>{});
|
|
113
|
+
} else {
|
|
114
|
+
this._characterService.setupCharacter();
|
|
115
|
+
this._game.state = GameState.CreateCharacter;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
reset = (): void => {
|
|
120
|
+
const emptySave = <ISaveGame>{
|
|
121
|
+
party: this._game.party,
|
|
122
|
+
statistics: this._game.statistics
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
this._dataService.save(GameStateSave, emptySave);
|
|
126
|
+
this._game.locations = null;
|
|
127
|
+
this._game.maps = null;
|
|
128
|
+
this._locationService.init();
|
|
129
|
+
|
|
130
|
+
// Save here to use the before and after save hooks after refreshing the world,
|
|
131
|
+
// if there is a beforeSave hook defined.
|
|
132
|
+
if (this._rules.general?.beforeSave) {
|
|
133
|
+
this._dataService.saveGame(this._game);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (this._game.party?.currentLocationId) {
|
|
137
|
+
this._game.commands.go(this._game.party.currentLocationId, false);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
startNewGame = (characterData: ICreateCharacter): void => {
|
|
142
|
+
this.createCharacter(characterData);
|
|
143
|
+
|
|
144
|
+
if (this._rules.setup.numberOfCharacters > 1 && this._rules.setup.numberOfCharacters > this._game.party.characters.length) {
|
|
145
|
+
this._characterService.setupCharacter();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this._game.party.characters[0].isActiveCharacter = true;
|
|
150
|
+
this._rules.setup.gameStart?.(this._game);
|
|
151
|
+
|
|
152
|
+
if (!this._game.currentLocation) {
|
|
153
|
+
this._game.commands.go('Start', false);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.setInterceptors();
|
|
157
|
+
this._game.state = GameState.Play;
|
|
158
|
+
this._dataService.saveGame(this._game);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
restart = (skipIntro?: boolean): void => {
|
|
162
|
+
this._dataService.remove(GameStateSave);
|
|
163
|
+
this.init(true, skipIntro);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
loadGame = (name: string): void => {
|
|
167
|
+
const saveGame = this._dataService.load<ISaveGame>(SaveGamePrefix + name);
|
|
168
|
+
|
|
169
|
+
if (saveGame) {
|
|
170
|
+
this._game.loading = true;
|
|
171
|
+
this._game.party = saveGame.party;
|
|
172
|
+
this._game.locations = saveGame.world;
|
|
173
|
+
this._game.maps = saveGame.maps;
|
|
174
|
+
this._game.worldProperties = saveGame.worldProperties ?? {};
|
|
175
|
+
this._game.statistics = saveGame.statistics;
|
|
176
|
+
this._game.sounds.playedAudio = saveGame.playedAudio;
|
|
177
|
+
this._locationService.init();
|
|
178
|
+
this._game.currentLocation = this._game.locations.get(saveGame.party.currentLocationId);
|
|
179
|
+
|
|
180
|
+
// Use the afterSave hook here to combine the loaded world with other saved data.
|
|
181
|
+
this._rules.general?.afterSave?.(this._game);
|
|
182
|
+
|
|
183
|
+
if (saveGame.party.previousLocationId) {
|
|
184
|
+
this._game.previousLocation = this._game.locations.get(saveGame.party.previousLocationId);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this._game.actionLog = [];
|
|
188
|
+
this.setInterceptors();
|
|
189
|
+
|
|
190
|
+
if (this._game.playState === PlayState.Menu) {
|
|
191
|
+
this._game.playState = null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
this._game.combinations.combinationResult.reset();
|
|
195
|
+
this._locationService.processDestinations(this._game);
|
|
196
|
+
this._locationService.loadLocationDescriptions(this._game);
|
|
197
|
+
this._rules.setup.continueGame?.(this._game);
|
|
198
|
+
this._game.loading = false;
|
|
199
|
+
this._game.state = GameState.Play;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
watchPlayState(callBack: (game: IGame, newPlayState: PlayState, oldPlayState: PlayState) => void): void {
|
|
204
|
+
this.watchState<PlayState>('playState', callBack);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private readonly resume = (locationName: string): void => {
|
|
208
|
+
if (!this._game.party.characters.some(c => c.currentHitpoints === undefined || c.currentHitpoints > 0)) {
|
|
209
|
+
this._game.state = GameState.GameOver;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
this.setInterceptors();
|
|
214
|
+
this._characterService.checkEquipment();
|
|
215
|
+
const lastLocation = locationName && this._game.locations.get(locationName) || this._game.locations.start;
|
|
216
|
+
const previousLocationName = this._game.party.previousLocationId;
|
|
217
|
+
|
|
218
|
+
if (previousLocationName) {
|
|
219
|
+
this._game.previousLocation = this._game.locations.get(previousLocationName);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
this._game.commands.go(lastLocation.id, false);
|
|
223
|
+
this._game.state = GameState.Play;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private watchState<T>(stateName: string, callBack: (game: IGame, newState: T, oldState: T) => void) {
|
|
227
|
+
const watcherNames = `_${stateName}Watchers`;
|
|
228
|
+
const watchers = this[watcherNames] ?? [];
|
|
229
|
+
this[watcherNames] = watchers;
|
|
230
|
+
|
|
231
|
+
if (watchers.length === 0) {
|
|
232
|
+
let state = this._game[stateName];
|
|
233
|
+
|
|
234
|
+
Object.defineProperty(this._game, stateName, {
|
|
235
|
+
enumerable: true,
|
|
236
|
+
configurable: true,
|
|
237
|
+
get: () => {
|
|
238
|
+
return state;
|
|
239
|
+
},
|
|
240
|
+
set: value => {
|
|
241
|
+
const oldState = state;
|
|
242
|
+
state = value;
|
|
243
|
+
watchers.forEach(w => w(this._game, state, oldState));
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (watchers.indexOf(callBack) < 0) {
|
|
249
|
+
watchers.push(callBack);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private readonly initTexts = (): void => {
|
|
254
|
+
const defaultTexts = new DefaultTexts();
|
|
255
|
+
|
|
256
|
+
for (const n in defaultTexts.texts) {
|
|
257
|
+
this._texts[n] = this._texts[n] ? this._texts[n] : defaultTexts.texts[n];
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
this._texts.format = defaultTexts.format;
|
|
261
|
+
this._texts.titleCase = defaultTexts.titleCase;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private readonly createCharacter = (characterData: ICreateCharacter): void => {
|
|
265
|
+
const character = this._characterService.createCharacter(this._game, characterData);
|
|
266
|
+
(<any>character).type = 'character';
|
|
267
|
+
character.items = character.items || [];
|
|
268
|
+
this._game.party.characters.push(character);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private readonly initGame = (playedAudio: string[]): void => {
|
|
272
|
+
this.initLogs();
|
|
273
|
+
|
|
274
|
+
Object.defineProperty(this._game, 'activeCharacter', {
|
|
275
|
+
configurable: true,
|
|
276
|
+
get: () => {
|
|
277
|
+
const characters = this._game.party.characters;
|
|
278
|
+
let character = characters.filter(c => c.isActiveCharacter)[0]
|
|
279
|
+
?? characters.filter(c => c.currentHitpoints > 0)[0]
|
|
280
|
+
?? characters[0];
|
|
281
|
+
|
|
282
|
+
if (!character.isActiveCharacter) {
|
|
283
|
+
character.isActiveCharacter = true;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return character;
|
|
287
|
+
|
|
288
|
+
},
|
|
289
|
+
set: value => {
|
|
290
|
+
if (!value || value.currentHitpoints <= 0) {
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
this._game.party.characters.forEach(c => c.isActiveCharacter = false);
|
|
295
|
+
value.isActiveCharacter = true;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
this._game.sounds = this._soundService.getSounds();
|
|
300
|
+
this._game.sounds.playedAudio = playedAudio;
|
|
301
|
+
|
|
302
|
+
this.initCombinations();
|
|
303
|
+
this._locationService.init();
|
|
304
|
+
|
|
305
|
+
Object.defineProperty(this._game, 'currentMap', {
|
|
306
|
+
configurable: true,
|
|
307
|
+
get: () => {
|
|
308
|
+
let result = null;
|
|
309
|
+
|
|
310
|
+
if (this._game.maps) {
|
|
311
|
+
for (const key in this._game.maps) {
|
|
312
|
+
const map = this._game.maps[key];
|
|
313
|
+
const location = map.locations.find(l => l.location === this._game.currentLocation.id);
|
|
314
|
+
|
|
315
|
+
if (location) {
|
|
316
|
+
result = map;
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
if (this._rules.general?.gameStateChange) {
|
|
327
|
+
this.watchState<GameState>('state', this._rules.general.gameStateChange);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (this._rules.general?.playStateChange) {
|
|
331
|
+
this.watchState<PlayState>('playState', this._rules.general.playStateChange);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
private readonly setInterceptors = (): void => {
|
|
336
|
+
const defaultPartyName = this._game.party.name ?? '';
|
|
337
|
+
let score = this._game.party.score || 0;
|
|
338
|
+
let gameState = this._game.state;
|
|
339
|
+
let currentDescription = this._game.currentDescription;
|
|
340
|
+
let currentHitpoints: Map<string, number> = new Map<string, number>();
|
|
341
|
+
|
|
342
|
+
InitEntityCollection(this._game.party, Quests);
|
|
343
|
+
InitEntityCollection(this._game.party, Characters);
|
|
344
|
+
|
|
345
|
+
Object.defineProperty(this._game.party, 'name', {
|
|
346
|
+
configurable: true,
|
|
347
|
+
get: () => {
|
|
348
|
+
let partyName = defaultPartyName;
|
|
349
|
+
|
|
350
|
+
if (!partyName) {
|
|
351
|
+
this._game.party.characters.forEach((c, i) => {
|
|
352
|
+
const separator = i == this._game.party.characters.length - 1 ? ' & ' : ', ';
|
|
353
|
+
|
|
354
|
+
if (partyName) {
|
|
355
|
+
partyName += separator;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
partyName += c.name;
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return partyName;
|
|
363
|
+
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
this._game.party.characters.forEach(c => {
|
|
368
|
+
InitEntityCollection(c, Items);
|
|
369
|
+
currentHitpoints[c.name] = c.currentHitpoints ?? c.hitpoints;
|
|
370
|
+
|
|
371
|
+
Object.defineProperty(c, 'currentHitpoints', {
|
|
372
|
+
configurable: true,
|
|
373
|
+
get: () => {
|
|
374
|
+
return currentHitpoints[c.name];
|
|
375
|
+
},
|
|
376
|
+
set: value => {
|
|
377
|
+
const change = value - currentHitpoints[c.name];
|
|
378
|
+
currentHitpoints[c.name] = value;
|
|
379
|
+
this._rules.character.hitpointsChange?.(this._game, c, change);
|
|
380
|
+
|
|
381
|
+
if (currentHitpoints[c.name] <= 0) {
|
|
382
|
+
this._game.activeCharacter = this._game.party.characters.find(c => c.currentHitpoints > 0);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
Object.defineProperty(c, 'combatItems', {
|
|
388
|
+
get: function () {
|
|
389
|
+
const result = c.items.filter(i => {
|
|
390
|
+
return canUseInCombat(i.useInCombat, i, c.equipment);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
for (const n in c.equipment) {
|
|
394
|
+
const item = <IItem>c.equipment[n];
|
|
395
|
+
|
|
396
|
+
if (item && canUseInCombat(item.useInCombat, item, c.equipment)) {
|
|
397
|
+
result.push(item);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
Object.defineProperty(this._game.party, 'score', {
|
|
407
|
+
configurable: true,
|
|
408
|
+
get: () => {
|
|
409
|
+
return score;
|
|
410
|
+
},
|
|
411
|
+
set: value => {
|
|
412
|
+
const change = value - score;
|
|
413
|
+
score = value;
|
|
414
|
+
|
|
415
|
+
// Todo: separate score and xp(?)
|
|
416
|
+
// Change when xp can be lost.
|
|
417
|
+
if (change > 0) {
|
|
418
|
+
const levelUp = this._rules.general?.scoreChange?.(this._game, change);
|
|
419
|
+
|
|
420
|
+
if (levelUp) {
|
|
421
|
+
this._game.playState = null;
|
|
422
|
+
this._game.state = GameState.LevelUp;
|
|
423
|
+
this._characterService.setupLevelUp();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
Object.defineProperty(this._game, 'state', {
|
|
430
|
+
configurable: true,
|
|
431
|
+
get: () => {
|
|
432
|
+
return gameState;
|
|
433
|
+
},
|
|
434
|
+
set: state => {
|
|
435
|
+
if (state === GameState.GameOver || state === GameState.Victory) {
|
|
436
|
+
this._game.playState = null;
|
|
437
|
+
this._rules.general?.determineFinalScore?.(this._game);
|
|
438
|
+
this.updateHighScore();
|
|
439
|
+
this._dataService.save(HighScores, this._game.highScores);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
gameState = state;
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
Object.defineProperty(this._game, 'currentDescription', {
|
|
447
|
+
configurable: true,
|
|
448
|
+
get: () => {
|
|
449
|
+
return currentDescription;
|
|
450
|
+
},
|
|
451
|
+
set: (value: { title: string, type: string, item: IFeature }) => {
|
|
452
|
+
currentDescription = value;
|
|
453
|
+
this._game.playState = PlayState.Description;
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private readonly initLogs = (): void => {
|
|
459
|
+
this._game.actionLog = [];
|
|
460
|
+
this._game.combatLog = [];
|
|
461
|
+
|
|
462
|
+
this._game.logToLocationLog = (message: string) => {
|
|
463
|
+
this._game.currentLocation.log ??= [];
|
|
464
|
+
this._game.currentLocation.log.push(message);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
this._game.logToActionLog = (message: string) => {
|
|
468
|
+
this._game.actionLog.splice(0, 0, message);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
this._game.logToCombatLog = (message: string) => {
|
|
472
|
+
this._game.combatLog.splice(0, 0, message);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private readonly initCombinations = (): void => {
|
|
477
|
+
this._game.combinations = {
|
|
478
|
+
combinationResult: {
|
|
479
|
+
done: false,
|
|
480
|
+
text: null,
|
|
481
|
+
featuresToRemove: [],
|
|
482
|
+
reset: (): void => {
|
|
483
|
+
const result = this._game.combinations.combinationResult;
|
|
484
|
+
result.done = false;
|
|
485
|
+
result.text = null;
|
|
486
|
+
result.featuresToRemove.length = 0;
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
activeCombination: null,
|
|
490
|
+
tryCombine: (target: ICombinable): ICombineResult => {
|
|
491
|
+
const activeCombo = this._game.combinations.activeCombination;
|
|
492
|
+
const result = this._combinationService.tryCombination(target);
|
|
493
|
+
|
|
494
|
+
if (result.text) {
|
|
495
|
+
let featuresToRemove: string[] = [];
|
|
496
|
+
|
|
497
|
+
if (result.success) {
|
|
498
|
+
if (result.removeTarget) {
|
|
499
|
+
featuresToRemove.push(target.id);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
if (result.removeTool) {
|
|
503
|
+
featuresToRemove.push(activeCombo.selectedTool.id);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
this._game.combinations.combinationResult.featuresToRemove = featuresToRemove;
|
|
507
|
+
this._dataService.saveGame(this._game);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return result;
|
|
512
|
+
},
|
|
513
|
+
getCombineClass: (tool: ICombinable): string => {
|
|
514
|
+
return this._combinationService.getCombineClass(tool);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private readonly updateHighScore = (): void => {
|
|
520
|
+
const scoreEntry = {name: this._game.party.name, score: this._game.party.score};
|
|
521
|
+
this._game.highScores ??= [];
|
|
522
|
+
let scoreAdded = false;
|
|
523
|
+
|
|
524
|
+
this._game.highScores.forEach((entry) => {
|
|
525
|
+
if (this._game.party.score > entry.score && !scoreAdded) {
|
|
526
|
+
const index = this._game.highScores.indexOf(entry);
|
|
527
|
+
|
|
528
|
+
if (this._game.highScores.length >= 5) {
|
|
529
|
+
this._game.highScores.splice(index, 1, scoreEntry);
|
|
530
|
+
} else {
|
|
531
|
+
this._game.highScores.splice(index, 0, scoreEntry);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
scoreAdded = true;
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
if (this._game.highScores.length < 5 && !scoreAdded) {
|
|
539
|
+
this._game.highScores.push(scoreEntry);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
this._dataService.save(HighScores, this._game.highScores);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function canUseInCombat(flagOrFunction: boolean | ((item: IItem, equipment: IEquipment) => boolean), item: IItem, equipment: {}) {
|
|
547
|
+
const canUse = (typeof flagOrFunction === "function") ? flagOrFunction(item, equipment) : flagOrFunction;
|
|
548
|
+
|
|
549
|
+
if (canUse && !item.use) {
|
|
550
|
+
console.log(`Item ${item.name} declares it can be used in combat but has no use function.`)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return canUse;
|
|
554
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {getItemFromParty, IDefinitions, IEnemy, IGame, IHelpers, IItem, random, removeItemFromParty} from 'storyScript';
|
|
2
|
+
import {compareString} from 'src/Engine/utilityFunctions';
|
|
3
|
+
|
|
4
|
+
export class HelperService implements IHelpers {
|
|
5
|
+
constructor(private _game: IGame, private _definitions: IDefinitions) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
randomEnemy = (selector?: (enemy: IEnemy) => boolean): IEnemy => random<IEnemy>('enemies', this._definitions, <(enemy: IEnemy) => boolean>selector);
|
|
9
|
+
|
|
10
|
+
randomItem = (selector?: (item: IItem) => boolean): IItem => random<IItem>('items', this._definitions, <(item: IItem) => boolean>selector);
|
|
11
|
+
|
|
12
|
+
getItem = (selector: string): IItem => this.find<IItem>(selector, 'items', this._definitions);
|
|
13
|
+
|
|
14
|
+
getEnemy = (selector: string): IEnemy => this.find<IEnemy>(selector, 'enemies', this._definitions);
|
|
15
|
+
|
|
16
|
+
rollDice = (compositeOrSides: string | number, dieNumber: number = 1, bonus: number = 0): number => {
|
|
17
|
+
let sides: number;
|
|
18
|
+
|
|
19
|
+
if (typeof compositeOrSides !== 'number') {
|
|
20
|
+
const dieResult = compositeOrSides.split(/d/i).map(e => e.trim());
|
|
21
|
+
const bonusResult = dieResult[1]?.split(/[+-]/i).map(e => e.trim());
|
|
22
|
+
|
|
23
|
+
if (dieResult.length === 1) {
|
|
24
|
+
// Fixed damage, e.g. 6.
|
|
25
|
+
sides = parseInt(dieResult[0]);
|
|
26
|
+
} else {
|
|
27
|
+
// Random damage, 'XdY+/-Z'
|
|
28
|
+
dieNumber = parseInt(dieResult[0]);
|
|
29
|
+
sides = parseInt(bonusResult[0]);
|
|
30
|
+
bonus = bonusResult[1] === undefined ? 0 : parseInt(bonusResult[1]);
|
|
31
|
+
const modifier = compositeOrSides.match(/[+-]/i);
|
|
32
|
+
bonus = bonus > 0 ? modifier?.[0] === '+' ? bonus : bonus * -1 : 0;
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
sides = compositeOrSides;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let result = 0;
|
|
39
|
+
|
|
40
|
+
for (let i = 0; i < dieNumber; i++) {
|
|
41
|
+
result += Math.floor(Math.random() * sides + 1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
result += bonus;
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
calculateBonus = (person: { items?: IItem[], equipment?: {} }, type: string) => {
|
|
49
|
+
let bonus = 0;
|
|
50
|
+
|
|
51
|
+
if (person[type]) {
|
|
52
|
+
bonus += person[type];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (person.equipment) {
|
|
56
|
+
for (const n in person.equipment) {
|
|
57
|
+
const item = person.equipment[n];
|
|
58
|
+
if (item?.[type] && !isNaN(item[type])) {
|
|
59
|
+
bonus += parseInt(item[type]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} else if (person.items) {
|
|
63
|
+
person.items.forEach(item => {
|
|
64
|
+
if (item?.[type] && !isNaN(item[type])) {
|
|
65
|
+
bonus += parseInt(item[type]);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return bonus;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getItemFromParty = (item: string | (() => IItem)): IItem => {
|
|
74
|
+
return getItemFromParty(this._game.party, item);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
removeItemFromParty = (item: IItem | (() => IItem)): void => {
|
|
78
|
+
removeItemFromParty(this._game.party, item);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
private find<T>(selector: string, type: string, definitions: IDefinitions): T {
|
|
82
|
+
const collection = definitions[type];
|
|
83
|
+
|
|
84
|
+
if (!collection && !selector) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const match = (<[() => T]>collection).filter((definition: () => T) => {
|
|
89
|
+
return compareString(definition.name, selector);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return match[0] ? match[0]() : null;
|
|
93
|
+
}
|
|
94
|
+
}
|