├── packages ├── db │ ├── README.md │ ├── src │ │ ├── Helper │ │ │ ├── PolyFill.tsx │ │ │ ├── Form.tsx │ │ │ ├── LoadStatus.ts │ │ │ ├── URLSearchParamsHelper.ts │ │ │ ├── StringHelper.css │ │ │ ├── NumberHelper.tsx │ │ │ ├── getImageSize.ts │ │ │ └── TimeHelper.tsx │ │ ├── vite-env.d.ts │ │ ├── Page │ │ │ ├── ScriptsPage.css │ │ │ ├── ServantPage.css │ │ │ ├── Script │ │ │ │ ├── ScriptMainData.css │ │ │ │ └── ShowScriptLineContext.ts │ │ │ ├── Servant │ │ │ │ ├── ServantAssets.css │ │ │ │ ├── ServantMaterialBreakdown.css │ │ │ │ ├── ServantStatGrowth.css │ │ │ │ ├── ServantMainData.css │ │ │ │ ├── ServantProfileComments.css │ │ │ │ ├── ServantBondGrowth.css │ │ │ │ ├── ServantPortrait.css │ │ │ │ └── ServantRelatedQuests.tsx │ │ │ ├── Home │ │ │ │ ├── weblate.ts │ │ │ │ └── index.tsx │ │ │ ├── CommandCode │ │ │ │ ├── CommandCodePortrait.css │ │ │ │ └── CommandCodePortrait.tsx │ │ │ ├── Event │ │ │ │ ├── EventTable.css │ │ │ │ ├── Shop.css │ │ │ │ └── EventHeelPortrait.tsx │ │ │ ├── Ai │ │ │ │ └── AiTable.css │ │ │ ├── ItemsPage.css │ │ │ ├── ClassBoard │ │ │ │ ├── ClassBoardBreakdown.css │ │ │ │ └── ClassBoardNavigation.css │ │ │ ├── ItemPage.css │ │ │ ├── ChangelogPage.css │ │ │ ├── ScriptPage.module.css │ │ │ ├── CraftEssence │ │ │ │ ├── CraftEssenceProfileComments.tsx │ │ │ │ └── CraftEssencePortrait.css │ │ │ ├── ServantsPage.css │ │ │ ├── MysticCode │ │ │ │ ├── MysticCodePortrait.css │ │ │ │ ├── MysticCodeExp.tsx │ │ │ │ └── MysticCodePortrait.tsx │ │ │ ├── FaqPage.css │ │ │ ├── Quest │ │ │ │ ├── QuestDrops.tsx │ │ │ │ └── QuestPhaseNavigator.tsx │ │ │ ├── ClassBoardPage.tsx │ │ │ ├── WarMap │ │ │ │ └── WarMap.css │ │ │ ├── Changelog │ │ │ │ └── Settings.tsx │ │ │ └── ListingPage.css │ │ ├── Descriptor │ │ │ ├── PopOver.css │ │ │ ├── VoiceLinePlayer.css │ │ │ ├── QuestHashDescriptor.tsx │ │ │ ├── SvtClassDestriptor.tsx │ │ │ ├── Descriptor.css │ │ │ ├── ProfileVoiceTypeDescriptor.tsx │ │ │ ├── BuffTypeDescription.ts │ │ │ ├── Func │ │ │ │ ├── handleOptionSection.tsx │ │ │ │ ├── handleOnFieldSection.tsx │ │ │ │ ├── handleScalingSection.tsx │ │ │ │ ├── handleTeamSection.tsx │ │ │ │ ├── FuncDescriptorSections.tsx │ │ │ │ └── handleLinkageSection.tsx │ │ │ ├── EventDescriptor.tsx │ │ │ ├── SkillScriptCondDescriptor.tsx │ │ │ ├── SvttAttrDestriptor.tsx │ │ │ ├── VoiceActorDescriptor.tsx │ │ │ ├── EntityReferenceDescriptor.tsx │ │ │ ├── IllustratorDescriptor.tsx │ │ │ ├── EventAllOutDescription.tsx │ │ │ ├── CommonConsumeDescriptor.tsx │ │ │ ├── CardDescription.tsx │ │ │ ├── WarDescriptor.tsx │ │ │ ├── BuffValueDescription.tsx │ │ │ ├── FuncValueDescriptor.tsx │ │ │ ├── ServantDescriptorId.tsx │ │ │ ├── SkillReferenceDescriptor.tsx │ │ │ ├── CostumeDescriptor.tsx │ │ │ ├── CraftEssenceReferenceDescriptor.tsx │ │ │ ├── ItemUseDescription.tsx │ │ │ ├── CommandCodeDescriptor.tsx │ │ │ ├── ItemSetDescriptor.tsx │ │ │ └── QuestEnumDescription.tsx │ │ ├── Assets │ │ │ ├── star.png │ │ │ ├── star1.png │ │ │ ├── star2.png │ │ │ ├── star3.png │ │ │ ├── star4.png │ │ │ ├── star5.png │ │ │ ├── figure_016.png │ │ │ ├── figure_074.png │ │ │ ├── figure_127.png │ │ │ ├── figure_145.png │ │ │ ├── figure_150.png │ │ │ ├── figure_174.png │ │ │ ├── figure_189.png │ │ │ ├── figure_198.png │ │ │ ├── figure_241.png │ │ │ ├── figure_253.png │ │ │ ├── card_bg_arts.png │ │ │ ├── card_bg_quick.png │ │ │ ├── card_txt_arts.png │ │ │ ├── icon_limit_on.png │ │ │ ├── load_icon_A01.png │ │ │ ├── load_icon_A02.png │ │ │ ├── load_icon_A03.png │ │ │ ├── load_icon_A04.png │ │ │ ├── card_bg_buster.png │ │ │ ├── card_icon_arts.png │ │ │ ├── card_icon_quick.png │ │ │ ├── card_txt_buster.png │ │ │ ├── card_txt_extra.png │ │ │ ├── card_txt_quick.png │ │ │ ├── img_arrow_load.png │ │ │ ├── img_bondsgage_1.png │ │ │ ├── img_bondsgage_2.png │ │ │ ├── img_bondsgage_3.png │ │ │ ├── img_bondsgage_4.png │ │ │ ├── img_bondsgage_5.png │ │ │ ├── img_bondsgage_6.png │ │ │ ├── img_bondsgage_7.png │ │ │ ├── img_bondsgage_8.png │ │ │ ├── img_bondsgage_9.png │ │ │ ├── kon_loading │ │ │ │ ├── 00.png │ │ │ │ ├── 01.png │ │ │ │ ├── 03.png │ │ │ │ ├── 05.png │ │ │ │ └── 06.png │ │ │ ├── FaqPage │ │ │ │ ├── ai_shibata.png │ │ │ │ ├── ai_graph_105220.png │ │ │ │ ├── ai_basic_example.png │ │ │ │ ├── ai_graph_94035321.png │ │ │ │ ├── quest_page_enemy.png │ │ │ │ ├── wodime_thumbnail.jpg │ │ │ │ ├── event_page_main_info.png │ │ │ │ ├── quest_page_main_info.png │ │ │ │ ├── script_search_page.png │ │ │ │ ├── war_page_free_quests.png │ │ │ │ ├── war_page_main_info.png │ │ │ │ ├── war_page_main_quests.png │ │ │ │ ├── event_page_shop_planner.png │ │ │ │ ├── quest_page_script_drop_data.png │ │ │ │ └── event_page_shop_planner_exclude.png │ │ │ ├── card_icon_buster.png │ │ │ ├── img_bond_category.png │ │ │ ├── img_bondsgage_10.png │ │ │ ├── list │ │ │ │ ├── listframes0_bg.png │ │ │ │ ├── listframes1_bg.png │ │ │ │ ├── listframes2_bg.png │ │ │ │ ├── listframes3_bg.png │ │ │ │ ├── listframes4_bg.png │ │ │ │ ├── listframes5_bg.png │ │ │ │ ├── listframes0_txt_item.png │ │ │ │ ├── listframes1_txt_item.png │ │ │ │ ├── listframes2_txt_item.png │ │ │ │ └── listframes3_txt_item.png │ │ │ ├── remmant_loading │ │ │ │ ├── cat1.png │ │ │ │ ├── cat2.png │ │ │ │ ├── dog1.png │ │ │ │ └── dog2.png │ │ │ ├── Steggy_loading │ │ │ │ ├── load_icon_A01.png │ │ │ │ ├── load_icon_A02.png │ │ │ │ ├── load_icon_A03.png │ │ │ │ └── load_icon_A04.png │ │ │ ├── jp.svg │ │ │ ├── tw.svg │ │ │ ├── cn.svg │ │ │ └── kr.svg │ │ ├── Breakdown │ │ │ ├── EffectBreakdown.css │ │ │ ├── EffectBreakdownLines.css │ │ │ └── SkillReferenceBreakdown.tsx │ │ ├── Component │ │ │ ├── BuffClassRelationOverwrite.css │ │ │ ├── QuestEnemy.css │ │ │ ├── SearchableSelect.css │ │ │ ├── BuffIcon.css │ │ │ ├── ScriptTable.css │ │ │ ├── DataTable.css │ │ │ ├── ErrorStatus.css │ │ │ ├── QuestSummaryTable.tsx │ │ │ ├── ButtonGrid.css │ │ │ ├── FaceIcon.tsx │ │ │ ├── NumberSelector.tsx │ │ │ ├── CollapsibleContent.css │ │ │ ├── SkillGroupOverWrite.tsx │ │ │ ├── ScriptDialogueLine.css │ │ │ ├── BuffIcon.tsx │ │ │ ├── CardType.css │ │ │ ├── CopyToClipboard.tsx │ │ │ ├── Navigation.css │ │ │ ├── ItemIcon.css │ │ │ ├── BondIcon.tsx │ │ │ └── Scene.css │ │ ├── custom.d.ts │ │ ├── setupTests.ts │ │ ├── index.tsx │ │ ├── Setting │ │ │ └── Theme.tsx │ │ ├── Hooks │ │ │ ├── useImageSize.ts │ │ │ ├── useWindowDimensions.ts │ │ │ └── useScroll.ts │ │ └── App.css │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── apple-touch-icon.png │ │ └── manifest.json │ ├── .gitignore │ ├── tsconfig.json │ └── vite.config.ts ├── battle │ ├── .npmignore │ ├── .gitignore │ ├── test-data │ │ ├── data │ │ │ └── .gitignore │ │ └── fetchTestData.ts │ ├── src │ │ ├── Enum │ │ │ └── BattleTeam.ts │ │ ├── Trait │ │ │ ├── getTraitNums.ts │ │ │ ├── checkAllTrait.ts │ │ │ └── checkTrait.ts │ │ ├── Event │ │ │ ├── BattleEvent.ts │ │ │ ├── BattleAdjustNpEvent.ts │ │ │ ├── BattleBuffEvent.ts │ │ │ ├── BattleRemoveBuffEvent.ts │ │ │ ├── BattleUnhandledEffectEvent.ts │ │ │ └── BattleDamageEvent.ts │ │ ├── Skill │ │ │ ├── BattleSkillFunc.ts │ │ │ └── BattleSkillPassive.ts │ │ ├── index.ts │ │ └── NoblePhantasm │ │ │ └── BattleNoblePhantasmFunc.ts │ ├── tests │ │ ├── Buff │ │ │ └── BuffManagerTest.ts │ │ ├── Actor │ │ │ ├── BattleServantActor │ │ │ │ └── traitTest.ts │ │ │ └── PerfectBattleActorTest.ts │ │ ├── Func │ │ │ └── Implementations │ │ │ │ ├── getDamageList │ │ │ │ ├── randomAttackTest.ts │ │ │ │ ├── classAttackRateTest.ts │ │ │ │ ├── npMagnificationTest.ts │ │ │ │ ├── powerMagnificationTest.ts │ │ │ │ ├── specialDefenseTest.ts │ │ │ │ └── criticalMagnificationTest.ts │ │ │ │ └── adjustNpFuncTest.ts │ │ ├── Battle │ │ │ └── BattleFuncQuestTraitTest.ts │ │ ├── Action │ │ │ └── inspectAvailableTest.ts │ │ ├── NoblePhantasm │ │ │ └── BattleNoblePhantasmTest.ts │ │ └── Skill │ │ │ └── BattleSkillTest.ts │ └── tsconfig.json ├── api-connector │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── Schema │ │ │ ├── Info.ts │ │ │ ├── Cv.ts │ │ │ ├── Trait.ts │ │ │ ├── Illustrator.ts │ │ │ ├── Master.ts │ │ │ ├── CommonRelease.ts │ │ │ ├── Enemy.ts │ │ │ ├── CommonConsume.ts │ │ │ ├── MasterMission.ts │ │ │ ├── Attribute.ts │ │ │ ├── Frequency.ts │ │ │ ├── Support.ts │ │ │ ├── EnemyMaster.ts │ │ │ ├── CraftEssence.ts │ │ │ ├── BattleMaster.ts │ │ │ ├── NpcServant.ts │ │ │ ├── Change.ts │ │ │ ├── BattlePoint.ts │ │ │ ├── Bgm.ts │ │ │ ├── CommandCode.ts │ │ │ ├── MysticCode.ts │ │ │ ├── Script.ts │ │ │ ├── Servant.ts │ │ │ ├── Gacha.ts │ │ │ ├── Gift.ts │ │ │ └── WarBoard.ts │ │ └── Enum │ │ │ ├── Language.ts │ │ │ ├── Region.ts │ │ │ └── Card.ts │ ├── tsconfig.json │ ├── README.md │ └── package.json ├── api-descriptor │ ├── .npmignore │ ├── .gitignore │ ├── src │ │ ├── Translations │ │ │ ├── en-US │ │ │ │ └── main.json │ │ │ ├── zh-CN │ │ │ │ └── main.json │ │ │ └── index.ts │ │ ├── Item │ │ │ ├── index.ts │ │ │ └── describeUse.ts │ │ ├── Skill │ │ │ ├── index.ts │ │ │ └── SkillReferencePartial.ts │ │ ├── Card │ │ │ ├── index.ts │ │ │ ├── CardReferencePartial.ts │ │ │ └── describe.ts │ │ ├── Trait │ │ │ ├── index.ts │ │ │ └── TraitReferencePartial.ts │ │ ├── Func │ │ │ ├── Breakdown.ts │ │ │ ├── getStaticDataVal.ts │ │ │ ├── extractStaticDataValFields.ts │ │ │ ├── index.ts │ │ │ ├── Sections │ │ │ │ └── describeTeamSection.ts │ │ │ ├── EffectSections.ts │ │ │ ├── Value │ │ │ │ └── describeGainHpFromTargetsValue.ts │ │ │ ├── extractStaticDataVal.ts │ │ │ └── extractMutatingDataVals.ts │ │ ├── Buff │ │ │ ├── BuffReferencePartial.ts │ │ │ ├── index.ts │ │ │ ├── describeType.ts │ │ │ └── BuffHelpers.ts │ │ └── index.ts │ ├── tsconfig.json │ └── package.json ├── paper-moon │ ├── src │ │ ├── react-app-env.d.ts │ │ ├── components │ │ │ ├── BattleDisplay │ │ │ │ ├── Skill │ │ │ │ │ ├── BattleActorSkillDisplay.css │ │ │ │ │ └── BattleActorSkillIcon.css │ │ │ │ ├── BattleActorAttackDisplay.css │ │ │ │ ├── BattleActorDisplay.css │ │ │ │ └── BattleEventDisplay.tsx │ │ │ └── Navigation.tsx │ │ ├── paper-moon │ │ │ └── api.ts │ │ ├── setupTests.ts │ │ ├── app │ │ │ ├── enemyActorConfig │ │ │ │ ├── types.ts │ │ │ │ └── slice.ts │ │ │ ├── hooks.ts │ │ │ ├── playerActorConfig │ │ │ │ └── types.ts │ │ │ ├── battleSetup │ │ │ │ ├── types.ts │ │ │ │ └── slice.ts │ │ │ ├── store.ts │ │ │ └── battle │ │ │ │ └── types.ts │ │ ├── index.tsx │ │ └── App.tsx │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ └── manifest.json │ ├── .gitignore │ └── tsconfig.json └── db-og-worker │ ├── wrangler.toml │ ├── .gitignore │ ├── tsconfig.json │ ├── webpack.config.js │ └── package.json ├── lerna.json ├── .prettierignore ├── .git-blame-ignore-revs ├── .prettierrc.json ├── .gitignore ├── package.json ├── .github └── workflows │ ├── worker-publish.yaml │ └── docker-publish.yml ├── .devcontainer └── Dockerfile ├── LICENSE └── README.md /packages/db/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/db/src/Helper/PolyFill.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/battle/.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.json 2 | src 3 | -------------------------------------------------------------------------------- /packages/api-connector/.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.json 2 | src 3 | -------------------------------------------------------------------------------- /packages/api-descriptor/.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.json 2 | src 3 | -------------------------------------------------------------------------------- /packages/battle/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | -------------------------------------------------------------------------------- /packages/api-connector/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | -------------------------------------------------------------------------------- /packages/api-descriptor/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | -------------------------------------------------------------------------------- /packages/battle/test-data/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | */ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /packages/db/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/db/src/Page/ScriptsPage.css: -------------------------------------------------------------------------------- 1 | span.keyword { 2 | font-weight: bold; 3 | } 4 | -------------------------------------------------------------------------------- /packages/paper-moon/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": ["packages/*"], 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/src/Page/ServantPage.css: -------------------------------------------------------------------------------- 1 | #servant .tab-content { 2 | padding-top: 1rem; 3 | } 4 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Translations/en-US/main.json: -------------------------------------------------------------------------------- 1 | { "translation key": "translated value" } 2 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Translations/zh-CN/main.json: -------------------------------------------------------------------------------- 1 | { "translation key": "translated value" } 2 | -------------------------------------------------------------------------------- /packages/battle/src/Enum/BattleTeam.ts: -------------------------------------------------------------------------------- 1 | export enum BattleTeam { 2 | PLAYER, 3 | ENEMY, 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /packages/db/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/public/favicon.ico -------------------------------------------------------------------------------- /packages/db/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/public/logo192.png -------------------------------------------------------------------------------- /packages/db/src/Descriptor/PopOver.css: -------------------------------------------------------------------------------- 1 | .skill-popover { 2 | max-width: 100em; 3 | width: auto; 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/src/Page/Script/ScriptMainData.css: -------------------------------------------------------------------------------- 1 | .script-data .script-nav-link { 2 | min-width: 6em; 3 | } 4 | -------------------------------------------------------------------------------- /packages/db/src/Assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star.png -------------------------------------------------------------------------------- /packages/db/src/Assets/star1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star1.png -------------------------------------------------------------------------------- /packages/db/src/Assets/star2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star2.png -------------------------------------------------------------------------------- /packages/db/src/Assets/star3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star3.png -------------------------------------------------------------------------------- /packages/db/src/Assets/star4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star4.png -------------------------------------------------------------------------------- /packages/db/src/Assets/star5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/star5.png -------------------------------------------------------------------------------- /packages/paper-moon/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Info.ts: -------------------------------------------------------------------------------- 1 | export interface Info { 2 | hash: string; 3 | timestamp: number; 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/public/favicon-16x16.png -------------------------------------------------------------------------------- /packages/db/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/public/favicon-32x32.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_016.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_074.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_074.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_127.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_127.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_145.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_145.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_150.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_174.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_174.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_189.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_189.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_198.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_198.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_241.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_241.png -------------------------------------------------------------------------------- /packages/db/src/Assets/figure_253.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/figure_253.png -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantAssets.css: -------------------------------------------------------------------------------- 1 | .servant-asset-images { 2 | max-width: 100%; 3 | height: auto; 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/public/apple-touch-icon.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_bg_arts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_bg_arts.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_bg_quick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_bg_quick.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_txt_arts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_txt_arts.png -------------------------------------------------------------------------------- /packages/db/src/Assets/icon_limit_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/icon_limit_on.png -------------------------------------------------------------------------------- /packages/db/src/Assets/load_icon_A01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/load_icon_A01.png -------------------------------------------------------------------------------- /packages/db/src/Assets/load_icon_A02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/load_icon_A02.png -------------------------------------------------------------------------------- /packages/db/src/Assets/load_icon_A03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/load_icon_A03.png -------------------------------------------------------------------------------- /packages/db/src/Assets/load_icon_A04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/load_icon_A04.png -------------------------------------------------------------------------------- /packages/paper-moon/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/paper-moon/public/favicon.ico -------------------------------------------------------------------------------- /packages/paper-moon/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/paper-moon/public/logo192.png -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/package-lock.json 2 | **/yarn.lock 3 | build 4 | coverage 5 | .vscode 6 | dist 7 | /app 8 | .github 9 | .devcontainer -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Cv.ts: -------------------------------------------------------------------------------- 1 | export interface Cv { 2 | id: number; 3 | name: string; 4 | comment: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Assets/card_bg_buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_bg_buster.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_icon_arts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_icon_arts.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_icon_quick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_icon_quick.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_txt_buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_txt_buster.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_txt_extra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_txt_extra.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_txt_quick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_txt_quick.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_arrow_load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_arrow_load.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_1.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_2.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_3.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_4.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_5.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_6.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_7.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_8.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_9.png -------------------------------------------------------------------------------- /packages/db/src/Assets/kon_loading/00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/kon_loading/00.png -------------------------------------------------------------------------------- /packages/db/src/Assets/kon_loading/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/kon_loading/01.png -------------------------------------------------------------------------------- /packages/db/src/Assets/kon_loading/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/kon_loading/03.png -------------------------------------------------------------------------------- /packages/db/src/Assets/kon_loading/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/kon_loading/05.png -------------------------------------------------------------------------------- /packages/db/src/Assets/kon_loading/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/kon_loading/06.png -------------------------------------------------------------------------------- /packages/db/src/Descriptor/VoiceLinePlayer.css: -------------------------------------------------------------------------------- 1 | .voice-line-player-button { 2 | white-space: nowrap; 3 | min-width: 42px; 4 | } 5 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Item/index.ts: -------------------------------------------------------------------------------- 1 | import describeUse from "./describeUse"; 2 | 3 | export default { 4 | describeUse, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/ai_shibata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/ai_shibata.png -------------------------------------------------------------------------------- /packages/db/src/Assets/card_icon_buster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/card_icon_buster.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bond_category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bond_category.png -------------------------------------------------------------------------------- /packages/db/src/Assets/img_bondsgage_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/img_bondsgage_10.png -------------------------------------------------------------------------------- /packages/db/src/Page/Script/ShowScriptLineContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | 3 | export default createContext(false); 4 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Trait.ts: -------------------------------------------------------------------------------- 1 | export interface Trait { 2 | id: number; 3 | name: string; 4 | negative?: boolean; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes0_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes0_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes1_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes1_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes2_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes2_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes3_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes3_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes4_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes4_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes5_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes5_bg.png -------------------------------------------------------------------------------- /packages/db/src/Assets/remmant_loading/cat1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/remmant_loading/cat1.png -------------------------------------------------------------------------------- /packages/db/src/Assets/remmant_loading/cat2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/remmant_loading/cat2.png -------------------------------------------------------------------------------- /packages/db/src/Assets/remmant_loading/dog1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/remmant_loading/dog1.png -------------------------------------------------------------------------------- /packages/db/src/Assets/remmant_loading/dog2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/remmant_loading/dog2.png -------------------------------------------------------------------------------- /packages/paper-moon/src/components/BattleDisplay/Skill/BattleActorSkillDisplay.css: -------------------------------------------------------------------------------- 1 | .battle-actor-skill-display { 2 | margin-top: 10px; 3 | } 4 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/ai_graph_105220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/ai_graph_105220.png -------------------------------------------------------------------------------- /packages/db/src/Breakdown/EffectBreakdown.css: -------------------------------------------------------------------------------- 1 | .effect-breakdown .effect { 2 | max-width: 45%; 3 | min-width: 300px; 4 | width: 45%; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Page/Home/weblate.ts: -------------------------------------------------------------------------------- 1 | export interface WeblateStat { 2 | code: string; 3 | url: string; 4 | failing_percent: number; 5 | } 6 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Illustrator.ts: -------------------------------------------------------------------------------- 1 | export interface Illustrator { 2 | id: number; 3 | name: string; 4 | comment: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/ai_basic_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/ai_basic_example.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/ai_graph_94035321.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/ai_graph_94035321.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/quest_page_enemy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/quest_page_enemy.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/wodime_thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/wodime_thumbnail.jpg -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes0_txt_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes0_txt_item.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes1_txt_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes1_txt_item.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes2_txt_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes2_txt_item.png -------------------------------------------------------------------------------- /packages/db/src/Assets/list/listframes3_txt_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/list/listframes3_txt_item.png -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantMaterialBreakdown.css: -------------------------------------------------------------------------------- 1 | .material-breakdown tbody td { 2 | text-align: center; 3 | vertical-align: middle; 4 | } 5 | -------------------------------------------------------------------------------- /packages/api-connector/src/Enum/Language.ts: -------------------------------------------------------------------------------- 1 | enum Language { 2 | DEFAULT = "Default", 3 | ENGLISH = "English", 4 | } 5 | 6 | export default Language; 7 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/event_page_main_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/event_page_main_info.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/quest_page_main_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/quest_page_main_info.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/script_search_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/script_search_page.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/war_page_free_quests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/war_page_free_quests.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/war_page_main_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/war_page_main_info.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/war_page_main_quests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/war_page_main_quests.png -------------------------------------------------------------------------------- /packages/db/src/Assets/Steggy_loading/load_icon_A01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/Steggy_loading/load_icon_A01.png -------------------------------------------------------------------------------- /packages/db/src/Assets/Steggy_loading/load_icon_A02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/Steggy_loading/load_icon_A02.png -------------------------------------------------------------------------------- /packages/db/src/Assets/Steggy_loading/load_icon_A03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/Steggy_loading/load_icon_A03.png -------------------------------------------------------------------------------- /packages/db/src/Assets/Steggy_loading/load_icon_A04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/Steggy_loading/load_icon_A04.png -------------------------------------------------------------------------------- /packages/db/src/Page/CommandCode/CommandCodePortrait.css: -------------------------------------------------------------------------------- 1 | #command-code-portrait { 2 | margin-bottom: 20px; 3 | width: 100%; 4 | height: auto; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Page/Event/EventTable.css: -------------------------------------------------------------------------------- 1 | .event-table thead th { 2 | border-top: none; 3 | } 4 | 5 | .event-table .width-1px { 6 | width: 1px; 7 | } 8 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantStatGrowth.css: -------------------------------------------------------------------------------- 1 | .growth-curve-name { 2 | padding: 0.75rem; 3 | padding-top: 0; 4 | padding-bottom: 3%; 5 | } 6 | -------------------------------------------------------------------------------- /packages/db/src/Helper/Form.tsx: -------------------------------------------------------------------------------- 1 | import { FormEvent } from "react"; 2 | 3 | export const preventDefault = (e: FormEvent) => { 4 | e.preventDefault(); 5 | }; 6 | -------------------------------------------------------------------------------- /packages/db/src/Page/Ai/AiTable.css: -------------------------------------------------------------------------------- 1 | .ai-info tr:first-child { 2 | font-weight: bold; 3 | } 4 | 5 | .ai-info td:first-child { 6 | font-weight: bold; 7 | } 8 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Skill/index.ts: -------------------------------------------------------------------------------- 1 | import SkillReferencePartial from "./SkillReferencePartial"; 2 | 3 | export default { 4 | SkillReferencePartial, 5 | }; 6 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/event_page_shop_planner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/event_page_shop_planner.png -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/quest_page_script_drop_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/quest_page_script_drop_data.png -------------------------------------------------------------------------------- /packages/db/src/Page/ItemsPage.css: -------------------------------------------------------------------------------- 1 | #items .filter { 2 | cursor: pointer; 3 | margin: 0 10px; 4 | } 5 | 6 | #items #item-search { 7 | text-align: center; 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/src/Assets/FaqPage/event_page_shop_planner_exclude.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlasacademy/apps/HEAD/packages/db/src/Assets/FaqPage/event_page_shop_planner_exclude.png -------------------------------------------------------------------------------- /packages/db/src/Descriptor/QuestHashDescriptor.tsx: -------------------------------------------------------------------------------- 1 | const shortenQuestHash = (questHash: string) => { 2 | return questHash.slice(2); 3 | }; 4 | 5 | export default shortenQuestHash; 6 | -------------------------------------------------------------------------------- /packages/api-connector/src/Enum/Region.ts: -------------------------------------------------------------------------------- 1 | enum Region { 2 | JP = "JP", 3 | NA = "NA", 4 | CN = "CN", 5 | KR = "KR", 6 | TW = "TW", 7 | } 8 | 9 | export default Region; 10 | -------------------------------------------------------------------------------- /packages/db/src/Page/ClassBoard/ClassBoardBreakdown.css: -------------------------------------------------------------------------------- 1 | .items_requeriments { 2 | padding: 0; 3 | } 4 | 5 | .items_requeriments > li { 6 | display: inline; 7 | margin-right: 1rem; 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/src/Helper/LoadStatus.ts: -------------------------------------------------------------------------------- 1 | import { AxiosError } from "axios"; 2 | 3 | export default interface LoadStatus { 4 | loading: boolean; 5 | data?: T; 6 | error?: AxiosError; 7 | } 8 | -------------------------------------------------------------------------------- /packages/db/src/Page/ClassBoard/ClassBoardNavigation.css: -------------------------------------------------------------------------------- 1 | .classboard_navigation { 2 | list-style: none; 3 | display: flex; 4 | flex-wrap: wrap; 5 | gap: 1rem; 6 | padding: 0; 7 | } 8 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantMainData.css: -------------------------------------------------------------------------------- 1 | .servant-data-table, 2 | .servant-data-table tbody th, 3 | .servant-data-table tbody td { 4 | text-align: center; 5 | vertical-align: middle; 6 | } 7 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Card/index.ts: -------------------------------------------------------------------------------- 1 | import CardReferencePartial from "./CardReferencePartial"; 2 | import describe from "./describe"; 3 | 4 | export default { 5 | describe, 6 | CardReferencePartial, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Trait/index.ts: -------------------------------------------------------------------------------- 1 | import TraitReferencePartial from "./TraitReferencePartial"; 2 | import describe from "./describe"; 3 | 4 | export default { 5 | describe, 6 | TraitReferencePartial, 7 | }; 8 | -------------------------------------------------------------------------------- /packages/db/src/Component/BuffClassRelationOverwrite.css: -------------------------------------------------------------------------------- 1 | .classRelationTable tr td { 2 | text-align: center; 3 | vertical-align: middle; 4 | } 5 | 6 | .classRelationTable tr td:first-child { 7 | width: 5%; 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/src/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg" { 2 | import React = require("react"); 3 | export const ReactComponent: React.FC>; 4 | const src: string; 5 | export default src; 6 | } 7 | -------------------------------------------------------------------------------- /packages/db/src/Page/Event/Shop.css: -------------------------------------------------------------------------------- 1 | .shopTable thead th { 2 | vertical-align: baseline; 3 | } 4 | 5 | ul.condition-list { 6 | text-align: left; 7 | margin: 0 0 0 1rem; 8 | padding: 0; 9 | font-size: 0.8rem; 10 | } 11 | -------------------------------------------------------------------------------- /packages/db/src/Component/QuestEnemy.css: -------------------------------------------------------------------------------- 1 | .quest-svt-tables { 2 | margin-bottom: 1em; 3 | } 4 | 5 | .quest-svt-lv { 6 | font-size: 0.75em; 7 | } 8 | 9 | .quest-svt-data-table > tbody > tr > td { 10 | text-align: right; 11 | } 12 | -------------------------------------------------------------------------------- /packages/db/src/Component/SearchableSelect.css: -------------------------------------------------------------------------------- 1 | .searchable-select-clear { 2 | background: transparent; 3 | border: 0; 4 | bottom: 0; 5 | padding: 0 12px; 6 | position: absolute; 7 | right: 0; 8 | top: 0; 9 | } 10 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantProfileComments.css: -------------------------------------------------------------------------------- 1 | table.servant-comments td.profile-condition { 2 | width: 15%; 3 | } 4 | 5 | @media (max-width: 768px) { 6 | .servant-comments-header { 7 | display: none; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Prettier format 2 | b79425d19557146705aed89a656477663db662a3 3 | 82d9295b5a7123fe7d96da3433d3f3b9a9616883 4 | b179ffb39887998ec8fe00788957ae68e188ee42 5 | 59d77b0151e2a50b64efdad8425a8788ef52f7c8 6 | d38a6d5d885b01919567b6fa68186ad9e8f92ed3 -------------------------------------------------------------------------------- /packages/db/src/Breakdown/EffectBreakdownLines.css: -------------------------------------------------------------------------------- 1 | tr.trigger-skill > td { 2 | padding: 0; 3 | border-top: 2px solid; 4 | border-bottom: 2px solid; 5 | } 6 | 7 | tr.trigger-skill .trigger-skill-name { 8 | padding-left: 0.75rem; 9 | } 10 | -------------------------------------------------------------------------------- /packages/paper-moon/src/paper-moon/api.ts: -------------------------------------------------------------------------------- 1 | import { ApiConnector, Language, Region } from "@atlasacademy/api-connector"; 2 | 3 | const apiConnector = new ApiConnector({ 4 | language: Language.ENGLISH, 5 | region: Region.NA, 6 | }); 7 | 8 | export default apiConnector; 9 | -------------------------------------------------------------------------------- /packages/db/src/Component/BuffIcon.css: -------------------------------------------------------------------------------- 1 | .buff-icon { 2 | width: auto; 3 | vertical-align: bottom; 4 | } 5 | 6 | .buff-icon.passive-frame { 7 | border: 1px solid; 8 | border-radius: 5px; 9 | } 10 | 11 | .buff-icon.hide-state { 12 | opacity: 0.5; 13 | } 14 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Master.ts: -------------------------------------------------------------------------------- 1 | export interface MasterLevelInfo { 2 | requiredExp: number; 3 | maxAp: number; 4 | maxCost: number; 5 | maxFriend: number; 6 | } 7 | 8 | export type MasterLevelInfoMap = { 9 | [key in number]?: MasterLevelInfo; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/db/src/Page/ItemPage.css: -------------------------------------------------------------------------------- 1 | .materialUsage th, 2 | .materialUsage td { 3 | text-align: center; 4 | vertical-align: middle; 5 | } 6 | 7 | .materialUsage .faceIcon { 8 | width: 1px; 9 | } 10 | 11 | .materialUsage .materialOwner { 12 | text-align: left; 13 | } 14 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/CommonRelease.ts: -------------------------------------------------------------------------------- 1 | import CondType from "../Enum/Cond"; 2 | 3 | export interface CommonRelease { 4 | id: number; 5 | priority: number; 6 | condGroup: number; 7 | condType: CondType; 8 | condId: number; 9 | condNum: number; 10 | } 11 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Enemy.ts: -------------------------------------------------------------------------------- 1 | import { Entity, EntityBasic, EntityType } from "./Entity"; 2 | 3 | export interface Enemy extends Entity { 4 | type: EntityType.ENEMY; 5 | } 6 | 7 | export interface EnemyBasic extends EntityBasic { 8 | type: EntityType.ENEMY; 9 | } 10 | -------------------------------------------------------------------------------- /packages/db/src/Page/ChangelogPage.css: -------------------------------------------------------------------------------- 1 | .changelog-table thead th { 2 | text-align: center; 3 | } 4 | 5 | .changelog-table tbody td { 6 | text-align: center; 7 | vertical-align: middle; 8 | } 9 | 10 | .pagination-item { 11 | width: 2.5em; 12 | text-align: center; 13 | } 14 | -------------------------------------------------------------------------------- /packages/db/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom/extend-expect"; 6 | -------------------------------------------------------------------------------- /packages/db/src/Page/Home/index.tsx: -------------------------------------------------------------------------------- 1 | import { UILanguage } from "@atlasacademy/api-descriptor"; 2 | 3 | import homeEN from "./en"; 4 | import homeZHCN from "./zhCN"; 5 | 6 | export const home = (uiLang: UILanguage) => 7 | uiLang === UILanguage.ZH_CN || uiLang === UILanguage.ZH_TW ? homeZHCN : homeEN; 8 | -------------------------------------------------------------------------------- /packages/paper-moon/src/components/BattleDisplay/BattleActorAttackDisplay.css: -------------------------------------------------------------------------------- 1 | .battle-actor-action-display { 2 | display: flex !important; 3 | justify-content: center; 4 | margin-top: 10px; 5 | } 6 | 7 | .battle-actor-action-display > .action { 8 | flex: 0 1 auto !important; 9 | } 10 | -------------------------------------------------------------------------------- /packages/paper-moon/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom/extend-expect"; 6 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/CommonConsume.ts: -------------------------------------------------------------------------------- 1 | export enum CommonConsumeType { 2 | ITEM = "item", 3 | AP = "ap", 4 | } 5 | 6 | export interface CommonConsume { 7 | id: number; 8 | priority: number; 9 | type: CommonConsumeType; 10 | objectId: number; 11 | num: number; 12 | } 13 | -------------------------------------------------------------------------------- /packages/battle/src/Trait/getTraitNums.ts: -------------------------------------------------------------------------------- 1 | import { Trait } from "@atlasacademy/api-connector"; 2 | 3 | export const getNum = (variable: Trait.Trait | number | string) => { 4 | if (typeof variable === "number" || typeof variable === "string") return variable; 5 | return (variable as Trait.Trait).id; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/db/src/Page/ScriptPage.module.css: -------------------------------------------------------------------------------- 1 | .scrollBarIndicator { 2 | position: fixed; 3 | background: linear-gradient(90deg, var(--success) 0%, var(--info) 100%); 4 | height: 0.25em; 5 | top: 0; 6 | left: 0; 7 | right: 0; 8 | z-index: 10; 9 | scroll-behavior: smooth; 10 | } 11 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/Breakdown.ts: -------------------------------------------------------------------------------- 1 | import { Descriptor } from "../Descriptor"; 2 | import { relatedSkill } from "./getRelatedSkillIds"; 3 | 4 | export interface Breakdown { 5 | readonly descriptor: Descriptor; 6 | readonly mutatorDescriptors: Descriptor[]; 7 | readonly relatedSkillIds: relatedSkill[]; 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/src/Helper/URLSearchParamsHelper.ts: -------------------------------------------------------------------------------- 1 | export const getNumParam = (searchParams: URLSearchParams, param: string) => { 2 | const num = searchParams.get(param); 3 | if (num !== null) { 4 | try { 5 | return parseInt(num); 6 | } catch {} 7 | } 8 | return undefined; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/enemyActorConfig/types.ts: -------------------------------------------------------------------------------- 1 | export interface EnemyActorConfigServantOptions { 2 | name: string; 3 | } 4 | 5 | export interface EnemyActorConfigState { 6 | open: boolean; 7 | loading: boolean; 8 | servant?: number; 9 | servantOptions?: EnemyActorConfigServantOptions; 10 | } 11 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantBondGrowth.css: -------------------------------------------------------------------------------- 1 | .servant-bond-table, 2 | .servant-bond-table td { 3 | text-align: center; 4 | vertical-align: middle; 5 | } 6 | 7 | .servant-bond-table th { 8 | white-space: nowrap; 9 | } 10 | 11 | .servant-bond-table th img { 12 | height: 25px; 13 | margin-bottom: 3px; 14 | } 15 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/MasterMission.ts: -------------------------------------------------------------------------------- 1 | import { Mission } from "./Mission"; 2 | import { QuestBasic } from "./Quest"; 3 | 4 | export interface MasterMission { 5 | id: number; 6 | startedAt: number; 7 | endedAt: number; 8 | closedAt: number; 9 | missions: Mission[]; 10 | quests: QuestBasic[]; 11 | } 12 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/SvtClassDestriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { ClassName } from "@atlasacademy/api-connector"; 4 | 5 | export const SvtClassDescriptor = ({ svtClass }: { svtClass: ClassName }) => { 6 | const { t } = useTranslation(); 7 | return <>{t("SvtClass." + svtClass)}; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/db/src/Page/CraftEssence/CraftEssenceProfileComments.tsx: -------------------------------------------------------------------------------- 1 | import { withTranslation } from "react-i18next"; 2 | 3 | import { ServantProfileComments } from "../Servant/ServantProfileComments"; 4 | 5 | class CraftEssenceProfileComments extends ServantProfileComments {} 6 | 7 | export default withTranslation()(CraftEssenceProfileComments); 8 | -------------------------------------------------------------------------------- /packages/db/src/Component/ScriptTable.css: -------------------------------------------------------------------------------- 1 | .script-table tr th:first-child { 2 | max-width: 20%; 3 | } 4 | 5 | .script-table tr td:first-child { 6 | max-width: 20%; 7 | } 8 | 9 | .script-table .main-dialogue, 10 | .script-table .compare-dialogue, 11 | .script-table .main-choice, 12 | .script-table .compare-choice { 13 | width: 40%; 14 | } 15 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Attribute.ts: -------------------------------------------------------------------------------- 1 | export enum Attribute { 2 | HUMAN = "human", 3 | SKY = "sky", 4 | EARTH = "earth", 5 | STAR = "star", 6 | BEAST = "beast", 7 | VOID = "void", 8 | } 9 | 10 | export type AttributeAffinityMap = { 11 | [key in Attribute]?: { 12 | [key in Attribute]?: number; 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/db/src/Component/DataTable.css: -------------------------------------------------------------------------------- 1 | .data-header { 2 | font-weight: bold; 3 | margin-bottom: 10px; 4 | text-align: center; 5 | } 6 | 7 | .data-table th { 8 | white-space: nowrap; 9 | width: 1px; 10 | vertical-align: middle; 11 | } 12 | 13 | .data-table td { 14 | text-align: right; 15 | vertical-align: middle; 16 | } 17 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Card/CardReferencePartial.ts: -------------------------------------------------------------------------------- 1 | import { Card } from "@atlasacademy/api-connector"; 2 | 3 | import { ReferencePartial, ReferenceType } from "../Descriptor"; 4 | 5 | export default class CardReferencePartial extends ReferencePartial { 6 | constructor(card: Card | number) { 7 | super(ReferenceType.CARD, card); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/db/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | 4 | import App from "./App"; 5 | import "./i18n"; 6 | 7 | const container = document.getElementById("root"); 8 | const root = createRoot(container!); 9 | root.render( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Buff/BuffReferencePartial.ts: -------------------------------------------------------------------------------- 1 | import { Buff } from "@atlasacademy/api-connector"; 2 | 3 | import { ReferencePartial, ReferenceType } from "../Descriptor"; 4 | 5 | export default class BuffReferencePartial extends ReferencePartial { 6 | constructor(buff: Buff.Buff | number) { 7 | super(ReferenceType.BUFF, buff); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Descriptor.css: -------------------------------------------------------------------------------- 1 | .descriptor-link { 2 | white-space: nowrap; 3 | } 4 | 5 | .descriptor-link:hover { 6 | text-decoration: none; 7 | } 8 | 9 | .descriptor-link .hover-text { 10 | white-space: normal; 11 | } 12 | 13 | .descriptor-link:hover .hover-text { 14 | text-decoration: underline; 15 | white-space: normal; 16 | } 17 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Skill/SkillReferencePartial.ts: -------------------------------------------------------------------------------- 1 | import { Skill } from "@atlasacademy/api-connector"; 2 | 3 | import { ReferencePartial, ReferenceType } from "../Descriptor"; 4 | 5 | export default class SkillReferencePartial extends ReferencePartial { 6 | constructor(skill: Skill.Skill | number) { 7 | super(ReferenceType.SKILL, skill); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Trait/TraitReferencePartial.ts: -------------------------------------------------------------------------------- 1 | import { Trait } from "@atlasacademy/api-connector"; 2 | 3 | import { ReferencePartial, ReferenceType } from "../Descriptor"; 4 | 5 | export default class TraitReferencePartial extends ReferencePartial { 6 | constructor(trait: Trait.Trait | number) { 7 | super(ReferenceType.TRAIT, trait); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleEvent.ts: -------------------------------------------------------------------------------- 1 | import { BattleActor } from "../Actor/BattleActor"; 2 | 3 | export default abstract class BattleEvent { 4 | constructor( 5 | public actor: BattleActor | null, 6 | public target: BattleActor | null, 7 | public success: boolean, 8 | public reference?: any, 9 | ) { 10 | // 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/ProfileVoiceTypeDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Profile } from "@atlasacademy/api-connector"; 4 | 5 | export const ProfileVoiceTypeDescriptor = ({ voiceType }: { voiceType: Profile.ProfileVoiceType }) => { 6 | const { t } = useTranslation(); 7 | return <>{t("ProfileVoiceType." + voiceType)}; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Frequency.ts: -------------------------------------------------------------------------------- 1 | export enum FrequencyType { 2 | NONE = "none", 3 | ONCE = "once", 4 | ONCE_UNTIL_REBOOT = "onceUntilReboot", 5 | EVERY_TIME = "everyTime", 6 | VALENTINE = "valentine", 7 | EVERY_TIME_AFTER = "everyTimeAfter", 8 | EVERY_TIME_BEFORE = "everyTimeBefore", 9 | ONCE_UNTIL_REMIND = "onceUntilRemind", 10 | } 11 | -------------------------------------------------------------------------------- /packages/api-connector/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "ES6", 5 | "lib": ["ESNext", "DOM"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "moduleResolution": "Node", 9 | "outDir": "./dist", 10 | "strict": true 11 | }, 12 | "include": ["src/**/*"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/battle/tests/Buff/BuffManagerTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Buff } from "@atlasacademy/api-connector"; 4 | 5 | import { Battle, BattleTeam } from "../../src"; 6 | import { servant } from "../helpers"; 7 | 8 | describe("BuffManager", () => { 9 | it("netBuffs does not include if does not have trait", async () => { 10 | // TODO 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /packages/db-og-worker/wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "db-site-worker" 2 | account_id = "fa227777c8b69f6569d4a4347a6cceb8" 3 | workers_dev = true 4 | compatibility_date = "2024-06-01" 5 | main = "./src/index.ts" 6 | kv_namespaces = [ 7 | { binding = "atlas_api_cache", preview_id = "ea0f171f5e2544709dfccc02701a9e51", id = "6307c816b0714a5e8fc7ce5f9f58226f" }, 8 | ] 9 | 10 | [site] 11 | bucket = "../../app" 12 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/hooks.ts: -------------------------------------------------------------------------------- 1 | import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; 2 | 3 | import type { AppDispatch, RootState } from "./store"; 4 | 5 | // Use throughout your app instead of plain `useDispatch` and `useSelector` 6 | export const useAppDispatch = () => useDispatch(); 7 | export const useAppSelector: TypedUseSelectorHook = useSelector; 8 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/BuffTypeDescription.ts: -------------------------------------------------------------------------------- 1 | import { Buff } from "@atlasacademy/api-connector"; 2 | import { BuffDescriptor } from "@atlasacademy/api-descriptor"; 3 | 4 | const BuffTypeDescription = new Map( 5 | Object.values(Buff.BuffType).map((type) => { 6 | return [type, BuffDescriptor.describeType(type)]; 7 | }) 8 | ); 9 | 10 | export default BuffTypeDescription; 11 | -------------------------------------------------------------------------------- /packages/paper-moon/src/components/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Navbar } from "react-bootstrap"; 3 | 4 | class Navigation extends React.Component { 5 | render() { 6 | return ( 7 | 8 | Paper-Moon 9 | 10 | ); 11 | } 12 | } 13 | 14 | export default Navigation; 15 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Support.ts: -------------------------------------------------------------------------------- 1 | export enum SvtClassSupportGroupType { 2 | ALL = "all", 3 | SABER = "saber", 4 | ARCHER = "archer", 5 | LANCER = "lancer", 6 | RIDER = "rider", 7 | CASTER = "caster", 8 | ASSASSIN = "assassin", 9 | BERSERKER = "berserker", 10 | EXTRA = "extra", 11 | MIX = "mix", 12 | RECOMMEND = "recommend", 13 | NOT_SUPPORT = "notSupport", 14 | } 15 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/EnemyMaster.ts: -------------------------------------------------------------------------------- 1 | export interface EnemyMasterBattle { 2 | id: number; 3 | face: string; 4 | figure: string; 5 | commandSpellIcon: string; 6 | maxCommandSpell: number; 7 | offsetX: number; 8 | offsetY: number; 9 | cutin?: string[]; 10 | } 11 | 12 | export interface EnemyMaster { 13 | id: number; 14 | name: string; 15 | battles: EnemyMasterBattle[]; 16 | } 17 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Buff/index.ts: -------------------------------------------------------------------------------- 1 | import * as BuffTypes from "./BuffTypes"; 2 | import BuffReferencePartial from "./BuffReferencePartial"; 3 | import describe from "./describe"; 4 | import describeType from "./describeType"; 5 | import describeValue from "./describeValue"; 6 | 7 | export default { 8 | describe, 9 | describeType, 10 | describeValue, 11 | BuffReferencePartial, 12 | BuffTypes, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/getStaticDataVal.ts: -------------------------------------------------------------------------------- 1 | import { DataVal, Func } from "@atlasacademy/api-connector"; 2 | 3 | import extractStaticDataVal from "./extractStaticDataVal"; 4 | import getValList from "./getValList"; 5 | 6 | export default function (func: Func.Func): DataVal.DataVal { 7 | let vals = getValList(func); 8 | 9 | if (!vals.length) return {}; 10 | 11 | return extractStaticDataVal(vals); 12 | } 13 | -------------------------------------------------------------------------------- /packages/paper-moon/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /packages/db/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .idea 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/extractStaticDataValFields.ts: -------------------------------------------------------------------------------- 1 | import { DataVal } from "@atlasacademy/api-connector"; 2 | 3 | import { hasUniqueValues } from "../Helpers"; 4 | 5 | export default function (vals: DataVal.DataVal[]): DataVal.DataValField[] { 6 | return Object.values(DataVal.DataValField).filter((field) => { 7 | const values = vals.map((val) => val[field]); 8 | 9 | return !hasUniqueValues(values); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /packages/db-og-worker/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /worker 13 | /dist 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /packages/battle/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "ES6", 5 | "lib": ["ESNext", "DOM"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "moduleResolution": "Node", 10 | "outDir": "./dist", 11 | "resolveJsonModule": true, 12 | "strict": true 13 | }, 14 | "include": ["src/**/*"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/db/src/Component/ErrorStatus.css: -------------------------------------------------------------------------------- 1 | @media only screen and (max-width: 500px) { 2 | #error-status li.d-inline { 3 | display: block !important; 4 | float: none; 5 | margin-top: 10% !important; 6 | } 7 | #error-status button.btn.btn-primary { 8 | height: 50px; 9 | font-size: x-large; 10 | width: 180px; 11 | } 12 | #error-status p { 13 | margin: 0 20% !important; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/api-descriptor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "CommonJS", 4 | "target": "ES6", 5 | "lib": ["ESNext", "DOM"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "moduleResolution": "Node", 9 | "outDir": "./dist", 10 | "strict": true, 11 | "resolveJsonModule": true, 12 | "esModuleInterop": true 13 | }, 14 | "include": ["src/**/*"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/db/src/Helper/StringHelper.css: -------------------------------------------------------------------------------- 1 | span.e000 { 2 | display: inline-block; 3 | line-height: 1; 4 | position: relative; 5 | vertical-align: -0.55em; 6 | } 7 | 8 | span.e000-bottom { 9 | transform: scale(1, 0.4); 10 | display: inline-block; 11 | padding-top: 0.98em; 12 | } 13 | 14 | span.e000-top { 15 | transform: scale(1, 0.75); 16 | position: absolute; 17 | display: block; 18 | line-height: 1.6; 19 | top: 0; 20 | } 21 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleAdjustNpEvent.ts: -------------------------------------------------------------------------------- 1 | import { BattleActor } from "../Actor/BattleActor"; 2 | import BattleEvent from "./BattleEvent"; 3 | 4 | export default class BattleAdjustNpEvent extends BattleEvent { 5 | constructor( 6 | public actor: BattleActor, 7 | public target: BattleActor, 8 | public success: boolean, 9 | public reference?: number, 10 | ) { 11 | super(actor, target, success, reference); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/playerActorConfig/types.ts: -------------------------------------------------------------------------------- 1 | export interface PlayerActorConfigServantOptions { 2 | name: string; 3 | level: string | number; 4 | } 5 | 6 | export interface PlayerActorConfigState { 7 | open: boolean; 8 | loading: boolean; 9 | ready: boolean; 10 | servant?: number; 11 | servantOptions: PlayerActorConfigServantOptions; 12 | defaultServantOptions: PlayerActorConfigServantOptions; 13 | craftEssence?: number; 14 | } 15 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "tabWidth": 4, 4 | "trailingComma": "es5", 5 | "plugins": ["@trivago/prettier-plugin-sort-imports"], 6 | "importOrder": ["", "^@atlasacademy/(.*)$", "^[./].*(? arr.reduce((a, b) => a + b, 0); 2 | 3 | export const toFixedLocale = (input: number, digits: number) => 4 | input.toLocaleString(undefined, { 5 | minimumFractionDigits: digits, 6 | maximumFractionDigits: digits, 7 | }); 8 | 9 | export const numToPct = (value: number) => 10 | value < 1 ? `${toFixedLocale(value * 100, 2)}%` : `${Math.round(value * 100).toLocaleString()}%`; 11 | -------------------------------------------------------------------------------- /packages/paper-moon/src/components/BattleDisplay/BattleActorDisplay.css: -------------------------------------------------------------------------------- 1 | .battle-actor-display { 2 | padding-left: 85px; 3 | position: relative; 4 | } 5 | 6 | .battle-actor-face { 7 | display: block; 8 | left: 0; 9 | position: absolute; 10 | top: 0; 11 | width: 75px; 12 | } 13 | .battle-actor-name { 14 | font-weight: bold; 15 | text-align: right; 16 | } 17 | .battle-actor-health, 18 | .battle-actor-gauge { 19 | text-align: right; 20 | } 21 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/battleSetup/types.ts: -------------------------------------------------------------------------------- 1 | import { BattleTeam } from "@atlasacademy/battle"; 2 | 3 | export interface BattleSetupOptionList { 4 | id: number; 5 | collectionNo: number; 6 | name: string; 7 | } 8 | 9 | export interface BattleSetupState { 10 | pending: boolean; 11 | canAddActor: boolean; 12 | servantList: BattleSetupOptionList[]; 13 | craftEssenceList: BattleSetupOptionList[]; 14 | selectedServant?: number; 15 | selectedTeam: BattleTeam; 16 | } 17 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleBuffEvent.ts: -------------------------------------------------------------------------------- 1 | import { BattleActor } from "../Actor/BattleActor"; 2 | import { BattleBuff } from "../Buff/BattleBuff"; 3 | import BattleEvent from "./BattleEvent"; 4 | 5 | export default class BattleBuffEvent extends BattleEvent { 6 | constructor( 7 | public actor: BattleActor, 8 | public target: BattleActor, 9 | public success: boolean, 10 | public reference: BattleBuff, 11 | ) { 12 | super(actor, target, success, reference); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/CraftEssence.ts: -------------------------------------------------------------------------------- 1 | import { Entity, EntityBasic, EntityType } from "./Entity"; 2 | import { Profile } from "./Profile"; 3 | 4 | export interface CraftEssence extends Entity { 5 | type: EntityType.SERVANT_EQUIP; 6 | bondEquipOwner?: number; 7 | valentineEquipOwner?: number; 8 | profile?: Profile; 9 | } 10 | 11 | export interface CraftEssenceBasic extends EntityBasic { 12 | type: EntityType.SERVANT_EQUIP; 13 | bondEquipOwner?: number; 14 | valentineEquipOwner?: number; 15 | } 16 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleRemoveBuffEvent.ts: -------------------------------------------------------------------------------- 1 | import { BattleActor } from "../Actor/BattleActor"; 2 | import { BattleBuff } from "../Buff/BattleBuff"; 3 | import BattleEvent from "./BattleEvent"; 4 | 5 | export default class BattleRemoveBuffEvent extends BattleEvent { 6 | constructor( 7 | public actor: BattleActor, 8 | public target: BattleActor, 9 | public success: boolean, 10 | public reference?: BattleBuff, 11 | ) { 12 | super(actor, target, success, reference); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | .vscode/ 3 | .idea/ 4 | /app/ 5 | /src/ 6 | packages/battle/dist 7 | 8 | # dependencies 9 | node_modules 10 | /.pnp 11 | .pnp.js 12 | .eslintcache 13 | 14 | # testing 15 | /coverage 16 | 17 | # production 18 | # /build 19 | 20 | # misc 21 | .DS_Store 22 | .env.local 23 | .env.development.local 24 | .env.test.local 25 | .env.production.local 26 | .idea 27 | 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | lerna-debug.log 32 | -------------------------------------------------------------------------------- /packages/db/src/Assets/jp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/BattleMaster.ts: -------------------------------------------------------------------------------- 1 | import { CommonRelease } from "./CommonRelease"; 2 | import { Gender } from "./Entity"; 3 | 4 | export interface BattleMasterImage { 5 | id: number; 6 | type: Gender; 7 | faceIcon?: string; 8 | skillCutin?: string; 9 | skillCutinOffsetX: number; 10 | skillCutinOffsetY: number; 11 | commandSpellCutin?: string; 12 | commandSpellCutinOffsetX: number; 13 | commandSpellCutinOffsetY: number; 14 | resultImage?: string; 15 | releaseConditions: CommonRelease[]; 16 | } 17 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleUnhandledEffectEvent.ts: -------------------------------------------------------------------------------- 1 | import { Func } from "@atlasacademy/api-connector"; 2 | 3 | import { BattleActor } from "../Actor/BattleActor"; 4 | import BattleEvent from "./BattleEvent"; 5 | 6 | export default class BattleUnhandledEffectEvent extends BattleEvent { 7 | constructor( 8 | public actor: BattleActor, 9 | public target: BattleActor, 10 | public success: false, 11 | public reference: Func.FuncType, 12 | ) { 13 | super(actor, target, success, reference); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/db/src/Assets/tw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/db/src/Page/CraftEssence/CraftEssencePortrait.css: -------------------------------------------------------------------------------- 1 | #craft-essence-portrait-image { 2 | margin-bottom: 20px; 3 | width: 100%; 4 | height: auto; 5 | } 6 | 7 | #craft-essence-portrait > .arrow { 8 | cursor: pointer; 9 | height: 10%; 10 | position: absolute; 11 | /* padding of bootstrap col class */ 12 | right: -15px; 13 | transform: translateY(-50%); 14 | top: 50%; 15 | } 16 | 17 | #craft-essence-portrait > .arrow.back { 18 | left: -15px; 19 | right: auto; 20 | transform: scaleX(-1) translateY(-50%); 21 | } 22 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/index.ts: -------------------------------------------------------------------------------- 1 | import describe from "./describe"; 2 | import describeBreakdown from "./describeBreakdown"; 3 | import describeValue from "./describeValue"; 4 | import { targetOpposingTeam, targetSameTeam } from "./getOpponentType"; 5 | import getRelatedNpIds from "./getRelatedNpIds"; 6 | import getRelatedSkillIds from "./getRelatedSkillIds"; 7 | 8 | export default { 9 | describe, 10 | describeBreakdown, 11 | describeValue, 12 | getRelatedSkillIds, 13 | getRelatedNpIds, 14 | targetOpposingTeam, 15 | targetSameTeam, 16 | }; 17 | -------------------------------------------------------------------------------- /packages/paper-moon/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Paper Moon", 3 | "name": "Atlas Academy - Paper Moon", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | } 15 | ], 16 | "start_url": ".", 17 | "display": "standalone", 18 | "theme_color": "#000000", 19 | "background_color": "#ffffff" 20 | } 21 | -------------------------------------------------------------------------------- /packages/db-og-worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2022", 4 | "target": "es2021", 5 | "lib": ["es2021"], 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "types": ["@cloudflare/workers-types"], 9 | "resolveJsonModule": true, 10 | "allowJs": true, 11 | "checkJs": true, 12 | "noEmit": true, 13 | "isolatedModules": true, 14 | "allowSyntheticDefaultImports": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "skipLibCheck": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/db/src/Helper/getImageSize.ts: -------------------------------------------------------------------------------- 1 | export type Dimension = { 2 | width: number; 3 | height: number; 4 | }; 5 | 6 | export const getImageSize = (url: string): Promise => { 7 | return new Promise((resolve, reject) => { 8 | const img = new Image(); 9 | 10 | img.addEventListener("load", () => { 11 | resolve({ width: img.naturalWidth, height: img.naturalHeight }); 12 | }); 13 | 14 | img.addEventListener("error", (event) => { 15 | resolve({ width: -1, height: -1 }); 16 | }); 17 | 18 | img.src = url; 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/NpcServant.ts: -------------------------------------------------------------------------------- 1 | import { EnemySkill } from "./QuestEnemy"; 2 | import { ServantBasic } from "./Servant"; 3 | import { SupportServantFlag, SupportServantLimit, SupportServantTd } from "./SupportServant"; 4 | import { Trait } from "./Trait"; 5 | 6 | export interface NpcServant { 7 | npcId: number; 8 | name: string; 9 | svt: ServantBasic; 10 | lv: number; 11 | atk: number; 12 | hp: number; 13 | traits: Trait[]; 14 | skills: EnemySkill; 15 | noblePhantasm: SupportServantTd; 16 | limit: SupportServantLimit; 17 | flags: SupportServantFlag[]; 18 | } 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "devDependencies": { 5 | "@trivago/prettier-plugin-sort-imports": "^5.2.2", 6 | "lerna": "^3.22.1", 7 | "prettier": "^3.5.3" 8 | }, 9 | "scripts": { 10 | "format": "prettier --write packages/", 11 | "watch": "lerna run watch --stream --no-sort --concurrency 99", 12 | "i18n": "lerna run i18n --scope=@atlasacademy/db --stream", 13 | "start:db": "lerna run start --scope=@atlasacademy/db --stream", 14 | "start:paper-moon": "lerna run start --scope=paper-moon --stream" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/db/src/Helper/TimeHelper.tsx: -------------------------------------------------------------------------------- 1 | export const getTimeString = (timestampSecond: number) => { 2 | return new Date(timestampSecond * 1000).toLocaleString(); 3 | }; 4 | 5 | export const getCurrentTimestamp = () => Math.floor(Date.now() / 1000); 6 | 7 | export const getEventStatus = (startedAt: number, endedAt: number) => { 8 | const currentTimestamp = getCurrentTimestamp(); 9 | if (currentTimestamp < startedAt) { 10 | return "Not started"; 11 | } 12 | if (currentTimestamp >= startedAt && currentTimestamp <= endedAt) { 13 | return "Ongoing"; 14 | } 15 | return "Finished"; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Translations/index.ts: -------------------------------------------------------------------------------- 1 | import { UILanguage } from ".."; 2 | import enTranslation from "./en-US/main.json"; 3 | import zhTranslation from "./zh-CN/main.json"; 4 | 5 | export const t = (key: string, language?: UILanguage): string => { 6 | if (language === UILanguage.ZH_CN) { 7 | return ( 8 | (zhTranslation as Record)[key] ?? 9 | (enTranslation as Record)[key] ?? 10 | "Unknown translation key" 11 | ); 12 | } 13 | 14 | return (enTranslation as Record)[key] ?? "Unknown translation key"; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/handleOptionSection.tsx: -------------------------------------------------------------------------------- 1 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 2 | 3 | import { t } from "../../i18n"; 4 | import { FuncDescriptorSections } from "./FuncDescriptorSections"; 5 | 6 | export default function handleOptionSection( 7 | region: Region, 8 | sections: FuncDescriptorSections, 9 | func: Func.BasicFunc, 10 | dataVal: DataVal.DataVal 11 | ): void { 12 | const section = sections.option, 13 | parts = section.parts; 14 | 15 | if (dataVal.ActSelectIndex !== undefined) parts.push(`[${t("Option")} ${dataVal.ActSelectIndex + 1}]`); 16 | } 17 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantPortrait.css: -------------------------------------------------------------------------------- 1 | #servant-portrait { 2 | position: relative; 3 | margin-bottom: 20px; 4 | } 5 | 6 | #servant-portrait > .arrow { 7 | cursor: pointer; 8 | height: 10%; 9 | position: absolute; 10 | /* padding of bootstrap col class */ 11 | right: -15px; 12 | transform: translateY(-50%); 13 | top: 50%; 14 | } 15 | 16 | #servant-portrait > .arrow.back { 17 | left: -15px; 18 | right: auto; 19 | transform: scaleX(-1) translateY(-50%); 20 | } 21 | 22 | #servant-portrait-image { 23 | display: block; 24 | width: 100%; 25 | height: auto; 26 | } 27 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./Descriptor"; 2 | export { default as BuffDescriptor } from "./Buff"; 3 | export { default as CardDescriptor } from "./Card"; 4 | export { default as FuncDescriptor } from "./Func"; 5 | export { default as ItemDescriptor } from "./Item"; 6 | export { default as SkillDescriptor } from "./Skill"; 7 | export { default as TraitDescriptor } from "./Trait"; 8 | export { toTitleCase } from "./Helpers"; 9 | 10 | export enum UILanguage { 11 | EN_US = "en-US", 12 | ID_ID = "id-ID", 13 | ZH_CN = "zh-CN", 14 | ZH_TW = "zh-TW", 15 | JA_JP = "ja-JP", 16 | KO_KR = "ko-KR", 17 | } 18 | -------------------------------------------------------------------------------- /packages/db/src/Component/QuestSummaryTable.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from "react-bootstrap"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | import { Quest } from "@atlasacademy/api-connector"; 5 | 6 | export const QuestSummaryTable = ({ quest }: { quest: Quest.Quest }) => { 7 | const { t } = useTranslation(); 8 | 9 | return ( 10 | <> 11 | 12 | 13 | 15 | 16 | 17 | 18 |
14 |
19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/EventDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | import { Region } from "@atlasacademy/api-connector"; 4 | 5 | import useApi from "../Hooks/useApi"; 6 | import { lang } from "../Setting/Manager"; 7 | 8 | export default function EventDescriptor(props: { region: Region; eventId: number }) { 9 | const { data: event } = useApi("eventBasic", props.eventId); 10 | return ( 11 | 12 | {event !== undefined ? {event.name} : `Event ${props.eventId}`} 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/db/src/Page/ServantsPage.css: -------------------------------------------------------------------------------- 1 | #servants .filter { 2 | cursor: pointer; 3 | margin: 0 5px; 4 | } 5 | 6 | #servants #class-name { 7 | justify-content: center; 8 | display: flex; 9 | flex-flow: row wrap; 10 | margin-bottom: 1rem; 11 | } 12 | 13 | #servants #servant-search { 14 | margin-left: auto; 15 | margin-bottom: 1rem; 16 | } 17 | 18 | #servants #servant-search form input { 19 | width: 100%; 20 | height: 37; 21 | text-align: center; 22 | } 23 | 24 | #servants #servant-rarity { 25 | margin-bottom: 1rem; 26 | } 27 | 28 | #servants #servant-rarity .btn-group { 29 | width: 100%; 30 | } 31 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/SkillScriptCondDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Skill } from "@atlasacademy/api-connector"; 4 | 5 | const SkillScriptCondDescriptor = ({ cond, value }: { cond: Skill.SkillScriptCond; value?: number }) => { 6 | const { t } = useTranslation(); 7 | switch (cond) { 8 | case Skill.SkillScriptCond.NONE: 9 | return <>{t("No Requirement")}; 10 | case Skill.SkillScriptCond.STAR_HIGHER: 11 | return <>{t("consumeStars", { count: value })}; 12 | } 13 | 14 | return <>; 15 | }; 16 | 17 | export default SkillScriptCondDescriptor; 18 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/handleOnFieldSection.tsx: -------------------------------------------------------------------------------- 1 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 2 | 3 | import { FuncDescriptorSections } from "./FuncDescriptorSections"; 4 | 5 | export default function handleOnFieldSection( 6 | region: Region, 7 | sections: FuncDescriptorSections, 8 | func: Func.BasicFunc, 9 | dataVal: DataVal.DataVal 10 | ): void { 11 | const section = sections.onField, 12 | parts = section.parts; 13 | 14 | if (dataVal.OnField ? dataVal.OnField > 0 : false) { 15 | parts.push("when on the field"); 16 | } else { 17 | section.showing = false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/db/src/Page/MysticCode/MysticCodePortrait.css: -------------------------------------------------------------------------------- 1 | #mystic-code-portrait-wrapper { 2 | margin-bottom: 20px; 3 | overflow: hidden; 4 | position: relative; 5 | width: 100%; 6 | } 7 | 8 | #mystic-code-portrait-wrapper:before { 9 | content: ""; 10 | display: block; 11 | padding-top: 100%; 12 | } 13 | 14 | .mystic-code-portrait { 15 | display: block; 16 | left: 0; 17 | position: absolute; 18 | top: 0; 19 | width: 80%; 20 | } 21 | 22 | .mystic-code-portrait:nth-child(even) { 23 | left: 40%; 24 | } 25 | 26 | .mystic-code-portrait > img { 27 | display: block; 28 | object-fit: cover; 29 | width: 100%; 30 | } 31 | -------------------------------------------------------------------------------- /packages/db/src/Setting/Theme.tsx: -------------------------------------------------------------------------------- 1 | export enum Theme { 2 | DEFAULT = "default", 3 | CERULEAN = "cerulean", 4 | COSMO = "cosmo", 5 | CYBORG = "cyborg", 6 | DARKLY = "darkly", 7 | FLATLY = "flatly", 8 | JOURNAL = "journal", 9 | LITERA = "litera", 10 | LUMEN = "lumen", 11 | LUX = "lux", 12 | MATERIA = "materia", 13 | MINTY = "minty", 14 | PULSE = "pulse", 15 | SANDSTONE = "sandstone", 16 | SIMPLEX = "simplex", 17 | SKETCHY = "sketchy", 18 | SLATE = "slate", 19 | SOLAR = "solar", 20 | SPACELAB = "spacelab", 21 | SUPERHERO = "superhero", 22 | UNITED = "united", 23 | YETI = "yeti", 24 | } 25 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Item/describeUse.ts: -------------------------------------------------------------------------------- 1 | import { Item } from "@atlasacademy/api-connector"; 2 | 3 | import { toTitleCase } from "../Helpers"; 4 | 5 | export default function (use: Item.ItemUse | string): string { 6 | switch (use) { 7 | case "skill & ascension": 8 | return "Skill Up & Ascension Material"; 9 | case Item.ItemUse.SKILL: 10 | return "Skill Up Material"; 11 | case Item.ItemUse.ASCENSION: 12 | return "Ascension Material"; 13 | case Item.ItemUse.COSTUME: 14 | return "Costume Unlock Material"; 15 | default: 16 | return toTitleCase(use); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/paper-moon/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "module": "esnext", 13 | "moduleResolution": "node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Change.ts: -------------------------------------------------------------------------------- 1 | interface mstSvt { 2 | id: number; 3 | type: number; 4 | collectionNo: number; 5 | name: number; 6 | } 7 | 8 | interface mstObject { 9 | id: number; 10 | name: string; 11 | } 12 | 13 | export interface Change { 14 | /** Hash of the commit producing this change. */ 15 | commit: string; 16 | /** Commit timestamp, represented in seconds since UNIX epoch. */ 17 | timestamp: string; 18 | 19 | changes: { 20 | svt: mstSvt[]; 21 | ce: mstSvt[]; 22 | skill: mstObject[]; 23 | buff: mstObject[]; 24 | np: mstObject[]; 25 | func: mstObject[]; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/BattlePoint.ts: -------------------------------------------------------------------------------- 1 | export interface BattlePointPhase { 2 | phase: number; 3 | value: number; 4 | name: string; 5 | effectId: number; 6 | } 7 | 8 | export enum BattlePointFlag { 9 | NONE = "none", 10 | NOT_TARGET_OTHER_PLAYER = "notTargetOtherPlayer", 11 | HIDE_UI_GAUGE_ALL_TIME = "hideUiGaugeAllTime", 12 | HIDE_UI_GAUGE_WHEN_CANT_ADD_POINT = "hideUiGaugeWhenCantAddPoint", 13 | HIDE_UI_GAUGE_WHEN_CANT_ADD_POINT_AND_FOLLOWER_SUPPORT = "hideUiGaugeWhenCantAddPointAndFollowerSupport", 14 | } 15 | 16 | export interface BattlePoint { 17 | id: number; 18 | flags: BattlePointFlag[]; 19 | phases: BattlePointPhase[]; 20 | } 21 | -------------------------------------------------------------------------------- /packages/db/src/Page/FaqPage.css: -------------------------------------------------------------------------------- 1 | ol.faq-list { 2 | padding-left: 1.5em; 3 | } 4 | 5 | ol.faq-toc { 6 | padding-left: 1em; 7 | } 8 | 9 | ol.faq-list > li { 10 | font-size: 1.75rem; 11 | font-weight: 500; 12 | } 13 | 14 | ol.faq-list > li > ol { 15 | font-size: 1rem; 16 | font-weight: normal; 17 | line-height: 1.5; 18 | padding: 0; 19 | margin-top: 1em; 20 | } 21 | 22 | ol.faq-list > li > ol > li { 23 | margin-bottom: 1em; 24 | } 25 | 26 | .faq-link-hover-target .faq-link-icon { 27 | text-decoration: none; 28 | color: inherit; 29 | visibility: hidden; 30 | } 31 | 32 | .faq-link-hover-target:hover .faq-link-icon { 33 | visibility: visible; 34 | } 35 | -------------------------------------------------------------------------------- /packages/battle/src/Trait/checkAllTrait.ts: -------------------------------------------------------------------------------- 1 | import { Trait } from "@atlasacademy/api-connector"; 2 | 3 | import { getNum } from "./getTraitNums"; 4 | 5 | export const checkAllTrait = (self?: T[], target?: T[]): boolean => { 6 | if (target === undefined || self === undefined || target.length === 0) return true; 7 | if (self.length === 0) return false; 8 | 9 | const selfNums = self.map((trait) => getNum(trait)); 10 | const targetNums = target.map((trait) => getNum(trait)); 11 | 12 | for (let selfNum of targetNums) { 13 | if (!selfNums.includes(selfNum)) { 14 | return false; 15 | } 16 | } 17 | 18 | return true; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/SvttAttrDestriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Attribute } from "@atlasacademy/api-connector"; 4 | 5 | import useApi from "../Hooks/useApi"; 6 | 7 | export const SvtAttrDescriptor = ({ attribute }: { attribute: Attribute.Attribute }) => { 8 | const { t } = useTranslation(); 9 | return <>{t("SvtAttribute." + attribute)}; 10 | }; 11 | 12 | export const AttributeDescriptor = ({ attributeId }: { attributeId: number }) => { 13 | const { data: enumList } = useApi("enumList"); 14 | if (enumList === undefined) return <>; 15 | 16 | return ; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/Sections/describeTeamSection.ts: -------------------------------------------------------------------------------- 1 | import { Func } from "@atlasacademy/api-connector"; 2 | 3 | import { BasePartial, ParticlePartial, TextPartial } from "../../Descriptor"; 4 | 5 | export default function (func: Func.Func): BasePartial[] { 6 | const makePartials = (label: string): BasePartial[] => { 7 | return [new ParticlePartial("["), new TextPartial(label), new ParticlePartial("]")]; 8 | }; 9 | 10 | switch (func.funcTargetTeam) { 11 | case Func.FuncTargetTeam.PLAYER: 12 | return makePartials("Player"); 13 | case Func.FuncTargetTeam.ENEMY: 14 | return makePartials("Enemy"); 15 | default: 16 | return []; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/battle/src/Skill/BattleSkillFunc.ts: -------------------------------------------------------------------------------- 1 | import BattleFunc, { BattleFuncProps, BattleFuncState } from "../Func/BattleFunc"; 2 | import BattleSkill from "./BattleSkill"; 3 | 4 | export default class BattleSkillFunc extends BattleFunc { 5 | constructor(props: BattleFuncProps, state: BattleFuncState | null, parent: BattleSkill) { 6 | super( 7 | props, 8 | state ?? { 9 | dataVal: BattleFunc.dataVal(props.func, props.level, 1), 10 | overcharge: 1, 11 | }, 12 | parent, 13 | ); 14 | } 15 | 16 | clone(skill: BattleSkill): BattleSkillFunc { 17 | return new BattleSkillFunc(this.props, this.cloneState(), skill); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/db/src/Assets/cn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/api-connector/README.md: -------------------------------------------------------------------------------- 1 | # Atlas Academy API Connector 2 | 3 | A library to interface with https://api.atlasacademy.io 4 | 5 | ## Example 6 | 7 | ```typescript 8 | import { ApiConnector, Language, Region, ReverseData, Skill } from "@atlasacademy/api-connector"; 9 | 10 | const cacheDuration = 20 * 1000; 11 | const apiConnector = new ApiConnector({ 12 | host: "https://api.atlasacademy.io", 13 | region: Region.JP, 14 | language: Language.DEFAULT, 15 | }); 16 | 17 | function getSkill(id: number, reverse = true): Promise { 18 | const reverseConfig = { 19 | reverse: reverse, 20 | reverseData: ReverseData.BASIC, 21 | }; 22 | return apiConnector.skill(id, reverseConfig, cacheDuration); 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /packages/battle/src/Event/BattleDamageEvent.ts: -------------------------------------------------------------------------------- 1 | import { BattleAttackAction } from "../Action/BattleAttackAction"; 2 | import { BattleActor } from "../Actor/BattleActor"; 3 | import BattleEvent from "./BattleEvent"; 4 | 5 | export interface BattleDamageEventData { 6 | attack: BattleAttackAction; 7 | damage: number; 8 | npGainedOnAttack: number; 9 | npGainedOnDefence: number; 10 | stars: number; 11 | } 12 | 13 | export default class BattleDamageEvent extends BattleEvent { 14 | constructor( 15 | public actor: BattleActor, 16 | public target: BattleActor, 17 | public success: boolean, 18 | public reference: BattleDamageEventData, 19 | ) { 20 | super(actor, target, success, reference); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/EffectSections.ts: -------------------------------------------------------------------------------- 1 | import { BasePartial } from "../Descriptor"; 2 | 3 | export class EffectSection { 4 | public showing: boolean = true; 5 | public parts: BasePartial[] = []; 6 | public preposition?: string; 7 | 8 | constructor(preposition?: string) { 9 | this.preposition = preposition; 10 | } 11 | } 12 | 13 | export class EffectSections { 14 | public team = new EffectSection(); 15 | public chance = new EffectSection(); 16 | public action = new EffectSection(); 17 | public affects = new EffectSection(); 18 | public amount = new EffectSection("of"); 19 | public target = new EffectSection("to"); 20 | public duration = new EffectSection(); 21 | public scaling = new EffectSection(); 22 | } 23 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/VoiceActorDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | import { Link } from "react-router-dom"; 3 | 4 | import { Region } from "@atlasacademy/api-connector"; 5 | 6 | import { lang } from "../Setting/Manager"; 7 | 8 | const VoiceActorDescriptor = (props: { region: Region; cv?: string }) => { 9 | const query = props.cv === undefined ? "" : `?cv=${encodeURIComponent(props.cv)}`; 10 | const { t } = useTranslation(); 11 | return ( 12 | <> 13 | {t("Voice Actor")}:  14 | 15 | {props.cv} 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default VoiceActorDescriptor; 22 | -------------------------------------------------------------------------------- /packages/db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 | "types": ["vite/client", "vite-plugin-svgr/client"], 6 | "allowJs": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | "downlevelIteration": true, 19 | "noFallthroughCasesInSwitch": true 20 | }, 21 | "include": ["src"] 22 | } 23 | -------------------------------------------------------------------------------- /packages/battle/tests/Actor/BattleServantActor/traitTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleTeam } from "../../../src"; 4 | import { createBattle, servant } from "../../helpers"; 5 | 6 | describe("BattleServantActor traits", () => { 7 | it("check add trait buff", async () => { 8 | const actor = servant(156, BattleTeam.PLAYER), 9 | target = servant(153, BattleTeam.PLAYER), 10 | battle = createBattle(); 11 | 12 | battle.addActor(actor); 13 | battle.addActor(target); 14 | 15 | expect(target.traits().filter((trait) => trait.id === 304).length === 0); 16 | 17 | await actor.skill(4)?.activate(battle); 18 | expect(target.traits().filter((trait) => trait.id === 304).length === 1); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/db/src/Assets/kr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Flag of South Korea 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/paper-moon/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import { Provider } from "react-redux"; 4 | 5 | import * as serviceWorker from "./serviceWorker"; 6 | import App from "./App"; 7 | import { store } from "./app/store"; 8 | 9 | import "bootstrap/dist/css/bootstrap.min.css"; 10 | 11 | ReactDOM.render( 12 | 13 | 14 | 15 | 16 | , 17 | document.getElementById("root") 18 | ); 19 | 20 | // If you want your app to work offline and load faster, you can change 21 | // unregister() to register() below. Note this comes with some pitfalls. 22 | // Learn more about service workers: https://bit.ly/CRA-PWA 23 | serviceWorker.unregister(); 24 | -------------------------------------------------------------------------------- /packages/db-og-worker/webpack.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | const path = require("path"); 4 | 5 | module.exports = { 6 | entry: "./src/index.ts", 7 | output: { 8 | filename: "worker.js", 9 | path: path.join(__dirname, "dist"), 10 | }, 11 | devtool: "cheap-module-source-map", 12 | mode: "development", 13 | resolve: { 14 | extensions: [".ts", ".tsx", ".js"], 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.tsx?$/, 20 | loader: "ts-loader", 21 | options: { 22 | // transpileOnly is useful to skip typescript checks occasionally: 23 | // transpileOnly: true, 24 | }, 25 | }, 26 | ], 27 | }, 28 | }; 29 | -------------------------------------------------------------------------------- /packages/db/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "AA-DB", 3 | "name": "Atlas Academy DB", 4 | "icons": [ 5 | { 6 | "src": "logo192.png", 7 | "type": "image/png", 8 | "sizes": "192x192" 9 | }, 10 | { 11 | "src": "favicon-32x32.png", 12 | "type": "image/png", 13 | "sizes": "32x32" 14 | }, 15 | { 16 | "src": "favicon.ico", 17 | "sizes": "32x32", 18 | "type": "image/x-icon" 19 | }, 20 | { 21 | "src": "favicon-16x16.png", 22 | "type": "image/png", 23 | "sizes": "16x16" 24 | } 25 | ], 26 | "start_url": ".", 27 | "display": "standalone", 28 | "theme_color": "#000000", 29 | "background_color": "#ffffff" 30 | } 31 | -------------------------------------------------------------------------------- /packages/db/src/Hooks/useImageSize.ts: -------------------------------------------------------------------------------- 1 | import useWindowDimensions from "./useWindowDimensions"; 2 | 3 | const getSceneScale = (windowWidth: number, windowHeight: number, wideScreen: boolean) => { 4 | if (wideScreen) { 5 | if (windowWidth < 768) { 6 | return 4; 7 | } else if (windowWidth <= 1024) { 8 | return 2.5; 9 | } 10 | } 11 | if (windowWidth < 768) { 12 | return 3; 13 | } 14 | return 2; 15 | }; 16 | 17 | export function useImageSize(wideScreen: boolean) { 18 | const { windowWidth, windowHeight } = useWindowDimensions(), 19 | sceneScale = getSceneScale(windowWidth, windowHeight, wideScreen), 20 | height = (wideScreen ? 576 : 576) / sceneScale, 21 | width = (wideScreen ? 1344 : 1024) / sceneScale; 22 | return { height, width }; 23 | } 24 | -------------------------------------------------------------------------------- /packages/db/src/Hooks/useWindowDimensions.ts: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/a/36862446/10241289 2 | import { useEffect, useState } from "react"; 3 | 4 | function getWindowDimensions() { 5 | const { innerWidth: windowWidth, innerHeight: windowHeight } = window; 6 | return { 7 | windowWidth, 8 | windowHeight, 9 | }; 10 | } 11 | 12 | export default function useWindowDimensions() { 13 | const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); 14 | 15 | useEffect(() => { 16 | function handleResize() { 17 | setWindowDimensions(getWindowDimensions()); 18 | } 19 | 20 | window.addEventListener("resize", handleResize); 21 | return () => window.removeEventListener("resize", handleResize); 22 | }, []); 23 | 24 | return windowDimensions; 25 | } 26 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Bgm.ts: -------------------------------------------------------------------------------- 1 | import CondType from "../Enum/Cond"; 2 | import { Shop } from "./Shop"; 3 | 4 | export interface Bgm { 5 | id: number; 6 | name: string; 7 | fileName: string; 8 | notReleased: boolean; 9 | audioAsset?: string; 10 | } 11 | 12 | export interface BgmRelease { 13 | id: number; 14 | type: CondType; 15 | condGroup: number; 16 | targetIds: number[]; 17 | vals: number[]; 18 | priority: number; 19 | closedMessage: string; 20 | } 21 | 22 | export interface BgmEntity { 23 | id: number; 24 | name: string; 25 | originalName: string; 26 | fileName: string; 27 | audioAsset?: string; 28 | priority: number; 29 | detail: string; 30 | notReleased: boolean; 31 | shop?: Shop; 32 | logo: string; 33 | releaseConditions: BgmRelease[]; 34 | } 35 | -------------------------------------------------------------------------------- /packages/paper-moon/src/components/BattleDisplay/BattleEventDisplay.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ConnectedProps, connect } from "react-redux"; 3 | 4 | import { BattleEvent } from "../../app/battle/types"; 5 | import { RootState } from "../../app/store"; 6 | 7 | interface ExternalProps { 8 | event: BattleEvent; 9 | } 10 | 11 | const mapStateToProps = (state: RootState, props: ExternalProps) => ({ 12 | ...props, 13 | }), 14 | mapDispatchToProps = { 15 | // 16 | }, 17 | connector = connect(mapStateToProps, mapDispatchToProps); 18 | 19 | type Props = ConnectedProps; 20 | 21 | class BattleEventDisplay extends React.Component { 22 | render() { 23 | return
{this.props.event.description}
; 24 | } 25 | } 26 | 27 | export default connector(BattleEventDisplay); 28 | -------------------------------------------------------------------------------- /packages/db/src/Component/ButtonGrid.css: -------------------------------------------------------------------------------- 1 | #toggle-modal { 2 | margin: 2.5px 0; 3 | } 4 | 5 | #toggle-all { 6 | position: absolute; 7 | width: 75px; 8 | top: 0; 9 | left: 100%; 10 | transform: translateX(-100%); 11 | margin: 0; 12 | } 13 | 14 | #toggle-container { 15 | padding-top: 5px; 16 | width: 100%; 17 | max-height: 200px; 18 | position: relative; 19 | overflow: auto; 20 | margin: 5px 0; 21 | } 22 | 23 | #toggle-base { 24 | position: relative; 25 | } 26 | 27 | div#toggle-container h4 { 28 | display: none; 29 | } 30 | 31 | .toggle-button { 32 | margin: 2px 2.5px; 33 | } 34 | 35 | @media screen and (min-width: 1000px) { 36 | div#toggle-container h4 { 37 | display: block; 38 | } 39 | #toggle-all { 40 | content: "Toggle All"; 41 | width: 100px; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/paper-moon/src/components/BattleDisplay/Skill/BattleActorSkillIcon.css: -------------------------------------------------------------------------------- 1 | .battle-actor-skill-icon { 2 | cursor: pointer; 3 | display: block; 4 | margin: 0 auto; 5 | position: relative; 6 | width: 40px; 7 | } 8 | 9 | .battle-actor-skill-icon.inactive { 10 | cursor: default; 11 | } 12 | 13 | .battle-actor-skill-icon > .icon { 14 | display: block; 15 | width: 100%; 16 | } 17 | 18 | .battle-actor-skill-icon.inactive > .icon { 19 | filter: grayscale(100%); 20 | } 21 | 22 | .battle-actor-skill-icon > .cooldown { 23 | position: absolute; 24 | top: 50%; 25 | left: 50%; 26 | transform: translate(-50%, -50%); 27 | 28 | font-size: 20px; 29 | font-weight: bold; 30 | text-shadow: 31 | -2px -2px 0 #000, 32 | 2px -2px 0 #000, 33 | -2px 2px 0 #000, 34 | 2px 2px 0 #000; 35 | } 36 | -------------------------------------------------------------------------------- /packages/db/src/Component/FaceIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Entity } from "@atlasacademy/api-connector"; 4 | 5 | interface IProps { 6 | type?: Entity.EntityType; 7 | rarity?: number; 8 | location: string; 9 | height?: number | string; 10 | mightNotExist?: boolean; 11 | } 12 | 13 | class FaceIcon extends React.Component { 14 | render() { 15 | return ( 16 | {""} 24 | ); 25 | } 26 | } 27 | 28 | export default FaceIcon; 29 | -------------------------------------------------------------------------------- /packages/battle/src/Trait/checkTrait.ts: -------------------------------------------------------------------------------- 1 | import { Trait } from "@atlasacademy/api-connector"; 2 | 3 | import { getNum } from "./getTraitNums"; 4 | 5 | /** 6 | * Individuality::CheckIndividualities 7 | * @param self 8 | * @param target 9 | */ 10 | export const checkTrait = (self?: T[], target?: T[]): boolean => { 11 | if (target === undefined || self === undefined || target.length === 0) return true; 12 | if (self.length === 0) return false; 13 | 14 | const selfNums = self.map((trait) => getNum(trait)); 15 | const targetNums = target.map((trait) => getNum(trait)); 16 | 17 | for (let selfNum of selfNums) { 18 | for (let targetNum of targetNums) { 19 | if (selfNum === targetNum) { 20 | return true; 21 | } 22 | } 23 | } 24 | 25 | return false; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/db/src/Component/NumberSelector.tsx: -------------------------------------------------------------------------------- 1 | import { Form } from "react-bootstrap"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | interface ChangeEvent extends React.ChangeEvent {} 5 | 6 | export default function NumberSelector(props: { 7 | value: string | number | string[] | undefined; 8 | onChange: (ev: ChangeEvent) => void; 9 | min?: number; 10 | max?: number; 11 | placeholder?: string; 12 | }) { 13 | const { t } = useTranslation(); 14 | const placeholder = props.placeholder ? props.placeholder : t("Enter a positive integer"); 15 | return ( 16 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /packages/api-connector/src/Enum/Card.ts: -------------------------------------------------------------------------------- 1 | import { Trait } from "../Schema/Trait"; 2 | 3 | enum Card { 4 | NONE = "0", 5 | ARTS = "1", 6 | BUSTER = "2", 7 | QUICK = "3", 8 | EXTRA = "4", 9 | BLANK = "5", 10 | WEAK = "10", 11 | STRENGTH = "11", 12 | WEAKALT1 = "21", 13 | WEAKALT2 = "22", 14 | BUSTERALT1 = "60", 15 | ADDATTACK2 = "104", 16 | } 17 | 18 | export enum AttackType { 19 | ONE = "one", 20 | ALL = "all", 21 | } 22 | 23 | export default Card; 24 | 25 | export interface CardConstant { 26 | individuality: Trait[]; 27 | adjustAtk: number; 28 | adjustTdGauge: number; 29 | adjustCritical: number; 30 | addAtk: number; 31 | addTdGauge: number; 32 | addCritical: number; 33 | } 34 | 35 | export type CardConstantMap = { 36 | [key in Card]?: { 37 | [key in number]?: CardConstant; 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/store.ts: -------------------------------------------------------------------------------- 1 | import { Action, ThunkAction, configureStore } from "@reduxjs/toolkit"; 2 | 3 | import { battleSlice } from "./battle/slice"; 4 | import { battleSetupSlice } from "./battleSetup/slice"; 5 | import { enemyActorConfigSlice } from "./enemyActorConfig/slice"; 6 | import { playerActorConfigSlice } from "./playerActorConfig/slice"; 7 | 8 | export const store = configureStore({ 9 | reducer: { 10 | battle: battleSlice.reducer, 11 | battleSetup: battleSetupSlice.reducer, 12 | enemyActorConfig: enemyActorConfigSlice.reducer, 13 | playerActorConfig: playerActorConfigSlice.reducer, 14 | }, 15 | }); 16 | 17 | export type AppDispatch = typeof store.dispatch; 18 | export type RootState = ReturnType; 19 | export type AppThunk = ThunkAction>; 20 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/EntityReferenceDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { Entity, Region } from "@atlasacademy/api-connector"; 2 | 3 | import useApi from "../Hooks/useApi"; 4 | import EntityDescriptor from "./EntityDescriptor"; 5 | 6 | export default function EntityReferenceDescriptor(props: { 7 | region: Region; 8 | svtId: number; 9 | iconHeight?: number; 10 | tab?: string; 11 | forceType?: Entity.EntityType; 12 | }) { 13 | const { data: entity } = useApi("entityBasic", props.svtId); 14 | if (entity !== undefined) { 15 | return ( 16 | 23 | ); 24 | } else { 25 | return null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/IllustratorDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | import { Link } from "react-router-dom"; 3 | 4 | import { Region } from "@atlasacademy/api-connector"; 5 | 6 | import { lang } from "../Setting/Manager"; 7 | 8 | const IllustratorDescriptor = (props: { region: Region; illustrator?: string; hideTypeText?: boolean }) => { 9 | const { region, illustrator, hideTypeText } = props; 10 | const query = illustrator === undefined ? "" : `?illustrator=${encodeURIComponent(illustrator)}`; 11 | const { t } = useTranslation(); 12 | return ( 13 | <> 14 | {hideTypeText ? null : <>{t("Illustrator")}: } 15 | 16 | {illustrator} 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default IllustratorDescriptor; 23 | -------------------------------------------------------------------------------- /packages/db/src/Component/CollapsibleContent.css: -------------------------------------------------------------------------------- 1 | .collapsible-header-collapse-actions { 2 | font-size: 2em; 3 | line-height: 1; 4 | margin-top: 5%; 5 | transition: transform 0.3s ease; 6 | } 7 | 8 | .collapsible-header-rotate-arrow { 9 | transform: rotate(-180deg); 10 | } 11 | 12 | .collapsible-card { 13 | border-color: transparent; 14 | margin: 0; 15 | } 16 | 17 | .collapsible-header-separator { 18 | margin: 0; 19 | } 20 | 21 | .collapsible-header-tight, 22 | .collapsible-header { 23 | cursor: pointer; 24 | margin: 1em 0; 25 | display: flex; 26 | justify-content: space-between; 27 | } 28 | 29 | .collapsible-header-tight { 30 | margin: 0.5em 0; 31 | } 32 | 33 | .collapsible-header-arrow { 34 | text-align: right; 35 | align-self: center; 36 | margin-right: 1em; 37 | } 38 | 39 | .collapsible-header-title { 40 | margin-bottom: 0; 41 | } 42 | -------------------------------------------------------------------------------- /packages/battle/src/index.ts: -------------------------------------------------------------------------------- 1 | import { BattleCommandAction } from "./Action/BattleCommandAction"; 2 | import { Battle } from "./Battle"; 3 | import { BattleTeam } from "./Enum/BattleTeam"; 4 | import BattleAdjustNpEvent from "./Event/BattleAdjustNpEvent"; 5 | import BattleBuffEvent from "./Event/BattleBuffEvent"; 6 | import BattleDamageEvent from "./Event/BattleDamageEvent"; 7 | import BattleEvent from "./Event/BattleEvent"; 8 | import BattleRemoveBuffEvent from "./Event/BattleRemoveBuffEvent"; 9 | import BattleUnhandledEffectEvent from "./Event/BattleUnhandledEffectEvent"; 10 | import BattleFactory from "./Factory/BattleFactory"; 11 | 12 | const events = { 13 | BattleAdjustNpEvent, 14 | BattleBuffEvent, 15 | BattleDamageEvent, 16 | BattleRemoveBuffEvent, 17 | BattleUnhandledEffectEvent, 18 | }; 19 | 20 | export { Battle, BattleCommandAction, BattleEvent, BattleFactory, BattleTeam, events }; 21 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/randomAttackTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleRandomType } from "../../../../src/BattleRandom"; 4 | import { randomAttack } from "../../../../src/Func/Implementations/getDamageList"; 5 | import { createBattle } from "../../../helpers"; 6 | 7 | describe("getDamageList randomAttack", () => { 8 | it("test range", async () => { 9 | const battle = createBattle(); 10 | 11 | battle.random().setType(BattleRandomType.LOW); 12 | expect((await randomAttack(battle)).value()).to.be.closeTo(0.9, 0.0001); 13 | 14 | battle.random().setType(BattleRandomType.AVERAGE); 15 | expect((await randomAttack(battle)).value()).to.equal(1); 16 | 17 | battle.random().setType(BattleRandomType.HIGH); 18 | expect((await randomAttack(battle)).value()).to.be.closeTo(1.099, 0.0001); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/db/src/Page/Event/EventHeelPortrait.tsx: -------------------------------------------------------------------------------- 1 | import { Col, Row } from "react-bootstrap"; 2 | 3 | import { Event, Region } from "@atlasacademy/api-connector"; 4 | 5 | import { lang } from "../../Setting/Manager"; 6 | 7 | const EventHeelPortrait = ({ region, heelPortraits }: { region: Region; heelPortraits: Event.EventHeelPortrait[] }) => { 8 | return ( 9 | <> 10 | 11 | {heelPortraits.map((heel) => ( 12 | 13 | {`${heel.name}{" "} 14 |
{heel.name}
15 | 16 | ))} 17 |
18 | 19 | ); 20 | }; 21 | 22 | export default EventHeelPortrait; 23 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/EventAllOutDescription.tsx: -------------------------------------------------------------------------------- 1 | import { Region } from "@atlasacademy/api-connector"; 2 | 3 | import useApi from "../Hooks/useApi"; 4 | import { WarDescriptorId } from "./WarDescriptor"; 5 | 6 | const EventAllOutDescription = ({ 7 | region, 8 | eventId, 9 | alloutBattleId, 10 | }: { 11 | region: Region; 12 | eventId: number; 13 | alloutBattleId: number; 14 | }) => { 15 | const { data: alloutBattle } = useApi("eventAlloutBattle", eventId); 16 | const chosenBattle = (alloutBattle ?? []).find((battle) => battle.alloutBattleId === alloutBattleId); 17 | 18 | if (chosenBattle !== undefined) { 19 | return ; 20 | } 21 | return ( 22 | <> 23 | Event {eventId} All out battle {alloutBattleId} 24 | 25 | ); 26 | }; 27 | 28 | export default EventAllOutDescription; 29 | -------------------------------------------------------------------------------- /packages/db/src/Page/Quest/QuestDrops.tsx: -------------------------------------------------------------------------------- 1 | import { QuestEnemy, Region } from "@atlasacademy/api-connector"; 2 | 3 | import { QuestDropDescriptor } from "../../Component/QuestEnemy"; 4 | 5 | const QuestDrops = ({ 6 | region, 7 | drops, 8 | questHash, 9 | questHashAverageGoTo, 10 | }: { 11 | region: Region; 12 | drops: QuestEnemy.EnemyDrop[]; 13 | questHash?: string | "average"; 14 | questHashAverageGoTo?: () => void; 15 | }) => { 16 | if (drops.length === 0) { 17 | return <>; 18 | } 19 | 20 | drops.sort((a, b) => a.type.localeCompare(b.type) || a.objectId - b.objectId || a.num - b.num); 21 | 22 | return ( 23 | 29 | ); 30 | }; 31 | 32 | export default QuestDrops; 33 | -------------------------------------------------------------------------------- /packages/api-connector/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@atlasacademy/api-connector", 3 | "type": "commonjs", 4 | "version": "5.3.0", 5 | "description": "Library to interface with api.atlasacademy.io", 6 | "homepage": "https://github.com/atlasacademy/apps/tree/master/packages/api-connector", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1", 14 | "build": "tsc", 15 | "prepare": "tsc", 16 | "link": "npm run build && cd dist && npm link", 17 | "watch": "tsc -w --preserveWatchOutput" 18 | }, 19 | "license": "ISC", 20 | "devDependencies": { 21 | "typescript": "^5.8.2" 22 | }, 23 | "dependencies": { 24 | "axios": "^0.27.2" 25 | }, 26 | "publishConfig": { 27 | "access": "public" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/Value/describeGainHpFromTargetsValue.ts: -------------------------------------------------------------------------------- 1 | import { DataVal } from "@atlasacademy/api-connector"; 2 | 3 | import { BasePartial, ParticlePartial, ValuePartial, ValueType } from "../../Descriptor"; 4 | 5 | export default function (staticDataVal: DataVal.DataVal, mutatingDataVal: DataVal.DataVal): BasePartial[] { 6 | const funcId = staticDataVal.DependFuncId ?? mutatingDataVal.DependFuncId, 7 | from: BasePartial[] = [], 8 | to: BasePartial[] = []; 9 | 10 | if (mutatingDataVal.DependFuncVals?.Value !== undefined) { 11 | to.push(new ValuePartial(ValueType.NUMBER, mutatingDataVal.DependFuncVals.Value)); 12 | } 13 | 14 | if (from.length && to.length) { 15 | return from.concat([new ParticlePartial(" => ")], to); 16 | } else if (from.length) { 17 | return from; 18 | } else if (to.length) { 19 | return to; 20 | } 21 | 22 | return []; 23 | } 24 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/CommonConsumeDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { CommonConsume, Item, Region } from "@atlasacademy/api-connector"; 2 | 3 | import { IconDescriptorMap } from "./ItemDescriptor"; 4 | 5 | const CommonConsumeDescriptor = ({ 6 | region, 7 | commonConsume, 8 | itemMap, 9 | }: { 10 | region: Region; 11 | commonConsume: CommonConsume.CommonConsume; 12 | itemMap: Map; 13 | }) => { 14 | switch (commonConsume.type) { 15 | case CommonConsume.CommonConsumeType.ITEM: 16 | return ( 17 | <> 18 | ×  19 | {commonConsume.num} 20 | 21 | ); 22 | case CommonConsume.CommonConsumeType.AP: 23 | return <>{commonConsume.num} AP; 24 | } 25 | }; 26 | 27 | export default CommonConsumeDescriptor; 28 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/handleScalingSection.tsx: -------------------------------------------------------------------------------- 1 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 2 | 3 | import { funcUpdatesByLevel, funcUpdatesByOvercharge } from "../../Helper/FuncHelper"; 4 | import { FuncDescriptorSections } from "./FuncDescriptorSections"; 5 | 6 | export default function handleScalingSection( 7 | region: Region, 8 | sections: FuncDescriptorSections, 9 | func: Func.BasicFunc, 10 | dataVal: DataVal.DataVal 11 | ): void { 12 | const section = sections.scaling, 13 | parts = section.parts, 14 | isLevel = funcUpdatesByLevel(func), 15 | isOvercharge = funcUpdatesByOvercharge(func); 16 | 17 | if (!isLevel && !isOvercharge) { 18 | section.showing = false; 19 | return; 20 | } 21 | 22 | if (isLevel) { 23 | parts.push(""); 24 | } 25 | 26 | if (isOvercharge) { 27 | parts.push(""); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/db/src/App.css: -------------------------------------------------------------------------------- 1 | #app { 2 | margin-bottom: 100px; 3 | } 4 | 5 | .text-prewrap { 6 | white-space: pre-wrap; 7 | } 8 | 9 | .text-nowrap { 10 | white-space: nowrap; 11 | } 12 | 13 | .mx-0p5 { 14 | margin: 0 0.125em; 15 | } 16 | 17 | .w-25pct { 18 | width: 25%; 19 | } 20 | 21 | .w-50pct { 22 | width: 50%; 23 | } 24 | 25 | .w-1px { 26 | width: 1px; 27 | } 28 | 29 | .align-middle { 30 | vertical-align: middle; 31 | } 32 | 33 | .underline { 34 | text-decoration: underline; 35 | } 36 | 37 | .flex-row { 38 | flex-direction: row; 39 | } 40 | 41 | .lh-1 { 42 | line-height: 1em; 43 | } 44 | 45 | .lh-1p5 { 46 | line-height: 1.5em; 47 | } 48 | 49 | .lh-2 { 50 | line-height: 2em; 51 | } 52 | 53 | .lh-3 { 54 | line-height: 3em; 55 | } 56 | 57 | .fs-075 { 58 | font-size: 0.75em; 59 | } 60 | 61 | .reset-button-style { 62 | line-height: 1; 63 | padding: 0; 64 | vertical-align: baseline; 65 | } 66 | -------------------------------------------------------------------------------- /packages/api-descriptor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@atlasacademy/api-descriptor", 3 | "type": "commonjs", 4 | "version": "2.0.19", 5 | "description": "Library to describe entities from api.atlasacademy.io", 6 | "homepage": "https://github.com/atlasacademy/apps/tree/master/packages/api-descriptor", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1", 14 | "build": "tsc", 15 | "prepare": "tsc", 16 | "link": "npm run build && cd dist && npm link", 17 | "watch": "tsc -w --preserveWatchOutput" 18 | }, 19 | "license": "ISC", 20 | "devDependencies": { 21 | "typescript": "^5.8.2" 22 | }, 23 | "dependencies": { 24 | "@atlasacademy/api-connector": "^5.3.0" 25 | }, 26 | "publishConfig": { 27 | "access": "public" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/CardDescription.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Card, Region } from "@atlasacademy/api-connector"; 4 | import { CardDescriptor } from "@atlasacademy/api-descriptor"; 5 | 6 | import Description from "./Description"; 7 | 8 | interface IProps { 9 | region: Region; 10 | card: Card | number; 11 | } 12 | 13 | class CardDescription extends React.Component { 14 | static renderAsString(card: Card | number): string { 15 | const descriptor = CardDescriptor.describe(card); 16 | 17 | return "[" + Description.renderAsString(descriptor) + "]"; 18 | } 19 | 20 | render() { 21 | const descriptor = CardDescriptor.describe(this.props.card); 22 | 23 | return ( 24 | 25 | [ 26 | ] 27 | 28 | ); 29 | } 30 | } 31 | 32 | export default CardDescription; 33 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/WarDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | import { Region, War } from "@atlasacademy/api-connector"; 4 | 5 | import useApi from "../Hooks/useApi"; 6 | import { lang } from "../Setting/Manager"; 7 | 8 | export const getWarName = (war: War.WarBasic) => 9 | war.flags.indexOf(War.WarFlag.SUB_FOLDER) === -1 ? war.longName : war.name; 10 | 11 | export default function WarDescriptor({ region, war }: { region: Region; war: War.WarBasic }) { 12 | return ( 13 | 14 | {getWarName(war)} 15 | 16 | ); 17 | } 18 | 19 | export function WarDescriptorId(props: { region: Region; warId: number }) { 20 | const { data: war } = useApi("warBasic", props.warId); 21 | if (war !== undefined) { 22 | return ; 23 | } else { 24 | return <>War {props.warId}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/db/src/Page/Servant/ServantRelatedQuests.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Region } from "@atlasacademy/api-connector"; 4 | 5 | import QuestDescriptor from "../../Descriptor/QuestDescriptor"; 6 | 7 | const ServantRelatedQuests = (props: { region: Region; questIds: number[]; title?: string }) => { 8 | const { t } = useTranslation(); 9 | if (props.questIds.length > 0) { 10 | return ( 11 | <> 12 |

{props.title ?? t("Servant Quest")}

13 |
    14 | {props.questIds.map((questId) => ( 15 |
  • 16 | 17 |
  • 18 | ))} 19 |
20 | 21 | ); 22 | } else { 23 | return null; 24 | } 25 | }; 26 | 27 | export default ServantRelatedQuests; 28 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/CommandCode.ts: -------------------------------------------------------------------------------- 1 | import { Skill } from "./Skill"; 2 | 3 | export interface CommandCodeAssetMap { 4 | cc?: { 5 | [key: number]: string; 6 | }; 7 | } 8 | 9 | export interface CommandCodeAssets { 10 | charaGraph: CommandCodeAssetMap; 11 | faces: CommandCodeAssetMap; 12 | } 13 | 14 | export interface CommandCodeBasic { 15 | id: number; 16 | collectionNo: number; 17 | name: string; 18 | rarity: number; 19 | face: string; 20 | } 21 | 22 | export interface CommandCode { 23 | id: number; 24 | collectionNo: number; 25 | name: string; 26 | ruby: string; 27 | originalName: string; 28 | rarity: number; 29 | extraAssets: CommandCodeAssets; 30 | skills: Skill[]; 31 | illustrator: string; 32 | comment: string; 33 | } 34 | 35 | export interface CommandCodeBasic { 36 | id: number; 37 | collectionNo: number; 38 | name: string; 39 | rarity: number; 40 | face: string; 41 | } 42 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/classAttackRateTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { ClassName } from "@atlasacademy/api-connector"; 4 | 5 | import { classAttackRate } from "../../../../src/Func/Implementations/getDamageList"; 6 | import { createBattle } from "../../../helpers"; 7 | 8 | describe("getDamageList classAttackRate", () => { 9 | it("class defined", () => { 10 | const battle = createBattle(); 11 | 12 | expect(classAttackRate(battle, ClassName.SABER).value()).to.equal(1); 13 | expect(classAttackRate(battle, ClassName.LANCER).value()).to.be.closeTo(1.05, 0.0001); 14 | expect(classAttackRate(battle, ClassName.CASTER).value()).to.be.closeTo(0.9, 0.0001); 15 | }); 16 | 17 | it("class not defined", () => { 18 | expect(() => { 19 | const battle = createBattle(); 20 | 21 | classAttackRate(battle, ClassName.EXTRA); 22 | }).to.throw(Error); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.github/workflows/worker-publish.yaml: -------------------------------------------------------------------------------- 1 | name: Cloudflare Worker Publish 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | deploy: 11 | runs-on: ubuntu-latest 12 | name: Deploy 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: '20' 18 | cache: 'npm' 19 | cache-dependency-path: '**/package-lock.json' 20 | - name: Build sites 21 | shell: bash 22 | run: | 23 | sudo apt-get install -y moreutils 24 | bash netlify_build.sh | ts -s '(%M:%.S)]' | ts '[%.T' 25 | - name: Install worker dependencies 26 | working-directory: 'packages/db-og-worker' 27 | run: npm ci 28 | - name: Publish to Cloudflare Worker 29 | working-directory: 'packages/db-og-worker' 30 | env: 31 | CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }} 32 | run: npx wrangler deploy 33 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/BuffValueDescription.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Buff, DataVal, Region } from "@atlasacademy/api-connector"; 4 | import { BuffDescriptor } from "@atlasacademy/api-descriptor"; 5 | 6 | import Description from "./Description"; 7 | 8 | interface IProps { 9 | region: Region; 10 | buff: Buff.Buff; 11 | dataVal: DataVal.DataVal; 12 | } 13 | 14 | class BuffValueDescription extends React.Component { 15 | static renderAsString(buff: Buff.Buff, dataVal: DataVal.DataVal): string { 16 | const descriptor = BuffDescriptor.describeValue(buff, dataVal); 17 | 18 | return descriptor ? Description.renderAsString(descriptor) : "-"; 19 | } 20 | 21 | render() { 22 | const descriptor = BuffDescriptor.describeValue(this.props.buff, this.props.dataVal); 23 | 24 | return descriptor ? : "-"; 25 | } 26 | } 27 | 28 | export default BuffValueDescription; 29 | -------------------------------------------------------------------------------- /packages/db-og-worker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "db-og-worker", 3 | "private": true, 4 | "main": "worker.js", 5 | "scripts": { 6 | "build": "webpack", 7 | "format": "prettier --write '*.{json,js}' 'src/**/*.{js,ts}' 'test/**/*.{js,ts}'", 8 | "lint": "eslint --max-warnings=0 src && prettier --check '*.{json,js}' 'src/**/*.{js,ts}' 'test/**/*.{js,ts}'" 9 | }, 10 | "license": "MIT", 11 | "eslintConfig": { 12 | "root": true, 13 | "extends": [ 14 | "typescript", 15 | "prettier" 16 | ] 17 | }, 18 | "devDependencies": { 19 | "@cloudflare/kv-asset-handler": "^0.3.4", 20 | "@cloudflare/workers-types": "^4.20241022.0", 21 | "@typescript-eslint/eslint-plugin": "^8.12.1", 22 | "@typescript-eslint/parser": "^8.12.1", 23 | "eslint": "^8.57.1", 24 | "eslint-config-typescript": "^3.0.0", 25 | "typescript": "^5.6.3", 26 | "wrangler": "^3.83.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/db/src/Component/SkillGroupOverWrite.tsx: -------------------------------------------------------------------------------- 1 | import { Region, Skill } from "@atlasacademy/api-connector"; 2 | 3 | import EffectBreakdown from "../Breakdown/EffectBreakdown"; 4 | import { lang } from "../Setting/Manager"; 5 | 6 | const SkillGroupOverWrite = ({ 7 | region, 8 | overwrites, 9 | levels, 10 | }: { 11 | region: Region; 12 | overwrites: Skill.SkillGroupOverwrite[]; 13 | levels?: number; 14 | }) => { 15 | const overwrite = overwrites[0]; 16 | const title = `Overwrite Effect from ${new Date(overwrite.startedAt * 1000).toLocaleString()} to ${new Date( 17 | overwrite.endedAt * 1000 18 | ).toLocaleString()}`; 19 | 20 | return ( 21 | <> 22 |

23 | {overwrite.detail} 24 |

25 | 26 | 27 | ); 28 | }; 29 | 30 | export default SkillGroupOverWrite; 31 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/handleTeamSection.tsx: -------------------------------------------------------------------------------- 1 | import { faDragon, faUser } from "@fortawesome/free-solid-svg-icons"; 2 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 3 | 4 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 5 | 6 | import { FuncDescriptorSections } from "./FuncDescriptorSections"; 7 | 8 | export default function handleTeamSection( 9 | region: Region, 10 | sections: FuncDescriptorSections, 11 | func: Func.BasicFunc, 12 | dataVal: DataVal.DataVal 13 | ): void { 14 | const section = sections.team, 15 | parts = section.parts; 16 | 17 | if (func.funcTargetTeam === Func.FuncTargetTeam.PLAYER) 18 | parts.push(); 19 | else if (func.funcTargetTeam === Func.FuncTargetTeam.ENEMY) 20 | parts.push(); 21 | else section.showing = false; 22 | } 23 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/FuncValueDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 4 | import { FuncDescriptor } from "@atlasacademy/api-descriptor"; 5 | 6 | import Description from "./Description"; 7 | 8 | interface IProps { 9 | region: Region; 10 | func: Func.BasicFunc; 11 | staticDataVal: DataVal.DataVal; 12 | dataVal: DataVal.DataVal; 13 | hideRate?: boolean; 14 | dependFunc?: Func.BasicFunc; 15 | } 16 | 17 | class FuncValueDescriptor extends React.Component { 18 | render() { 19 | const descriptor = FuncDescriptor.describeValue( 20 | this.props.func, 21 | this.props.staticDataVal, 22 | this.props.dataVal, 23 | this.props.hideRate, 24 | this.props.dependFunc 25 | ); 26 | 27 | return descriptor ? : "-"; 28 | } 29 | } 30 | 31 | export default FuncValueDescriptor; 32 | -------------------------------------------------------------------------------- /packages/db/src/Component/ScriptDialogueLine.css: -------------------------------------------------------------------------------- 1 | .scriptDialogueText-small { 2 | position: relative; 3 | top: -0.125em; 4 | font-size: 0.75em; 5 | } 6 | 7 | .scriptDialogueText-medium { 8 | /* [f medium] seems to always appear before [messageShake] */ 9 | /* and the text size is the same */ 10 | font-size: 1em; 11 | } 12 | 13 | .scriptDialogueText-large { 14 | font-size: 1.5em; 15 | } 16 | 17 | .scriptDialogueText-x-large { 18 | font-size: 2em; 19 | } 20 | 21 | img.dialogueTextImage { 22 | height: 1.5em; 23 | } 24 | 25 | ruby > img.dialogueTextImage { 26 | margin-top: 2em; 27 | } 28 | 29 | /* The best for this is probably ::first-line but margin-top doesn't work with it */ 30 | /* This is probably good enough since it's rare to have 2 berserker images on the same line */ 31 | ruby:nth-of-type(1) > img.dialogueTextImage { 32 | margin-top: 1em; 33 | } 34 | 35 | rt.dialogueTextImageRuby { 36 | font-size: 1em; 37 | } 38 | 39 | ruby.dialogueRuby > rt { 40 | font-size: 0.75em; 41 | } 42 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.233.0/containers/javascript-node/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 18, 16, 14, 18-bullseye, 16-bullseye, 14-bullseye, 18-buster, 16-buster, 14-buster 4 | ARG VARIANT="18-bullseye" 5 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} 6 | 7 | # [Optional] Uncomment this section to install additional OS packages. 8 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 9 | # && apt-get -y install --no-install-recommends 10 | 11 | # [Optional] Uncomment if you want to install an additional version of node using nvm 12 | # ARG EXTRA_NODE_VERSION=10 13 | # RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" 14 | 15 | # [Optional] Uncomment if you want to install more global node modules 16 | # RUN su node -c "npm install -g " 17 | -------------------------------------------------------------------------------- /packages/battle/tests/Actor/PerfectBattleActorTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleActorLogic } from "../../dist/Actor/BattleActor"; 4 | import { BattleTeam } from "../../src"; 5 | import { createBattle, servant } from "../helpers"; 6 | 7 | describe("PerfectBattleActor", () => { 8 | it("func target trait", async () => { 9 | const setup = async (logic: BattleActorLogic) => { 10 | const actor = servant(15, BattleTeam.PLAYER), // euryale, 11 | target = servant(2, BattleTeam.ENEMY, { logic }), // artoria 12 | battle = createBattle(); 13 | 14 | battle.addActor(actor); 15 | battle.addActor(target); 16 | 17 | await actor.skill(2)?.activate(battle); 18 | 19 | return target; 20 | }; 21 | 22 | expect((await setup(BattleActorLogic.NORMAL)).buffs().hasTrait(3012, true)).to.be.false; 23 | 24 | expect((await setup(BattleActorLogic.PERFECT)).buffs().hasTrait(3012, true)).to.be.true; 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/db/src/Component/BuffIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import "./BuffIcon.css"; 4 | 5 | interface IProp { 6 | location: string; 7 | alt?: string; 8 | height?: number; 9 | passiveFrame?: boolean; 10 | hideState?: boolean; 11 | } 12 | 13 | class BuffIcon extends React.Component { 14 | render() { 15 | const classNames = ["buff-icon"]; 16 | if (this.props.passiveFrame) classNames.push("passive-frame"); 17 | if (this.props.hideState) classNames.push("hide-state"); 18 | 19 | return ( 20 | {this.props.alt 31 | ); 32 | } 33 | } 34 | 35 | export default BuffIcon; 36 | -------------------------------------------------------------------------------- /packages/db/src/Page/CommandCode/CommandCodePortrait.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { CommandCode } from "@atlasacademy/api-connector"; 4 | 5 | import "./CommandCodePortrait.css"; 6 | 7 | interface IProps { 8 | commandCode: CommandCode.CommandCode; 9 | } 10 | 11 | class CommandCodePortrait extends React.Component { 12 | private asset(): string | undefined { 13 | const assetMap = this.props.commandCode.extraAssets.charaGraph.cc; 14 | 15 | return assetMap ? Object.values(assetMap).shift() : undefined; 16 | } 17 | 18 | render() { 19 | const asset = this.asset(); 20 | 21 | return ( 22 |
23 | {this.props.commandCode.name} 30 |
31 | ); 32 | } 33 | } 34 | 35 | export default CommandCodePortrait; 36 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/enemyActorConfig/slice.ts: -------------------------------------------------------------------------------- 1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit"; 2 | 3 | import { EnemyActorConfigServantOptions, EnemyActorConfigState } from "./types"; 4 | 5 | const initialState: EnemyActorConfigState = { 6 | open: false, 7 | loading: false, 8 | }; 9 | 10 | export const enemyActorConfigSlice = createSlice({ 11 | name: "enemyActorConfig", 12 | initialState, 13 | reducers: { 14 | setLoading: (state, action: PayloadAction) => { 15 | state.loading = action.payload; 16 | }, 17 | setOpen: (state, action: PayloadAction) => { 18 | state.open = action.payload; 19 | }, 20 | setServant: (state, action: PayloadAction) => { 21 | state.servant = action.payload; 22 | }, 23 | setServantOptions: (state, action: PayloadAction) => { 24 | state.servantOptions = action.payload; 25 | }, 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /packages/db/src/Component/CardType.css: -------------------------------------------------------------------------------- 1 | .card-type { 2 | display: inline-block; 3 | height: 1em; 4 | position: relative; 5 | } 6 | 7 | .card-type-ratio { 8 | height: 100%; 9 | } 10 | 11 | .card-type-icon, 12 | .card-type-text { 13 | height: 100%; 14 | width: auto; 15 | left: 0; 16 | position: absolute; 17 | top: 0; 18 | } 19 | 20 | .card-type-icon { 21 | /** 22 | 133 / 185 23 | */ 24 | height: calc(133% / 1.85); 25 | left: 10%; 26 | /** 27 | (185 - 133) / 185 / 2 28 | 52 / 370 29 | */ 30 | top: calc(52% / 3.7); 31 | } 32 | 33 | .card-type-text { 34 | /** 35 | 73 / 150 36 | */ 37 | height: calc(73% / 1.5); 38 | /** 39 | (150 - 73) / 150 / 2 40 | 77 / 300 41 | */ 42 | top: calc(77% / 3); 43 | } 44 | 45 | .card-type.extra > .card-type-text { 46 | /** 47 | 100 / 200 48 | */ 49 | height: 50%; 50 | /** 51 | (200 - 100) / 200 / 2 52 | 100 / 400 53 | */ 54 | top: 25%; 55 | } 56 | -------------------------------------------------------------------------------- /packages/battle/src/NoblePhantasm/BattleNoblePhantasmFunc.ts: -------------------------------------------------------------------------------- 1 | import BattleFunc, { BattleFuncProps, BattleFuncState } from "../Func/BattleFunc"; 2 | import BattleNoblePhantasm from "./BattleNoblePhantasm"; 3 | 4 | export default class BattleNoblePhantasmFunc extends BattleFunc { 5 | constructor( 6 | public props: BattleFuncProps, 7 | state: BattleFuncState | null, 8 | parent: BattleNoblePhantasm, 9 | ) { 10 | super( 11 | props, 12 | { 13 | dataVal: BattleFunc.dataVal(props.func, props.level, 1), 14 | overcharge: 1, 15 | }, 16 | parent, 17 | ); 18 | } 19 | 20 | clone(np: BattleNoblePhantasm): BattleNoblePhantasmFunc { 21 | return new BattleNoblePhantasmFunc(this.props, this.cloneState(), np); 22 | } 23 | 24 | setOvercharge(overcharge: number) { 25 | this.state.overcharge = overcharge; 26 | this.state.dataVal = BattleFunc.dataVal(this.props.func, this.props.level, overcharge); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/db/src/Page/ClassBoardPage.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | import { Region } from "@atlasacademy/api-connector"; 4 | 5 | import { ClassBoardProvider } from "../Contexts/ClassBoard"; 6 | import Manager from "../Setting/Manager"; 7 | import ClassBoardBreakdown from "./ClassBoard/ClassBoardBreakdown"; 8 | import ClassBoardMap from "./ClassBoard/ClassBoardMap"; 9 | import ClassBoardNavigation from "./ClassBoard/ClassBoardNavigation"; 10 | 11 | interface Props { 12 | region: Region; 13 | id?: string; 14 | } 15 | 16 | const ClassBoardPage: React.FC = ({ region, id }) => { 17 | useEffect(() => { 18 | Manager.setRegion(region); 19 | document.title = `[${region}] Class Board - Atlas Academy DB`; 20 | }, [region]); 21 | 22 | return ( 23 | 24 | 25 | 26 | 27 | 28 | ); 29 | }; 30 | 31 | export default ClassBoardPage; 32 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Card/describe.ts: -------------------------------------------------------------------------------- 1 | import { Card } from "@atlasacademy/api-connector"; 2 | 3 | import { BasePartial, Descriptor, TextPartial, ValuePartial, ValueType } from "../Descriptor"; 4 | import { toTitleCase } from "../Helpers"; 5 | 6 | const cardIdMap = new Map([ 7 | [0, Card.NONE], 8 | [1, Card.ARTS], 9 | [2, Card.BUSTER], 10 | [3, Card.QUICK], 11 | [4, Card.EXTRA], 12 | [5, Card.BLANK], 13 | [10, Card.WEAK], 14 | [11, Card.STRENGTH], 15 | ]); 16 | 17 | export default function (card: Card | number): Descriptor { 18 | const partials: BasePartial[] = [], 19 | cardType: Card | undefined = typeof card === "number" ? cardIdMap.get(card) : card; 20 | 21 | if (cardType) { 22 | partials.push(new TextPartial(toTitleCase(cardType))); 23 | } else if (typeof card === "number") { 24 | partials.push(new ValuePartial(ValueType.UNKNOWN, card)); 25 | } else { 26 | partials.push(new TextPartial(toTitleCase(card))); 27 | } 28 | 29 | return new Descriptor(partials); 30 | } 31 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/MysticCode.ts: -------------------------------------------------------------------------------- 1 | import { CommonRelease } from "./CommonRelease"; 2 | import { Skill } from "./Skill"; 3 | 4 | export interface MysticCodeAssets { 5 | item: { 6 | male: string; 7 | female: string; 8 | }; 9 | masterFace: { 10 | male: string; 11 | female: string; 12 | }; 13 | masterFigure: { 14 | male: string; 15 | female: string; 16 | }; 17 | } 18 | 19 | export interface MysticCodeBasic { 20 | id: number; 21 | name: string; 22 | item: { 23 | male: string; 24 | female: string; 25 | }; 26 | } 27 | 28 | export interface MysticCodeCostume { 29 | id: number; 30 | releaseConditions: CommonRelease[]; 31 | extraAssets: MysticCodeAssets; 32 | } 33 | 34 | export interface MysticCode { 35 | id: number; 36 | name: string; 37 | originalName: string; 38 | detail: string; 39 | maxLv: number; 40 | extraAssets: MysticCodeAssets; 41 | skills: Skill[]; 42 | expRequired: number[]; 43 | costumes: MysticCodeCostume[]; 44 | } 45 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/FuncDescriptorSections.tsx: -------------------------------------------------------------------------------- 1 | import { Renderable } from "../../Helper/OutputHelper"; 2 | 3 | export class FuncDescriptorSection { 4 | public showing: boolean = true; 5 | public parts: Renderable[] = []; 6 | public preposition?: string; 7 | 8 | constructor(preposition?: string) { 9 | this.preposition = preposition; 10 | } 11 | } 12 | 13 | export class FuncDescriptorSections { 14 | public option = new FuncDescriptorSection(); 15 | public team = new FuncDescriptorSection(); 16 | public condition = new FuncDescriptorSection(); 17 | public chance = new FuncDescriptorSection(); 18 | public action = new FuncDescriptorSection(); 19 | public amount = new FuncDescriptorSection("of"); 20 | public onField = new FuncDescriptorSection(); 21 | public affects = new FuncDescriptorSection(); 22 | public target = new FuncDescriptorSection("to"); 23 | public duration = new FuncDescriptorSection(); 24 | public linkage = new FuncDescriptorSection(); 25 | public scaling = new FuncDescriptorSection(); 26 | } 27 | -------------------------------------------------------------------------------- /packages/db/src/Component/CopyToClipboard.tsx: -------------------------------------------------------------------------------- 1 | import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons"; 2 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 3 | import copy from "copy-to-clipboard"; 4 | import { useState } from "react"; 5 | 6 | import { t } from "../i18n"; 7 | 8 | const CopyToClipboard = ({ text, title }: { text: string; title?: string }) => { 9 | const [copied, setCopied] = useState(false); 10 | 11 | const buttonTitle = title ? title : t("Copy text to clipboard", { text }); 12 | 13 | if (copied) return ; 14 | 15 | return ( 16 | { 21 | copy(text); 22 | setCopied(true); 23 | setTimeout(() => { 24 | setCopied(false); 25 | }, 1000); 26 | }} 27 | /> 28 | ); 29 | }; 30 | 31 | export default CopyToClipboard; 32 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/extractStaticDataVal.ts: -------------------------------------------------------------------------------- 1 | import { DataVal } from "@atlasacademy/api-connector"; 2 | 3 | import getStaticDataValFields from "./extractStaticDataValFields"; 4 | 5 | export default function extractStaticDataVal(dataVals: DataVal.DataVal[]): DataVal.DataVal { 6 | if (!dataVals.length) return {}; 7 | 8 | const fields = getStaticDataValFields(dataVals); 9 | const staticVals: DataVal.DataVal = {}; 10 | const hasDependingVals = dataVals.filter((val) => val.DependFuncVals !== undefined).length > 0; 11 | 12 | const dependingVals: DataVal.DataVal[] | undefined = hasDependingVals 13 | ? dataVals.map((val) => (val.DependFuncVals ?? {}) as DataVal.DataVal) 14 | : undefined; 15 | 16 | const dependingStaticValues = dependingVals ? extractStaticDataVal(dependingVals) : undefined; 17 | 18 | for (let x in fields) { 19 | // @ts-ignore 20 | staticVals[fields[x]] = dataVals[0][fields[x]]; 21 | } 22 | 23 | if (hasDependingVals) staticVals.DependFuncVals = dependingStaticValues; 24 | 25 | return staticVals; 26 | } 27 | -------------------------------------------------------------------------------- /packages/db/src/Page/MysticCode/MysticCodeExp.tsx: -------------------------------------------------------------------------------- 1 | import { Table } from "react-bootstrap"; 2 | 3 | import { MysticCode } from "@atlasacademy/api-connector"; 4 | 5 | const MysticCodeExp = (props: { mysticCode: MysticCode.MysticCode }) => { 6 | const expTable = ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {[0].concat(props.mysticCode.expRequired).map((exp, i, expRequired) => ( 17 | 18 | 19 | 20 | 21 | 22 | ))} 23 | 24 |
LevelNext LevelTotal EXP
{i + 1}{(i + 1 < expRequired.length ? expRequired[i + 1] - exp : 0).toLocaleString()}{exp.toLocaleString()}
25 | ); 26 | return expTable; 27 | }; 28 | 29 | export default MysticCodeExp; 30 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/ServantDescriptorId.tsx: -------------------------------------------------------------------------------- 1 | import { Region, Servant } from "@atlasacademy/api-connector"; 2 | 3 | import EntityReferenceDescriptor from "./EntityReferenceDescriptor"; 4 | import { ServantDescriptorMap } from "./ServantDescriptor"; 5 | 6 | export default function ServantDescriptorId(props: { 7 | region: Region; 8 | id: number; 9 | servants?: Map; 10 | iconHeight?: number; 11 | tab?: string; 12 | }) { 13 | if (props.servants !== undefined) { 14 | return ( 15 | 22 | ); 23 | } else { 24 | return ( 25 | 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/db/src/Component/Navigation.css: -------------------------------------------------------------------------------- 1 | #navigation { 2 | z-index: 10; 3 | } 4 | 5 | #navigation .icons { 6 | font-size: 1.5em; 7 | line-height: 1; 8 | } 9 | 10 | #navigation .icons .flag { 11 | border: 1px solid white; 12 | border-radius: 5px; 13 | box-sizing: border-box; 14 | } 15 | 16 | #navigation .icons .flag.inactive { 17 | border: 0; 18 | opacity: 0.5; 19 | } 20 | 21 | #navigation .icons .flag > svg { 22 | width: 1.25em; 23 | height: 1em; 24 | } 25 | 26 | #navigation .icons > .row { 27 | flex-flow: nowrap; 28 | margin: 0 1px; 29 | } 30 | 31 | #navigation .icons > .row > .col { 32 | padding: 0; 33 | } 34 | 35 | #navigation .icons > .row > .col > * { 36 | justify-content: center; 37 | display: flex; 38 | } 39 | 40 | #nav-uilang .dropdown-toggle::after { 41 | content: unset; 42 | } 43 | 44 | .modal-close { 45 | border: 0; 46 | background: unset; 47 | color: #000; 48 | font-size: 1.75em; 49 | padding: 0.5rem; 50 | margin: -0.5rem -0.5rem -1rem auto; 51 | opacity: 0.5; 52 | } 53 | 54 | .modal-close:hover { 55 | opacity: 0.75; 56 | } 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Atlas Academy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Script.ts: -------------------------------------------------------------------------------- 1 | import { Quest } from "./Quest"; 2 | 3 | export interface ScriptExtendData { 4 | combineResultMultipleForm?: number; 5 | myroomForm?: number; 6 | faceSize?: number; 7 | faceSizeRect?: number[]; 8 | conds?: { condType: number; value: number }[]; 9 | } 10 | 11 | export interface SvtScript { 12 | extendData: ScriptExtendData; 13 | id: number; 14 | form: number; 15 | faceX: number; 16 | faceY: number; 17 | bgImageId: number; 18 | scale: number; 19 | offsetX: number; 20 | offsetY: number; 21 | offsetXMyroom: number; 22 | offsetYMyroom: number; 23 | } 24 | 25 | export interface ScriptSearchResult { 26 | scriptId: string; 27 | script: string; 28 | score: number; 29 | snippets: string[]; 30 | } 31 | 32 | export interface Script { 33 | scriptId: string; 34 | scriptSizeBytes: number; 35 | script: string; 36 | quests: Quest[]; 37 | } 38 | 39 | export type ScriptSearchOptions = { 40 | query: string; 41 | scriptFileName?: string; 42 | warId?: number[]; 43 | rawScript?: boolean; 44 | limit?: number; 45 | }; 46 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Buff/describeType.ts: -------------------------------------------------------------------------------- 1 | import { Buff } from "@atlasacademy/api-connector"; 2 | 3 | import { toTitleCase } from "../Helpers"; 4 | import { getUpDownBuffType } from "./BuffHelpers"; 5 | import { buffTriggerTypes, buffTypeDescriptions } from "./BuffTypes"; 6 | 7 | export default function (type: Buff.BuffType): string { 8 | const upDownBuffType = getUpDownBuffType(type), 9 | triggerType = buffTriggerTypes.get(type), 10 | typeDescription = buffTypeDescriptions.get(type); 11 | 12 | if (upDownBuffType) { 13 | if (upDownBuffType.up === type) { 14 | return `${upDownBuffType.description} Up`; 15 | } else { 16 | return `${upDownBuffType.description} Down`; 17 | } 18 | } else if (typeDescription) { 19 | return typeDescription; 20 | } else if (triggerType) { 21 | if (triggerType.counterNp) return "Counter NP"; 22 | return `Trigger Skill ${triggerType.when ? ` ${triggerType.when} ` : triggerType.after ? "after " : "before "}${ 23 | triggerType.event 24 | }`; 25 | } 26 | 27 | return toTitleCase(type); 28 | } 29 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/npMagnificationTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Card } from "@atlasacademy/api-connector"; 4 | 5 | import { BattleTeam } from "../../../../src"; 6 | import { BattleAttackAction } from "../../../../src/Action/BattleAttackAction"; 7 | import { npMagnification } from "../../../../src/Func/Implementations/getDamageList"; 8 | import { createBattle, servant } from "../../../helpers"; 9 | 10 | describe("getDamageList npMagnification", () => { 11 | it("check np buff", async () => { 12 | const actor = servant(65, BattleTeam.PLAYER), 13 | target = servant(17, BattleTeam.ENEMY), 14 | battle = createBattle(); 15 | 16 | battle.addActor(actor); 17 | battle.addActor(target); 18 | 19 | const attack = new BattleAttackAction(actor, Card.BUSTER, false, Card.BUSTER, false, true, 1); 20 | 21 | expect(npMagnification(attack, actor, target).value()).to.equal(0); 22 | 23 | await actor.skill(1)?.activate(battle); 24 | expect(npMagnification(attack, actor, target).value()).to.be.closeTo(0.17, 0.0001); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Buff/BuffHelpers.ts: -------------------------------------------------------------------------------- 1 | import { Buff } from "@atlasacademy/api-connector"; 2 | 3 | import { UpDownBuffType, buffTraitDescriptions, upDownBuffs } from "./BuffTypes"; 4 | 5 | export function getUpDownBuffType(type: Buff.BuffType): UpDownBuffType | undefined { 6 | for (let x in upDownBuffs) { 7 | if (upDownBuffs[x].up === type || upDownBuffs[x].down === type) return upDownBuffs[x]; 8 | } 9 | 10 | return undefined; 11 | } 12 | 13 | export function getTraitDescription(buff: Buff.BasicBuff): string | undefined { 14 | const traitIds = buff.vals.map((trait) => trait.id); 15 | 16 | let traitDescription: string | undefined = undefined, 17 | maxPriority = 1000; 18 | for (let x in traitIds) { 19 | const traitId = traitIds[x], 20 | description = buffTraitDescriptions.get(traitId); 21 | 22 | if (description !== undefined) { 23 | if (description.priority < maxPriority) { 24 | traitDescription = description.name; 25 | maxPriority = description.priority; 26 | } 27 | } 28 | } 29 | 30 | return traitDescription; 31 | } 32 | -------------------------------------------------------------------------------- /packages/db/src/Hooks/useScroll.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const getCurrentPosition = () => { 4 | const scrollLimit = 5 | Math.max( 6 | document.body.scrollHeight, 7 | document.body.offsetHeight, 8 | document.documentElement.clientHeight, 9 | document.documentElement.scrollHeight, 10 | document.documentElement.offsetHeight 11 | ) - window.innerHeight; 12 | const scrollPosition = window.scrollY; 13 | if (scrollLimit === 0) return 0; 14 | return scrollPosition / scrollLimit; 15 | }; 16 | 17 | /** 18 | * Return current scroll position from 0 to 1 19 | */ 20 | const useScroll = () => { 21 | const [scrollPosition, setScrollPosition] = useState(getCurrentPosition()); 22 | 23 | useEffect(() => { 24 | const scroll = () => { 25 | setScrollPosition(getCurrentPosition()); 26 | }; 27 | document.addEventListener("scroll", scroll); 28 | 29 | return () => document.removeEventListener("scroll", scroll); 30 | }, []); 31 | 32 | return scrollPosition; 33 | }; 34 | 35 | export default useScroll; 36 | -------------------------------------------------------------------------------- /packages/db/src/Component/ItemIcon.css: -------------------------------------------------------------------------------- 1 | .item-icon { 2 | display: inline-block; 3 | position: relative; 4 | } 5 | 6 | .item-icon-ratio { 7 | height: 100%; 8 | } 9 | 10 | .item-icon-bg, 11 | .item-icon-image, 12 | .item-icon-quantity { 13 | height: 100%; 14 | left: 0; 15 | position: absolute; 16 | top: 0; 17 | } 18 | 19 | .item-icon-image { 20 | object-fit: contain; 21 | height: 70%; 22 | left: 50%; 23 | margin-left: -40%; 24 | margin-top: -35%; 25 | top: 50%; 26 | width: 70%; 27 | } 28 | 29 | .item-icon-quantity { 30 | bottom: 5%; 31 | color: #ffffff; 32 | font-size: 0.75em; 33 | left: auto; 34 | height: 1.5em; 35 | right: 16%; 36 | /* From https://owumaro.github.io/text-stroke-generator/ */ 37 | text-shadow: 38 | rgb(0, 0, 0) 1px 0px 0px, 39 | rgb(0, 0, 0) 0.540302px 0.841471px 0px, 40 | rgb(0, 0, 0) -0.416147px 0.909297px 0px, 41 | rgb(0, 0, 0) -0.989992px 0.14112px 0px, 42 | rgb(0, 0, 0) -0.653644px -0.756802px 0px, 43 | rgb(0, 0, 0) 0.283662px -0.958924px 0px, 44 | rgb(0, 0, 0) 0.96017px -0.279416px 0px; 45 | top: auto; 46 | } 47 | -------------------------------------------------------------------------------- /packages/db/src/Page/WarMap/WarMap.css: -------------------------------------------------------------------------------- 1 | .warmap-parent { 2 | overflow: auto; 3 | } 4 | .warmap-container { 5 | position: relative; 6 | width: 1108px; 7 | overflow: hidden; 8 | z-index: 0; 9 | } 10 | .warmap { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | width: 100%; 15 | z-index: -1; 16 | } 17 | .warspot-fig { 18 | position: absolute; 19 | z-index: 50; 20 | } 21 | .warspot-img { 22 | position: absolute; 23 | height: 80px; 24 | transform: translate(-45%, -50%); 25 | z-index: 50; 26 | } 27 | .spot-name { 28 | display: inline-block; 29 | position: absolute; 30 | background-color: rgba(0, 0, 24, 0.8); 31 | color: #fff; 32 | white-space: nowrap; 33 | padding-left: 5px; 34 | padding-right: 5px; 35 | text-align: center; 36 | vertical-align: center; 37 | font-size: 0.9em; 38 | transform: translate(-50%); 39 | top: 35px; 40 | border-radius: 30px; 41 | z-index: 50; 42 | } 43 | .spot-road { 44 | overflow: hidden; 45 | position: absolute; 46 | z-index: 20; 47 | } 48 | .toggle-spots { 49 | margin: 5px 2.5px; 50 | } 51 | .toggle-spots:first-child { 52 | margin: 5px 2.5px 5px 0px; 53 | } 54 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Servant.ts: -------------------------------------------------------------------------------- 1 | import { Entity, EntityBasic, EntityScript, EntityType } from "./Entity"; 2 | import { Profile } from "./Profile"; 3 | 4 | export interface ServantScript extends EntityScript {} 5 | 6 | export interface Servant extends Entity { 7 | type: EntityType.NORMAL | EntityType.HEROINE | EntityType.ENEMY_COLLECTION_DETAIL; 8 | profile?: Profile; 9 | } 10 | 11 | export interface ServantWithLore extends Servant { 12 | profile: NonNullable; 13 | } 14 | 15 | export interface ServantBasic extends EntityBasic { 16 | type: EntityType.NORMAL | EntityType.HEROINE | EntityType.ENEMY_COLLECTION_DETAIL; 17 | } 18 | 19 | export enum ServantFrameType { 20 | BLACK = "black", 21 | BRONZE = "bronze", 22 | SILVER = "silver", 23 | GOLD = "gold", 24 | GOLD_RED = "goldRed", 25 | GOLD_RED_GREAT = "goldRedGreat", 26 | GOLD_BLACK = "goldBlack", 27 | GOLD_BLACK_GREAT = "goldBlackGreat", 28 | } 29 | 30 | export interface GrailCostInfo { 31 | qp: number; 32 | addLvMax: number; 33 | frameType: ServantFrameType; 34 | } 35 | 36 | export type GrailCostInfoMap = { 37 | [key in number]?: { 38 | [key in number]?: GrailCostInfo; 39 | }; 40 | }; 41 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/battle/types.ts: -------------------------------------------------------------------------------- 1 | import { Card } from "@atlasacademy/api-connector"; 2 | import { BattleTeam } from "@atlasacademy/battle"; 3 | 4 | export interface BattleStateActor { 5 | id: number; 6 | name: string; 7 | face?: string; 8 | team: BattleTeam; 9 | currentHealth: number; 10 | maxHealth: number; 11 | currentGauge: number; 12 | gaugeLineCount: number; 13 | gaugeLineMax: number; 14 | } 15 | 16 | export interface BattleStateActorSkill { 17 | actorId: number; 18 | position: number; 19 | name: string; 20 | icon?: string; 21 | available: boolean; 22 | cooldown: number; 23 | } 24 | 25 | export interface BattleQueuedAttack { 26 | actorId: number; 27 | card: Card; 28 | } 29 | 30 | export type BattleEvent = { 31 | actorId?: number; 32 | targetId?: number; 33 | description: string; 34 | }; 35 | 36 | export interface BattleState { 37 | running: boolean; 38 | actorSkills: BattleStateActorSkill[]; 39 | playerActing: boolean; 40 | playerAttacking: boolean; 41 | playerTurn: boolean; 42 | playerActors: BattleStateActor[]; 43 | enemyActors: BattleStateActor[]; 44 | queuedAttacks: BattleQueuedAttack[]; 45 | events: BattleEvent[]; 46 | } 47 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/SkillReferenceDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | import { Region, Skill } from "@atlasacademy/api-connector"; 5 | 6 | import Api from "../Api"; 7 | import SkillDescriptor from "./SkillDescriptor"; 8 | 9 | interface IProps { 10 | region: Region; 11 | id: number; 12 | } 13 | 14 | interface IState { 15 | skill?: Skill.Skill; 16 | } 17 | 18 | class SkillReferenceDescriptor extends React.Component { 19 | constructor(props: IProps) { 20 | super(props); 21 | 22 | this.state = {}; 23 | } 24 | 25 | async componentDidMount() { 26 | Api.skill(this.props.id).then((skill) => this.setState({ skill })); 27 | } 28 | 29 | static renderAsString(id: number): string { 30 | return `[Skill: ${id}]`; 31 | } 32 | 33 | render() { 34 | const route = `/${this.props.region}/skill/${this.props.id}`; 35 | 36 | if (this.state.skill === undefined) { 37 | return [Skill: {this.props.id}]; 38 | } 39 | 40 | return ; 41 | } 42 | } 43 | 44 | export default SkillReferenceDescriptor; 45 | -------------------------------------------------------------------------------- /packages/db/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react-swc"; 2 | import { defineConfig, splitVendorChunkPlugin } from "vite"; 3 | import eslint from "vite-plugin-eslint2"; 4 | import svgrPlugin from "vite-plugin-svgr"; 5 | 6 | export default defineConfig({ 7 | base: "/db/", 8 | plugins: [react(), eslint(), svgrPlugin(), splitVendorChunkPlugin()], 9 | server: { 10 | port: 3000, 11 | }, 12 | build: { 13 | target: "ios12", 14 | outDir: "build", 15 | commonjsOptions: { 16 | include: [], 17 | }, 18 | rollupOptions: { 19 | maxParallelFileOps: 100, 20 | }, 21 | chunkSizeWarningLimit: 1000, 22 | }, 23 | optimizeDeps: { 24 | // https://vitejs.dev/guide/dep-pre-bundling.html#monorepos-and-linked-dependencies 25 | include: ["@atlasacademy/api-connector", "@atlasacademy/api-descriptor"], 26 | // https://vitejs.dev/config/dep-optimization-options.html#optimizedeps-disabled 27 | // Setting this to false should enable optimizeDeps for both dev and build. 28 | // This way esbuild will convert dependencies to esm and we don't have to deal with @rollup/plugin-commonjs 29 | disabled: false, 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Gacha.ts: -------------------------------------------------------------------------------- 1 | import CondType from "../Enum/Cond"; 2 | import { CommonRelease } from "./CommonRelease"; 3 | import { PayType } from "./Shop"; 4 | 5 | export interface GachaStoryAdjust { 6 | idx: number; 7 | adjustId: number; 8 | condType: CondType; 9 | targetId: number; 10 | value: number; 11 | imageId: number; 12 | } 13 | 14 | export enum GachaFlag { 15 | PC_MESSAGE = "pcMessage", 16 | BONUS_SELECT = "bonusSelect", 17 | DISPLAY_FEATURED_SVT = "displayFeaturedSvt", 18 | } 19 | 20 | export interface GachaSub { 21 | id: number; 22 | priority: number; 23 | imageId: number; 24 | adjustAddId: number; 25 | openedAt: number; 26 | closedAt: number; 27 | releaseConditions: CommonRelease[]; 28 | script: Record; 29 | } 30 | 31 | export interface Gacha { 32 | id: number; 33 | name: string; 34 | imageId: number; 35 | type: PayType; 36 | adjustId: number; 37 | pickupId: number; 38 | drawNum1: number; 39 | drawNum2: number; 40 | maxDrawNum: number; 41 | openedAt: number; 42 | closedAt: number; 43 | detailUrl: string; 44 | flags: GachaFlag[]; 45 | gachaSubs: GachaSub[]; 46 | storyAdjusts: GachaStoryAdjust[]; 47 | } 48 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/powerMagnificationTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Card } from "@atlasacademy/api-connector"; 4 | 5 | import { BattleTeam } from "../../../../src"; 6 | import { BattleAttackActionList } from "../../../../src/Action/BattleAttackAction"; 7 | import { powerMagnification } from "../../../../src/Func/Implementations/getDamageList"; 8 | import { createBattle, servant } from "../../../helpers"; 9 | 10 | describe("getDamageList powerMagnification", () => { 11 | it("special damage up", async () => { 12 | const battle = createBattle(), 13 | actor = servant(60, BattleTeam.PLAYER), 14 | target = servant(17, BattleTeam.ENEMY); 15 | 16 | battle.addActor(actor); 17 | battle.addActor(target); 18 | 19 | const actions = new BattleAttackActionList(); 20 | actions.add(actor, Card.BUSTER, false); 21 | actions.add(actor, Card.QUICK, false); 22 | actions.add(actor, Card.ARTS, false); 23 | 24 | expect(powerMagnification(actions.get(1), actor, target).value()).to.equal(0); 25 | 26 | await actor.skill(2)?.activate(battle); 27 | expect(powerMagnification(actions.get(1), actor, target).value()).to.equal(1); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/Gift.ts: -------------------------------------------------------------------------------- 1 | import CondType from "../Enum/Cond"; 2 | 3 | export enum GiftType { 4 | SERVANT = "servant", 5 | ITEM = "item", 6 | FRIENDSHIP = "friendship", 7 | USER_EXP = "userExp", 8 | EQUIP = "equip", 9 | EVENT_SVT_JOIN = "eventSvtJoin", 10 | EVENT_SVT_GET = "eventSvtGet", 11 | QUEST_REWARD_ICON = "questRewardIcon", 12 | COSTUME_RELEASE = "costumeRelease", 13 | COSTUME_GET = "costumeGet", 14 | COMMAND_CODE = "commandCode", 15 | EVENT_POINT_BUFF = "eventPointBuff", 16 | EVENT_BOARD_GAME_TOKEN = "eventBoardGameToken", 17 | EVENT_COMMAND_ASSIST = "eventCommandAssist", 18 | EVENT_HEEL_PORTRAIT = "eventHeelPortrait", 19 | BATTLE_ITEM = "battleItem", 20 | PRIVILEGE = "privilege", 21 | CLASS_SKILL = "classSkill", 22 | } 23 | 24 | export interface BaseGift { 25 | id: number; 26 | type: GiftType; 27 | objectId: number; 28 | priority: number; 29 | num: number; 30 | } 31 | 32 | export interface GiftAdd { 33 | priority: number; 34 | replacementGiftIcon: string; 35 | condType: CondType; 36 | targetId: number; 37 | targetNum: number; 38 | replacementGifts: BaseGift[]; 39 | } 40 | 41 | export interface Gift extends BaseGift { 42 | giftAdds: GiftAdd[]; 43 | } 44 | -------------------------------------------------------------------------------- /packages/battle/test-data/fetchTestData.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import fs from "fs"; 3 | import glob from "glob"; 4 | import tar from "tar"; 5 | 6 | const repo = "https://github.com/atlasacademy/battle-test-data", 7 | hash = "74af1890ba4d13231f2a4180dc7970f3c00a4708", 8 | path = "./test-data/data", 9 | tarPath = `${path}/${hash}.tar.gz`; 10 | 11 | (async () => { 12 | if (fs.existsSync(tarPath)) { 13 | console.log("TEST DATA ALREADY EXISTS."); 14 | return; 15 | } 16 | 17 | console.log("DELETING OLD DATA"); 18 | glob.sync(`${path}/*.tar.gz`).forEach((file) => { 19 | fs.unlinkSync(file); 20 | }); 21 | 22 | console.log("DOWNLOADING DATA"); 23 | await new Promise((resolve) => { 24 | const file = fs.createWriteStream(tarPath); 25 | 26 | axios.get(`${repo}/tarball/${hash}`, { responseType: "stream" }).then((response) => { 27 | response.data.pipe(file); 28 | file.on("finish", () => { 29 | file.close(); 30 | resolve(); 31 | }); 32 | }); 33 | }); 34 | 35 | console.log("EXTRACTING DATA"); 36 | tar.x({ 37 | cwd: path, 38 | file: tarPath, 39 | strip: 1, 40 | sync: true, 41 | }); 42 | })(); 43 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/specialDefenseTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Card } from "@atlasacademy/api-connector"; 4 | 5 | import { BattleTeam } from "../../../../src"; 6 | import { BattleAttackActionList } from "../../../../src/Action/BattleAttackAction"; 7 | import { specialDefence } from "../../../../src/Func/Implementations/getDamageList"; 8 | import { buff, createBattle, servant } from "../../../helpers"; 9 | 10 | describe("getDamageList specialDefense", () => { 11 | it("test buff", async () => { 12 | const battle = createBattle(), 13 | actor = servant(2, BattleTeam.PLAYER), 14 | target = servant(17, BattleTeam.ENEMY); 15 | 16 | battle.addActor(actor); 17 | battle.addActor(target); 18 | 19 | const actions = new BattleAttackActionList(); 20 | actions.add(actor, Card.BUSTER, false); 21 | actions.add(actor, Card.QUICK, false); 22 | actions.add(actor, Card.ARTS, false); 23 | 24 | expect(specialDefence(actions.get(1), actor, target).value()).to.equal(1); 25 | 26 | target.addBuff(buff(315, { Value: 500 }, false, false, null)); 27 | expect(specialDefence(actions.get(1), actor, target).value()).to.equal(0.5); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/CostumeDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Region } from "@atlasacademy/api-connector"; 4 | 5 | import useApi from "../Hooks/useApi"; 6 | import { lang } from "../Setting/Manager"; 7 | import ServantDescriptor from "./ServantDescriptor"; 8 | 9 | export default function CostumeDescriptor(props: { 10 | region: Region; 11 | servantId: number; 12 | costumeLimit: number; 13 | iconHeight?: number; 14 | tab?: string; 15 | }) { 16 | const { data: servant } = useApi("servant", props.servantId); 17 | const { t } = useTranslation(); 18 | 19 | if (servant === undefined) return null; 20 | 21 | let costume = undefined; 22 | if (servant.profile !== undefined) { 23 | costume = Object.values(servant.profile.costume).find((costume) => costume.id === props.costumeLimit); 24 | } 25 | return ( 26 | <> 27 | {" "} 33 | {t("costume")}: {costume?.shortName ?? props.costumeLimit} 34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/getDamageList/criticalMagnificationTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Card } from "@atlasacademy/api-connector"; 4 | 5 | import { BattleTeam } from "../../../../src"; 6 | import { BattleAttackActionList } from "../../../../src/Action/BattleAttackAction"; 7 | import { criticalMagnification } from "../../../../src/Func/Implementations/getDamageList"; 8 | import { createBattle, servant } from "../../../helpers"; 9 | 10 | describe("getDamageList criticalMagnification", () => { 11 | it("check crit buff", async () => { 12 | const actor = servant(150, BattleTeam.PLAYER), 13 | target = servant(17, BattleTeam.ENEMY), 14 | battle = createBattle(); 15 | 16 | battle.addActor(actor); 17 | battle.addActor(target); 18 | 19 | const actions = new BattleAttackActionList(); 20 | actions.add(actor, Card.BUSTER, false); 21 | actions.add(actor, Card.QUICK, false); 22 | actions.add(actor, Card.ARTS, false); 23 | 24 | expect(criticalMagnification(actions.get(1), actor, target).value()).to.equal(0); 25 | 26 | await actor.skill(3)?.activate(battle); 27 | expect(criticalMagnification(actions.get(1), actor, target).value()).to.equal(1); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /packages/db/src/Breakdown/SkillReferenceBreakdown.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Region, Skill } from "@atlasacademy/api-connector"; 4 | 5 | import Api from "../Api"; 6 | import SkillBreakdown from "./SkillBreakdown"; 7 | 8 | interface IProps { 9 | region: Region; 10 | id: number; 11 | cooldowns: boolean; 12 | levels?: number; 13 | rankUp?: number; 14 | } 15 | 16 | interface IState { 17 | skill?: Skill.Skill; 18 | } 19 | 20 | class SkillReferenceBreakdown extends React.Component { 21 | constructor(props: IProps) { 22 | super(props); 23 | 24 | this.state = {}; 25 | } 26 | 27 | async componentDidMount() { 28 | Api.skill(this.props.id).then((skill) => this.setState({ skill })); 29 | } 30 | 31 | render() { 32 | if (this.state.skill === undefined) { 33 | return null; 34 | } 35 | 36 | return ( 37 | 44 | ); 45 | } 46 | } 47 | 48 | export default SkillReferenceBreakdown; 49 | -------------------------------------------------------------------------------- /packages/db/src/Component/BondIcon.tsx: -------------------------------------------------------------------------------- 1 | import img_bondsgage_1 from "../Assets/img_bondsgage_1.png"; 2 | import img_bondsgage_2 from "../Assets/img_bondsgage_2.png"; 3 | import img_bondsgage_3 from "../Assets/img_bondsgage_3.png"; 4 | import img_bondsgage_4 from "../Assets/img_bondsgage_4.png"; 5 | import img_bondsgage_5 from "../Assets/img_bondsgage_5.png"; 6 | import img_bondsgage_6 from "../Assets/img_bondsgage_6.png"; 7 | import img_bondsgage_7 from "../Assets/img_bondsgage_7.png"; 8 | import img_bondsgage_8 from "../Assets/img_bondsgage_8.png"; 9 | import img_bondsgage_9 from "../Assets/img_bondsgage_9.png"; 10 | import img_bondsgage_10 from "../Assets/img_bondsgage_10.png"; 11 | 12 | const bondIconImage = new Map([ 13 | [1, img_bondsgage_1], 14 | [2, img_bondsgage_2], 15 | [3, img_bondsgage_3], 16 | [4, img_bondsgage_4], 17 | [5, img_bondsgage_5], 18 | [6, img_bondsgage_6], 19 | [7, img_bondsgage_7], 20 | [8, img_bondsgage_8], 21 | [9, img_bondsgage_9], 22 | [10, img_bondsgage_10], 23 | ]); 24 | 25 | let BondIcon = (props: { level: number }) => { 26 | let { level } = props; 27 | if (1 <= level && level <= 10) return {`Bond; 28 | else return null; 29 | }; 30 | 31 | export default BondIcon; 32 | -------------------------------------------------------------------------------- /packages/battle/tests/Battle/BattleFuncQuestTraitTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleTeam } from "../../src"; 4 | import { createBattle, servant } from "../helpers"; 5 | 6 | describe("BattleFuncQuestTraitTest", () => { 7 | it("event bonus will not trigger if battle does not have trait", async () => { 8 | const actor = servant(1, BattleTeam.PLAYER), // mash 9 | battle = createBattle(); 10 | 11 | battle.addActor(actor); 12 | await battle.init(); 13 | 14 | expect( 15 | actor 16 | .buffs() 17 | .all(false) 18 | .filter((buff) => buff.props.buff.id === 2846), 19 | ).to.be.of.length(0); 20 | }); 21 | 22 | it("event bonus will trigger if battle has trait", async () => { 23 | const actor = servant(1, BattleTeam.PLAYER), // mash 24 | battle = createBattle({ 25 | traits: [{ id: 94000104, name: "Event" }], 26 | }); 27 | 28 | battle.addActor(actor); 29 | await battle.init(); 30 | 31 | expect( 32 | actor 33 | .buffs() 34 | .all(false) 35 | .filter((buff) => buff.props.buff.id === 2846), 36 | ).to.be.of.length(1); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/CraftEssenceReferenceDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | 4 | import { CraftEssence, Region } from "@atlasacademy/api-connector"; 5 | 6 | import Api from "../Api"; 7 | import { BasicCraftEssenceDescriptor } from "./CraftEssenceDescriptor"; 8 | 9 | interface IProps { 10 | region: Region; 11 | id: number; 12 | } 13 | 14 | interface IState { 15 | craftEssence?: CraftEssence.CraftEssenceBasic; 16 | } 17 | 18 | class CraftEssenceReferenceDescriptor extends React.Component { 19 | constructor(props: IProps) { 20 | super(props); 21 | 22 | this.state = {}; 23 | } 24 | 25 | async componentDidMount() { 26 | Api.craftEssenceBasic(this.props.id).then((craftEssence) => this.setState({ craftEssence })); 27 | } 28 | 29 | render() { 30 | const route = `/${this.props.region}/craft-essence/${this.props.id}`; 31 | 32 | if (this.state.craftEssence === undefined) { 33 | return [Craft Essence: {this.props.id}]; 34 | } 35 | 36 | return ; 37 | } 38 | } 39 | 40 | export default CraftEssenceReferenceDescriptor; 41 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/ItemUseDescription.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Item, Region } from "@atlasacademy/api-connector"; 4 | import { ItemDescriptor } from "@atlasacademy/api-descriptor"; 5 | 6 | import { mergeElements } from "../Helper/OutputHelper"; 7 | 8 | interface IProps { 9 | region: Region; 10 | item: Item.Item; 11 | } 12 | 13 | class ItemUseDescription extends React.Component { 14 | render() { 15 | let itemUseDescriptions = []; 16 | const { uses } = this.props.item; 17 | for (let use of uses) { 18 | if (use === Item.ItemUse.SKILL && uses.includes(Item.ItemUse.ASCENSION)) { 19 | itemUseDescriptions.push(ItemDescriptor.describeUse("skill & ascension")); 20 | continue; 21 | } 22 | if (use === Item.ItemUse.ASCENSION && uses.includes(Item.ItemUse.SKILL)) continue; 23 | 24 | itemUseDescriptions.push(ItemDescriptor.describeUse(use)); 25 | } 26 | return ( 27 |
28 | {mergeElements( 29 | itemUseDescriptions.map((use) => {use}), 30 | ", " 31 | )} 32 |
33 | ); 34 | } 35 | } 36 | 37 | export default ItemUseDescription; 38 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/Func/handleLinkageSection.tsx: -------------------------------------------------------------------------------- 1 | import { faLink, faLinkSlash } from "@fortawesome/free-solid-svg-icons"; 2 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 3 | 4 | import { DataVal, Func, Region } from "@atlasacademy/api-connector"; 5 | 6 | import { FuncDescriptorSections } from "./FuncDescriptorSections"; 7 | 8 | export default function handleLinkageSection( 9 | region: Region, 10 | sections: FuncDescriptorSections, 11 | func: Func.BasicFunc, 12 | dataVal: DataVal.DataVal 13 | ): void { 14 | const section = sections.linkage, 15 | parts = section.parts; 16 | 17 | if (dataVal.CheckDuplicate === 1) { 18 | parts.push("[This function instance can only be executed once]"); 19 | } 20 | 21 | if (dataVal.AddLinkageTargetIndividualty !== undefined && dataVal.BehaveAsFamilyBuff === 1) { 22 | parts.push( 23 | <> 24 | [ 25 | {dataVal.UnSubStateWhileLinkedToOthers === 1 ? ( 26 | 27 | ) : null} 28 | {dataVal.AddLinkageTargetIndividualty}] 29 | 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/battle/src/Skill/BattleSkillPassive.ts: -------------------------------------------------------------------------------- 1 | import BattleSkill, { BattleSkillProps, BattleSkillState } from "./BattleSkill"; 2 | import BattleSkillFunc from "./BattleSkillFunc"; 3 | 4 | export default class BattleSkillPassive extends BattleSkill { 5 | constructor( 6 | public props: BattleSkillProps, 7 | state: BattleSkillState | null, 8 | ) { 9 | super( 10 | props, 11 | state ?? { 12 | cooldown: 0, 13 | funcs: props.skill.functions.map((func, i) => { 14 | return new BattleSkillFunc( 15 | { 16 | actorId: props.actorId, 17 | func, 18 | level: props.level, 19 | passive: true, 20 | }, 21 | null, 22 | this, 23 | ); 24 | }), 25 | }, 26 | ); 27 | 28 | this.state.funcs.forEach((func) => (func.parent = this)); 29 | } 30 | 31 | clone(): BattleSkillPassive { 32 | return new BattleSkillPassive(this.props, { 33 | ...this.state, 34 | funcs: this.state.funcs.map((func) => func.clone(this)), 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/db/src/Page/Changelog/Settings.tsx: -------------------------------------------------------------------------------- 1 | import { Button, ButtonGroup } from "react-bootstrap"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | interface IProps { 5 | visibleOnly: boolean; 6 | updateVisibleOnly: (value: boolean) => void; 7 | 8 | localTime: boolean; 9 | updateLocalTime: (value: boolean) => void; 10 | } 11 | 12 | let Settings = ({ visibleOnly, updateVisibleOnly, localTime, updateLocalTime }: IProps) => { 13 | const { t } = useTranslation(); 14 | return ( 15 |
16 | 17 | 20 | 23 | 26 | 27 |
28 |   29 |
30 | ); 31 | }; 32 | 33 | export default Settings; 34 | -------------------------------------------------------------------------------- /packages/api-connector/src/Schema/WarBoard.ts: -------------------------------------------------------------------------------- 1 | import { Gift } from "./Gift"; 2 | 3 | export enum WarBoardStageSquareType { 4 | NORMAL = "normal", 5 | ITEM = "item", 6 | EFFECT = "effect", 7 | TREASURE = "treasure", 8 | WALL = "wall", 9 | } 10 | 11 | export enum WarBoardTreasureRarity { 12 | COMMON = "common", 13 | RARE = "rare", 14 | SRARE = "srare", 15 | COMMON_PLUS = "commonPlus", 16 | RARE_PLUS = "rarePlus", 17 | SRARE_PLUS = "srarePlus", 18 | COMMON_PLUS2 = "commonPlus2", 19 | RARE_PLUS2 = "rarePlus2", 20 | SRARE_PLUS2 = "srarePlus2", 21 | ITEM_ICON = "itemIcon", 22 | ITEM_ICON_PLUS = "itemIconPlus", 23 | ITEM_ICON_PLUS2 = "itemIconPlus2", 24 | } 25 | interface WarBoardTreasure { 26 | warBoardTreasureId: number; 27 | rarity: WarBoardTreasureRarity; 28 | gifts: Gift[]; 29 | } 30 | interface WarBoardStageSquare { 31 | squareIndex: number; 32 | type: WarBoardStageSquareType; 33 | effectId: number; 34 | treasures: WarBoardTreasure[]; 35 | } 36 | interface WarBoardStage { 37 | warBoardStageId: number; 38 | boardMessage: string; 39 | formationCost: number; 40 | questId: number; 41 | questPhase: number; 42 | squares: WarBoardStageSquare[]; 43 | } 44 | export interface WarBoard { 45 | warBoardId: number; 46 | stages: WarBoardStage[]; 47 | } 48 | -------------------------------------------------------------------------------- /packages/db/src/Page/ListingPage.css: -------------------------------------------------------------------------------- 1 | .listing-page > hr { 2 | margin-top: 0; 3 | } 4 | 5 | .listing-page .page-navigator { 6 | float: right; 7 | } 8 | 9 | .listing-page .col-center, 10 | table.listing-table .col-center, 11 | .listing-page .rarity-col, 12 | table.listing-table .rarity-col { 13 | text-align: center; 14 | width: 1px; 15 | } 16 | 17 | @media (min-width: 768px) { 18 | .listing-page .rarity-col, 19 | table.listing-table .rarity-col { 20 | min-width: 10em; 21 | white-space: nowrap; 22 | } 23 | } 24 | 25 | .listing-page .listing-svtId { 26 | font-family: monospace; 27 | font-size: 0.9rem; 28 | } 29 | 30 | .listing-page table th, 31 | .listing-page table td, 32 | table.listing-table th, 33 | table.listing-table td { 34 | vertical-align: middle; 35 | } 36 | 37 | .listing-page #item-type { 38 | justify-content: left; 39 | margin-bottom: 1rem; 40 | } 41 | 42 | .listing-page > .row .btn-group { 43 | width: 100%; 44 | } 45 | 46 | .listing-page #item-search { 47 | margin-left: auto; 48 | margin-bottom: 1rem; 49 | } 50 | 51 | .listing-page #item-search form { 52 | width: 100%; 53 | } 54 | 55 | .listing-page #item-search form input { 56 | margin-left: auto; 57 | width: 100%; 58 | text-align: center; 59 | } 60 | 61 | .listing-page #item-rarity { 62 | margin-bottom: 1rem; 63 | } 64 | -------------------------------------------------------------------------------- /packages/db/src/Page/MysticCode/MysticCodePortrait.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { MysticCode } from "@atlasacademy/api-connector"; 4 | 5 | import "./MysticCodePortrait.css"; 6 | 7 | interface IProps { 8 | mysticCode: MysticCode.MysticCode; 9 | } 10 | 11 | class MysticCodePortrait extends React.Component { 12 | render() { 13 | return ( 14 |
15 | 21 | {this.props.mysticCode.name} 22 | 23 | 24 | 30 | {this.props.mysticCode.name} 31 | 32 |
33 | ); 34 | } 35 | } 36 | 37 | export default MysticCodePortrait; 38 | -------------------------------------------------------------------------------- /packages/paper-moon/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container } from "react-bootstrap"; 3 | import { ConnectedProps, connect } from "react-redux"; 4 | 5 | import { battleSetupInitThunk } from "./app/battleSetup/thunks"; 6 | import BattleDisplay from "./components/BattleDisplay"; 7 | import BattleSetup from "./components/BattleSetup/BattleSetup"; 8 | import EnemyActorConfigModal from "./components/EnemyActorConfig/EnemyActorConfigModal"; 9 | import Navigation from "./components/Navigation"; 10 | import PlayerActorConfigModal from "./components/PlayerActorConfig/PlayerActorConfigModal"; 11 | 12 | const mapDispatchToProps = { 13 | init: battleSetupInitThunk, 14 | }, 15 | connector = connect(null, mapDispatchToProps); 16 | 17 | type AppProps = ConnectedProps; 18 | 19 | class App extends React.Component { 20 | async componentDidMount() { 21 | await this.props.init(); 22 | } 23 | 24 | render() { 25 | return ( 26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | ); 36 | } 37 | } 38 | 39 | export default connector(App); 40 | -------------------------------------------------------------------------------- /packages/battle/tests/Action/inspectAvailableTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleTeam } from "../../src"; 4 | import { BattleCommandAction } from "../../src/Action/BattleCommandAction"; 5 | import inspectAvailable from "../../src/Action/inspectAvailable"; 6 | import BattleSkill from "../../src/Skill/BattleSkill"; 7 | import { createBattle, servant } from "../helpers"; 8 | 9 | describe("inspectAvailable", () => { 10 | it("returns available skills", async () => { 11 | const battle = createBattle(), 12 | actor = servant(2, BattleTeam.PLAYER), 13 | manaBurst = actor.skill(2); 14 | 15 | battle.addActor(actor); 16 | 17 | let availableActions = inspectAvailable(battle); 18 | expect(availableActions).to.contain(BattleCommandAction.SERVANT_1_SKILL_1); 19 | expect(availableActions).to.contain(BattleCommandAction.SERVANT_1_SKILL_2); 20 | expect(availableActions).to.contain(BattleCommandAction.SERVANT_1_SKILL_3); 21 | 22 | await manaBurst.activate(battle); 23 | availableActions = inspectAvailable(battle); 24 | expect(availableActions).to.contain(BattleCommandAction.SERVANT_1_SKILL_1); 25 | expect(availableActions).to.not.contain(BattleCommandAction.SERVANT_1_SKILL_2); 26 | expect(availableActions).to.contain(BattleCommandAction.SERVANT_1_SKILL_3); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/api-descriptor/src/Func/extractMutatingDataVals.ts: -------------------------------------------------------------------------------- 1 | import { DataVal } from "@atlasacademy/api-connector"; 2 | 3 | import getStaticDataValFields from "./extractStaticDataValFields"; 4 | 5 | export default function extractMutatingDataVals(dataVals: DataVal.DataVal[]): DataVal.DataVal[] { 6 | const staticFields = getStaticDataValFields(dataVals), 7 | hasDependingVals = dataVals.filter((val) => val.DependFuncVals !== undefined).length > 0, 8 | mutatingDataVals: DataVal.DataVal[] = []; 9 | 10 | dataVals.forEach((dataVal) => { 11 | const fields = Object.keys(dataVal), 12 | mutatingDataVal: DataVal.DataVal = {}; 13 | 14 | fields.forEach((field) => { 15 | if (staticFields.indexOf(field as DataVal.DataValField) !== -1) return; 16 | 17 | // @ts-ignore 18 | mutatingDataVal[field] = dataVal[field]; 19 | }); 20 | 21 | mutatingDataVals.push(mutatingDataVal); 22 | }); 23 | 24 | if (hasDependingVals) { 25 | const dependingVals: DataVal.DataVal[] = dataVals.map((val) => val.DependFuncVals ?? {}), 26 | dependingMutatingVals = extractMutatingDataVals(dependingVals); 27 | 28 | dependingMutatingVals.forEach((dependingMutatingVal, i) => { 29 | mutatingDataVals[i].DependFuncVals = dependingMutatingVal; 30 | }); 31 | } 32 | 33 | return mutatingDataVals; 34 | } 35 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/CommandCodeDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "react-router-dom"; 2 | 3 | import { CommandCode, Region } from "@atlasacademy/api-connector"; 4 | 5 | import FaceIcon from "../Component/FaceIcon"; 6 | import useApi from "../Hooks/useApi"; 7 | import { lang } from "../Setting/Manager"; 8 | 9 | import "./Descriptor.css"; 10 | 11 | export default function CommandCodeDescriptor(props: { 12 | region: Region; 13 | commandCode: CommandCode.CommandCodeBasic; 14 | iconHeight?: number; 15 | }) { 16 | return ( 17 | 18 | {" "} 19 | {" "} 24 | 25 | {props.commandCode.name} 26 | 27 | 28 | ); 29 | } 30 | 31 | export function CommandCodeDescriptorId(props: { region: Region; ccId: number; iconHeight?: number }) { 32 | const { data: cc } = useApi("commandCodeBasic", props.ccId); 33 | return cc !== undefined ? ( 34 | 35 | ) : null; 36 | } 37 | -------------------------------------------------------------------------------- /packages/battle/tests/NoblePhantasm/BattleNoblePhantasmTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { Func } from "../../../api-connector"; 4 | import { BattleTeam } from "../../src/Enum/BattleTeam"; 5 | import BattleDamageEvent from "../../src/Event/BattleDamageEvent"; 6 | import { createBattle, servant } from "../helpers"; 7 | 8 | describe("BattleNoblePhantasmTest", () => { 9 | it("hits", () => { 10 | const actor = servant(11, BattleTeam.PLAYER), 11 | noblePhantasm = actor.noblePhantasm(); 12 | 13 | expect(noblePhantasm.hits()).to.eql([3, 3, 5, 7, 8, 10, 12, 14, 16, 22]); 14 | }); 15 | 16 | it("deals damage", async () => { 17 | const actor = servant(2, BattleTeam.PLAYER), 18 | target = servant(17, BattleTeam.ENEMY), 19 | battle = createBattle(); 20 | 21 | battle.addActor(actor); 22 | battle.addActor(target); 23 | 24 | const np = actor.noblePhantasm(), 25 | func = np.func(1); 26 | 27 | expect(func).to.not.be.undefined; 28 | expect(func.props.func.funcType).to.equal(Func.FuncType.DAMAGE_NP); 29 | 30 | const events = await func.execute(battle); 31 | expect(events.length).to.equal(1); 32 | 33 | const event = events[0]; 34 | expect(event).to.be.instanceof(BattleDamageEvent); 35 | expect(event.reference.damage).to.equal(40475); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/battle/tests/Func/Implementations/adjustNpFuncTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleTeam } from "../../../src"; 4 | import BattleSkill from "../../../src/Skill/BattleSkill"; 5 | import { createBattle, servant } from "../../helpers"; 6 | 7 | describe("adjustNpFunc", () => { 8 | it("artoria skill 3", async () => { 9 | const actor = servant(2, BattleTeam.PLAYER), 10 | battle = createBattle(), 11 | charge = actor.skill(3); 12 | 13 | battle.addActor(actor); 14 | 15 | expect(actor.gaugePercent()).to.equal(0); 16 | await charge.activate(battle); 17 | 18 | expect(actor.gaugePercent()).to.equal(0.3); 19 | }); 20 | 21 | it("shiki saber skill 3", async () => { 22 | const shiki = servant(91, BattleTeam.PLAYER), 23 | waver = servant(37, BattleTeam.PLAYER), 24 | battle = createBattle(); 25 | 26 | battle.addActor(shiki); 27 | battle.addActor(waver); 28 | 29 | expect(shiki.gaugePercent()).to.equal(0); 30 | 31 | await waver.skill(2)?.activate(battle); 32 | expect(shiki.gaugePercent()).to.equal(0.1); 33 | 34 | await waver.skill(3)?.activate(battle); 35 | expect(shiki.gaugePercent()).to.equal(0.2); 36 | 37 | await shiki.skill(3)?.activate(battle); 38 | expect(shiki.gaugePercent()).to.equal(0.1); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Atlas Academy DB 2 | 3 | ![Cloudflare Worker Publish](https://github.com/atlasacademy/apps/workflows/Cloudflare%20Worker%20Publish/badge.svg) 4 | 5 | Source code for the Atlas Academy DB at https://apps.atlasacademy.io/db 6 | 7 | You can join our Discod to discuss the development. Feel free to make pull request or open an issue but we are usually more responsive on Discord. 8 | 9 | [![Discord server invite](https://discordapp.com/api/guilds/502554574423457812/embed.png)](https://atlasacademy.io/discord) 10 | 11 | ## Development workflow 12 | 13 | ```bash 14 | # clone repo 15 | git clone https://github.com/atlasacademy/apps.git aa-apps 16 | cd aa-apps 17 | 18 | # install lerna and prettier. You should use prettier with the given config to format the files. 19 | npm ci 20 | 21 | # setup packages with local npm link 22 | npx lerna bootstrap --ci --force-local 23 | 24 | # run typescript watchers 25 | npm run watch 26 | 27 | # run dev db on another terminal 28 | npm run start:db 29 | 30 | # ... make changes 31 | 32 | # commit changes 33 | npm run format 34 | git add -A && git commit -m "stuff" 35 | ``` 36 | 37 | ## Publish workflow 38 | 39 | This is not applicable if you are not part of the npm.js Atlas Academy org. Ping one of the contributors to publish the changes. 40 | 41 | ```bash 42 | # publish changes 43 | lerna publish 44 | 45 | # merge to master 46 | git checkout master && git pull && git merge dev 47 | ``` 48 | -------------------------------------------------------------------------------- /packages/db/src/Component/Scene.css: -------------------------------------------------------------------------------- 1 | .scene-wrapper { 2 | display: block; 3 | overflow: hidden; 4 | position: relative; 5 | } 6 | 7 | .scene-background { 8 | background-repeat: no-repeat; 9 | bottom: 0; 10 | display: block; 11 | left: 0; 12 | position: absolute; 13 | right: 0; 14 | top: 0; 15 | } 16 | 17 | .scene-figure-wrapper { 18 | bottom: 0; 19 | display: block; 20 | position: absolute; 21 | right: 0; 22 | } 23 | 24 | .scene-figure { 25 | background-repeat: no-repeat; 26 | background-size: 100%; 27 | bottom: 0; 28 | display: block; 29 | left: 0; 30 | position: absolute; 31 | right: 0; 32 | top: 0; 33 | } 34 | 35 | .scene-figure-face, 36 | .scene-equip { 37 | background-repeat: no-repeat; 38 | display: block; 39 | position: absolute; 40 | } 41 | 42 | .scene-foreground { 43 | position: absolute; 44 | height: 100%; 45 | width: 100%; 46 | background-size: cover; 47 | } 48 | 49 | /* Types foreground */ 50 | .frame { 51 | background-position: 0 -10px; 52 | } 53 | 54 | /* Mobile Fix - Foreground Types */ 55 | @media (max-width: 767px) { 56 | .frame { 57 | background-position: 0 -7px; 58 | } 59 | } 60 | 61 | .sepia-bg { 62 | position: absolute; 63 | height: 100%; 64 | width: 100%; 65 | background: radial-gradient(ellipse at center, #c1701f 0%, #512f0d 80%); 66 | opacity: 0.55; 67 | } 68 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/ItemSetDescriptor.tsx: -------------------------------------------------------------------------------- 1 | import { Item, Region, Shop } from "@atlasacademy/api-connector"; 2 | 3 | import EntityReferenceDescriptor from "../Descriptor/EntityReferenceDescriptor"; 4 | import { IconDescriptorMap } from "../Descriptor/ItemDescriptor"; 5 | 6 | const ItemSetDescriptor = (props: { region: Region; itemSet: Shop.ItemSet; itemMap: Map }) => { 7 | const region = props.region, 8 | itemSet = props.itemSet; 9 | switch (itemSet.purchaseType) { 10 | case Shop.PurchaseType.ITEM: 11 | return ( 12 | <> 13 | × 14 | {itemSet.setNum} 15 | 16 | ); 17 | case Shop.PurchaseType.SERVANT: 18 | return ( 19 | <> 20 | ×{itemSet.setNum} 21 | 22 | ); 23 | // case Shop.PurchaseType.EVENT_SHOP: 24 | // case Shop.PurchaseType.ITEM_AS_PRESENT: 25 | // case Shop.PurchaseType.GIFT: 26 | default: 27 | return ( 28 | <> 29 | {itemSet.purchaseType} {itemSet.targetId} {itemSet.setNum} 30 | 31 | ); 32 | } 33 | }; 34 | 35 | export default ItemSetDescriptor; 36 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Docker 2 | 3 | on: 4 | # push: 5 | # branches: 6 | # - master 7 | # paths-ignore: 8 | # - 'packages/db-og-worker/**' 9 | workflow_dispatch: 10 | 11 | env: 12 | # TODO: Change variable to your image's name. 13 | IMAGE_NAME: apps 14 | 15 | jobs: 16 | # Push image to GitHub Packages. 17 | # See also https://docs.docker.com/docker-hub/builds/ 18 | push: 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - name: Build image 25 | run: docker build . --file Dockerfile --no-cache --tag $IMAGE_NAME 26 | 27 | - name: Log into GitHub Container Registry 28 | # TODO: Create a PAT with `read:packages` and `write:packages` scopes and save it as an Actions secret `CR_PAT` 29 | run: echo "${{ secrets.CR_PAT }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin 30 | 31 | - name: Push image to GitHub Container Registry 32 | run: | 33 | IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME 34 | 35 | # Change all uppercase to lowercase 36 | IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') 37 | 38 | # Use Docker `latest` tag convention 39 | VERSION=latest 40 | 41 | echo IMAGE_ID=$IMAGE_ID 42 | echo VERSION=$VERSION 43 | 44 | docker tag $IMAGE_NAME $IMAGE_ID:$VERSION 45 | docker push $IMAGE_ID:$VERSION 46 | -------------------------------------------------------------------------------- /packages/paper-moon/src/app/battleSetup/slice.ts: -------------------------------------------------------------------------------- 1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit"; 2 | 3 | import { BattleTeam } from "@atlasacademy/battle"; 4 | 5 | import { BattleSetupOptionList, BattleSetupState } from "./types"; 6 | 7 | const initialState: BattleSetupState = { 8 | pending: true, 9 | canAddActor: true, 10 | servantList: [], 11 | craftEssenceList: [], 12 | selectedTeam: BattleTeam.PLAYER, 13 | }; 14 | 15 | export const battleSetupSlice = createSlice({ 16 | name: "battleSetup", 17 | initialState, 18 | reducers: { 19 | setCanAddActor: (state, action: PayloadAction) => { 20 | state.canAddActor = action.payload; 21 | }, 22 | setCraftEssenceList: (state, action: PayloadAction) => { 23 | state.craftEssenceList = action.payload; 24 | }, 25 | setPending: (state, action: PayloadAction) => { 26 | state.pending = action.payload; 27 | }, 28 | setServantList: (state, action: PayloadAction) => { 29 | state.servantList = action.payload; 30 | }, 31 | selectServant: (state, action: PayloadAction) => { 32 | state.selectedServant = action.payload; 33 | }, 34 | selectTeam: (state, action: PayloadAction) => { 35 | state.selectedTeam = action.payload; 36 | }, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /packages/db/src/Descriptor/QuestEnumDescription.tsx: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | import { Quest } from "@atlasacademy/api-connector"; 4 | import { toTitleCase } from "@atlasacademy/api-descriptor"; 5 | 6 | import { t } from "../i18n"; 7 | 8 | export const QuestTypeDescriptionMap = new Map([ 9 | [Quest.QuestType.MAIN, t("Main")], 10 | [Quest.QuestType.FREE, t("Free")], 11 | [Quest.QuestType.FRIENDSHIP, t("Interlude")], 12 | [Quest.QuestType.EVENT, t("Event")], 13 | [Quest.QuestType.HERO_BALLAD, t("Hero Ballad")], 14 | [Quest.QuestType.WAR_BOARD, t("War Board")], 15 | ]); 16 | 17 | export const QuestTypeDescription = ({ questType }: { questType: Quest.QuestType }) => { 18 | const { t } = useTranslation(); 19 | 20 | switch (questType) { 21 | case Quest.QuestType.MAIN: 22 | return <>{t("Main")}; 23 | case Quest.QuestType.FREE: 24 | return <>{t("Free")}; 25 | case Quest.QuestType.FRIENDSHIP: 26 | return <>{t("Interlude")}; 27 | case Quest.QuestType.EVENT: 28 | return <>{t("Event")}; 29 | case Quest.QuestType.HERO_BALLAD: 30 | return <>{t("Hero Ballad")}; 31 | case Quest.QuestType.WAR_BOARD: 32 | return <>{t("War Board")}; 33 | default: 34 | return <>{toTitleCase(questType)}; 35 | } 36 | }; 37 | 38 | export const QuestFlagDescription = new Map([[Quest.QuestFlag.NONE, "None"]]); 39 | -------------------------------------------------------------------------------- /packages/db/src/Page/Quest/QuestPhaseNavigator.tsx: -------------------------------------------------------------------------------- 1 | import { Pagination } from "react-bootstrap"; 2 | 3 | import { Quest, Region } from "@atlasacademy/api-connector"; 4 | 5 | const PhaseNavigator = (props: { 6 | region: Region; 7 | quest: Quest.QuestPhase; 8 | currentPhase: number; 9 | setPhase: (phase: number) => void; 10 | }) => { 11 | const currentPhase = props.currentPhase, 12 | phases = props.quest.phases.sort((a, b) => a - b); 13 | return ( 14 | 15 | { 18 | props.setPhase(currentPhase - 1); 19 | }} 20 | /> 21 | {props.quest.phases.map((phase) => ( 22 | { 26 | props.setPhase(phase); 27 | }} 28 | > 29 | {phase} 30 | 31 | ))} 32 | { 35 | props.setPhase(currentPhase + 1); 36 | }} 37 | /> 38 | 39 | ); 40 | }; 41 | export default PhaseNavigator; 42 | -------------------------------------------------------------------------------- /packages/battle/tests/Skill/BattleSkillTest.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | import { BattleTeam } from "../../src"; 4 | import BattleSkill from "../../src/Skill/BattleSkill"; 5 | import { createBattle, servant } from "../helpers"; 6 | 7 | describe("BattleSkill", () => { 8 | it("cooldown", async () => { 9 | const battle = createBattle(), 10 | actor = servant(2, BattleTeam.PLAYER), 11 | charisma = actor.skill(1); 12 | 13 | battle.addActor(actor); 14 | 15 | expect(charisma.level()).to.equal(10); 16 | expect(charisma.available()).to.be.true; 17 | expect(charisma.cooldown()).to.equal(0); 18 | 19 | await charisma.activate(battle); 20 | 21 | expect(charisma.available()).to.be.false; 22 | expect(charisma.cooldown()).to.equal(5); 23 | }); 24 | 25 | it("cooldown is level dependant", async () => { 26 | const battle = createBattle(), 27 | actor = servant(2, BattleTeam.PLAYER, { 28 | skillLevels: [1], 29 | }), 30 | charisma = actor.skill(1); 31 | 32 | battle.addActor(actor); 33 | 34 | expect(charisma.level()).to.equal(1); 35 | expect(charisma.available()).to.be.true; 36 | expect(charisma.cooldown()).to.equal(0); 37 | 38 | await charisma.activate(battle); 39 | 40 | expect(charisma.available()).to.be.false; 41 | expect(charisma.cooldown()).to.equal(7); 42 | }); 43 | }); 44 | --------------------------------------------------------------------------------