diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ee46f8e..229b5b3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,33 +1,33 @@ name: CI on: - push: - branches: [main] - pull_request: - branches: [main] + push: + branches: [main] + pull_request: + branches: [main] jobs: - build-and-test: - runs-on: ubuntu-latest + build-and-test: + runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 + steps: + - uses: actions/checkout@v3 - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: "18" + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: 8 + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 - - name: Install dependencies - run: pnpm install + - name: Install dependencies + run: pnpm install - - name: Build - run: pnpm run build + - name: Build + run: pnpm run build - - name: Test - run: pnpm test + - name: Test + run: pnpm test diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..63dcce3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,16 @@ +**/*/target +**/*/dist +packages/torii-client/wasm +packages/torii-client/pkg +packages/torii-wasm/pkg/ +packages/utils-wasm/pkg/ + +examples/dojo-starter +packages/create-dojo + +# ignore lock files +**/*-lock.yaml +package-lock.json +dev-dist + +**/CHANGELOG.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..36ff165 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": true, + "singleQuote": false, + "bracketSpacing": true, + "printWidth": 80 +} diff --git a/clients/react-vite/.eslintrc.cjs b/clients/react-vite/.eslintrc.cjs index 29cb6d5..1f68439 100644 --- a/clients/react-vite/.eslintrc.cjs +++ b/clients/react-vite/.eslintrc.cjs @@ -1,14 +1,19 @@ module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended'], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], - rules: { - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, + root: true, + env: { browser: true, es2020: true }, + extends: [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended", + "plugin:storybook/recommended", ], - }, -} + ignorePatterns: ["dist", ".eslintrc.cjs"], + parser: "@typescript-eslint/parser", + plugins: ["react-refresh"], + rules: { + "react-refresh/only-export-components": [ + "warn", + { allowConstantExport: true }, + ], + }, +}; diff --git a/clients/react-vite/.storybook/main.ts b/clients/react-vite/.storybook/main.ts index 3197ba6..2cf2173 100644 --- a/clients/react-vite/.storybook/main.ts +++ b/clients/react-vite/.storybook/main.ts @@ -1,20 +1,20 @@ import type { StorybookConfig } from "@storybook/react-vite"; const config: StorybookConfig = { - stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], - addons: [ - "@storybook/addon-onboarding", - "@storybook/addon-links", - "@storybook/addon-essentials", - "@chromatic-com/storybook", - "@storybook/addon-interactions", - ], - core: { - builder: "@storybook/builder-vite", // šŸ‘ˆ The builder enabled here. - }, - framework: { - name: "@storybook/react-vite", - options: {}, - }, + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@storybook/addon-onboarding", + "@storybook/addon-links", + "@storybook/addon-essentials", + "@chromatic-com/storybook", + "@storybook/addon-interactions", + ], + core: { + builder: "@storybook/builder-vite", // šŸ‘ˆ The builder enabled here. + }, + framework: { + name: "@storybook/react-vite", + options: {}, + }, }; export default config; diff --git a/clients/react-vite/.storybook/preview.ts b/clients/react-vite/.storybook/preview.ts index 37914b1..19d2768 100644 --- a/clients/react-vite/.storybook/preview.ts +++ b/clients/react-vite/.storybook/preview.ts @@ -1,14 +1,14 @@ import type { Preview } from "@storybook/react"; const preview: Preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, }, - }, }; export default preview; diff --git a/clients/react-vite/README.md b/clients/react-vite/README.md index e1cdc89..297660d 100644 --- a/clients/react-vite/README.md +++ b/clients/react-vite/README.md @@ -4,27 +4,31 @@ This template provides a minimal setup to get React working in Vite with HMR and Currently, two official plugins are available: -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh ## Expanding the ESLint configuration If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: -- Configure the top-level `parserOptions` property like this: +- Configure the top-level `parserOptions` property like this: ```js export default { - // other rules... - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: __dirname, - }, -} + // other rules... + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + project: [ + "./tsconfig.json", + "./tsconfig.node.json", + "./tsconfig.app.json", + ], + tsconfigRootDir: __dirname, + }, +}; ``` -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list +- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` +- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/clients/react-vite/components.json b/clients/react-vite/components.json index 1c6facd..cecb2b8 100644 --- a/clients/react-vite/components.json +++ b/clients/react-vite/components.json @@ -1,17 +1,17 @@ { - "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/index.css", - "baseColor": "slate", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils" - } -} \ No newline at end of file + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} diff --git a/clients/react-vite/index.html b/clients/react-vite/index.html index 611e2ac..0adb5ab 100644 --- a/clients/react-vite/index.html +++ b/clients/react-vite/index.html @@ -1,17 +1,20 @@ - - - - - - - + + + + + + + - Vite + React + TS - - -
- - + Vite + React + TS + + +
+ + diff --git a/clients/react-vite/package.json b/clients/react-vite/package.json index 8626a81..d7d9ae6 100644 --- a/clients/react-vite/package.json +++ b/clients/react-vite/package.json @@ -1,65 +1,65 @@ { - "name": "survivor", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" - }, - "dependencies": { - "@cartridge/connector": "^0.3.36", - "@lootsurvivor/core": "workspace:^", - "@lootsurvivor/react": "workspace:^", - "@radix-ui/react-slider": "^1.2.0", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-tabs": "^1.1.0", - "@starknet-react/chains": "^0.1.7", - "@starknet-react/core": "^2.8.3", - "@tanstack/react-query": "^5.51.15", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", - "framer-motion": "^11.3.19", - "get-starknet-core": "^3.3.2", - "graphql-request": "^7.1.0", - "lucide-react": "^0.416.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "starknet": "^6.11.0", - "tailwind-merge": "^2.4.0", - "tailwindcss-animate": "^1.0.7" - }, - "devDependencies": { - "@chromatic-com/storybook": "^1.6.1", - "@storybook/addon-essentials": "^8.2.6", - "@storybook/addon-interactions": "^8.2.6", - "@storybook/addon-links": "^8.2.6", - "@storybook/addon-onboarding": "^8.2.6", - "@storybook/blocks": "^8.2.6", - "@storybook/builder-vite": "^8.2.6", - "@storybook/react": "^8.2.6", - "@storybook/react-vite": "^8.2.6", - "@storybook/test": "^8.2.6", - "@types/node": "^20.14.12", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@typescript-eslint/eslint-plugin": "^7.15.0", - "@typescript-eslint/parser": "^7.15.0", - "@vitejs/plugin-react": "^4.3.1", - "autoprefixer": "^10.4.19", - "eslint": "^8.57.0", - "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", - "eslint-plugin-storybook": "^0.8.0", - "postcss": "^8.4.40", - "storybook": "^8.2.6", - "tailwindcss": "^3.4.7", - "typescript": "^5.2.2", - "vite": "^5.3.4", - "vite-plugin-svgr": "^4.2.0" - } + "name": "survivor", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build" + }, + "dependencies": { + "@cartridge/connector": "^0.3.36", + "@lootsurvivor/core": "workspace:^", + "@lootsurvivor/react": "workspace:^", + "@radix-ui/react-slider": "^1.2.0", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.0", + "@starknet-react/chains": "^0.1.7", + "@starknet-react/core": "^2.8.3", + "@tanstack/react-query": "^5.51.15", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "framer-motion": "^11.3.19", + "get-starknet-core": "^3.3.2", + "graphql-request": "^7.1.0", + "lucide-react": "^0.416.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "starknet": "^6.11.0", + "tailwind-merge": "^2.4.0", + "tailwindcss-animate": "^1.0.7" + }, + "devDependencies": { + "@chromatic-com/storybook": "^1.6.1", + "@storybook/addon-essentials": "^8.2.6", + "@storybook/addon-interactions": "^8.2.6", + "@storybook/addon-links": "^8.2.6", + "@storybook/addon-onboarding": "^8.2.6", + "@storybook/blocks": "^8.2.6", + "@storybook/builder-vite": "^8.2.6", + "@storybook/react": "^8.2.6", + "@storybook/react-vite": "^8.2.6", + "@storybook/test": "^8.2.6", + "@types/node": "^20.14.12", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.15.0", + "@typescript-eslint/parser": "^7.15.0", + "@vitejs/plugin-react": "^4.3.1", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.7", + "eslint-plugin-storybook": "^0.8.0", + "postcss": "^8.4.40", + "storybook": "^8.2.6", + "tailwindcss": "^3.4.7", + "typescript": "^5.2.2", + "vite": "^5.3.4", + "vite-plugin-svgr": "^4.2.0" + } } diff --git a/clients/react-vite/postcss.config.js b/clients/react-vite/postcss.config.js index 2e7af2b..49c0612 100644 --- a/clients/react-vite/postcss.config.js +++ b/clients/react-vite/postcss.config.js @@ -1,6 +1,6 @@ export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/clients/react-vite/public/images/bg-skulls.png b/clients/react-vite/public/images/bg-skulls.png index 997df8a..396a784 100644 Binary files a/clients/react-vite/public/images/bg-skulls.png and b/clients/react-vite/public/images/bg-skulls.png differ diff --git a/clients/react-vite/src/App.tsx b/clients/react-vite/src/App.tsx index 28d696f..46d955e 100644 --- a/clients/react-vite/src/App.tsx +++ b/clients/react-vite/src/App.tsx @@ -5,13 +5,13 @@ import { useSurvivorState } from "./hooks/useSurvivorState"; import { useConnect } from "@starknet-react/core"; function App() { - const { survivor } = useSurvivorState(); + const { survivor } = useSurvivorState(); - return ( - <> - - - ); + return ( + <> + + + ); } export default App; diff --git a/clients/react-vite/src/components/game/BeastCard.tsx b/clients/react-vite/src/components/game/BeastCard.tsx index c94c87b..5491ffc 100644 --- a/clients/react-vite/src/components/game/BeastCard.tsx +++ b/clients/react-vite/src/components/game/BeastCard.tsx @@ -3,68 +3,73 @@ import { RoundedContainer } from "./RoundedContainer"; import { motion } from "framer-motion"; export interface Beast { - name: string; - level: number; - health: number; - maxHealth: number; - image: string; + name: string; + level: number; + health: number; + maxHealth: number; + image: string; } export const BeastCard = ({ beast }: { beast: Beast }) => { - return ( - -
{beast.name}
- -
-
Tier 1
-
-
- + return ( + +
+ {beast.name}
-
-
- {beast.health}/{beast.maxHealth} HP -
-
-
+ +
+
Tier 1
+
+
+ +
+
+
+ {beast.health}/{beast.maxHealth} HP +
+
+
-
lvl. {beast.level}
-
- - +
lvl. {beast.level}
+
+ + + + + + {/* Add your content here */} +
+ Giant: argghhh, who do you think you are!!! I will crush + your skull and eat your flesh! Time to die human. +
+
+ +
+ + +
+
+ + +
+
- - - {/* Add your content here */} -
- Giant: argghhh, who do you think you are!!! I will crush your skull - and eat your flesh! Time to die human. -
-
- -
- - -
-
- - -
-
- - ); + ); }; diff --git a/clients/react-vite/src/components/game/Confirming.tsx b/clients/react-vite/src/components/game/Confirming.tsx index 0eb6b1c..628ecd9 100644 --- a/clients/react-vite/src/components/game/Confirming.tsx +++ b/clients/react-vite/src/components/game/Confirming.tsx @@ -1,38 +1,38 @@ import { RoundedContainer } from "./RoundedContainer"; const items = [ - { - title: "+2 Strength", - }, - { - title: "Equip Sword", - }, + { + title: "+2 Strength", + }, + { + title: "Equip Sword", + }, ]; export const Confirmation = () => { - return ( - -
Upgrading...
+ return ( + +
Upgrading...
- - {items.map((item) => ( - -
{item.title}
-
- ))} -
-
- ); + + {items.map((item) => ( + +
{item.title}
+
+ ))} +
+
+ ); }; export const ConfirmationCard = ({ - children, + children, }: { - children: React.ReactNode; + children: React.ReactNode; }) => { - return ( -
- {children} -
- ); + return ( +
+ {children} +
+ ); }; diff --git a/clients/react-vite/src/components/game/ItemBar.tsx b/clients/react-vite/src/components/game/ItemBar.tsx index 5e21089..96ed0e7 100644 --- a/clients/react-vite/src/components/game/ItemBar.tsx +++ b/clients/react-vite/src/components/game/ItemBar.tsx @@ -3,49 +3,49 @@ import { motion } from "framer-motion"; import Ring from "@/components/icons/ring.svg"; export interface Item { - id: number; - name: string; - greatness: number; - type: "Weapon" | "Waist" | "Head" | "Feet" | "Hands" | "Chest"; + id: number; + name: string; + greatness: number; + type: "Weapon" | "Waist" | "Head" | "Feet" | "Hands" | "Chest"; } export interface ItemBarProps { - item: Item; + item: Item; } const ItemBar = ({ item }: ItemBarProps) => { - // TODO: Inject actual greatness logic to next level - const getBackgroundWidth = (greatness: number) => { - return `${Math.min(100, Math.max(0, greatness))}%`; - }; - - return ( -
- -
-
- -
{item.name}
+ // TODO: Inject actual greatness logic to next level + const getBackgroundWidth = (greatness: number) => { + return `${Math.min(100, Math.max(0, greatness))}%`; + }; + + return ( +
+ +
+
+ +
{item.name}
+
+ +
Greatness: {item.greatness}
+
+ +
+ +
+ + +
- -
Greatness: {item.greatness}
-
- -
- -
- - -
-
- ); + ); }; export default ItemBar; diff --git a/clients/react-vite/src/components/game/ItemBarList.tsx b/clients/react-vite/src/components/game/ItemBarList.tsx index 59e21d3..c9ff680 100644 --- a/clients/react-vite/src/components/game/ItemBarList.tsx +++ b/clients/react-vite/src/components/game/ItemBarList.tsx @@ -1,11 +1,11 @@ import ItemBar, { Item } from "./ItemBar"; export const ItemBarList = ({ items }: { items: Item[] }) => { - return ( -
- {items.map((item) => ( - - ))} -
- ); + return ( +
+ {items.map((item) => ( + + ))} +
+ ); }; diff --git a/clients/react-vite/src/components/game/LevelUp.tsx b/clients/react-vite/src/components/game/LevelUp.tsx index 990cc1c..3b06ea5 100644 --- a/clients/react-vite/src/components/game/LevelUp.tsx +++ b/clients/react-vite/src/components/game/LevelUp.tsx @@ -3,133 +3,138 @@ import { Button } from "../ui/button"; import { RoundedContainer } from "./RoundedContainer"; import { Slider } from "@/components/ui/slider"; const stats = [ - { - stat: "Strength", - description: "Increases your physical damage", - currentStatPoints: 2, - onLevelUp: () => {}, - }, + { + stat: "Strength", + description: "Increases your physical damage", + currentStatPoints: 2, + onLevelUp: () => {}, + }, - { - stat: "Intelligence", - description: "Increases your spell damage", - currentStatPoints: 2, - onLevelUp: () => {}, - }, - { - stat: "Vitality", - description: "Increases your health points", - currentStatPoints: 2, - onLevelUp: () => {}, - }, - { - stat: "Dexterity", - description: "Increases your critical chance", - currentStatPoints: 2, - onLevelUp: () => {}, - }, - { - stat: "Wisdom", - description: "Wisdom increases chance of avoiding a Beast ambush", - currentStatPoints: 2, - onLevelUp: () => {}, - }, - { - stat: "Charisma", - description: "Charisma provides discounts on the marketplace and potions", - currentStatPoints: 2, - onLevelUp: () => {}, - }, + { + stat: "Intelligence", + description: "Increases your spell damage", + currentStatPoints: 2, + onLevelUp: () => {}, + }, + { + stat: "Vitality", + description: "Increases your health points", + currentStatPoints: 2, + onLevelUp: () => {}, + }, + { + stat: "Dexterity", + description: "Increases your critical chance", + currentStatPoints: 2, + onLevelUp: () => {}, + }, + { + stat: "Wisdom", + description: "Wisdom increases chance of avoiding a Beast ambush", + currentStatPoints: 2, + onLevelUp: () => {}, + }, + { + stat: "Charisma", + description: + "Charisma provides discounts on the marketplace and potions", + currentStatPoints: 2, + onLevelUp: () => {}, + }, ]; export const LevelUp = () => { - const [availableStatPoints, setAvailableStatPoints] = useState(2); - const [statPoints, setStatPoints] = useState(stats.map(() => 0)); + const [availableStatPoints, setAvailableStatPoints] = useState(2); + const [statPoints, setStatPoints] = useState(stats.map(() => 0)); - const handleStatChange = (index: number, value: number) => { - const oldValue = statPoints[index]; - const newStatPoints = [...statPoints]; - newStatPoints[index] = value; - setStatPoints(newStatPoints); - setAvailableStatPoints((prev) => prev - (value - oldValue)); - }; - return ( - -
Level Up
+ const handleStatChange = (index: number, value: number) => { + const oldValue = statPoints[index]; + const newStatPoints = [...statPoints]; + newStatPoints[index] = value; + setStatPoints(newStatPoints); + setAvailableStatPoints((prev) => prev - (value - oldValue)); + }; + return ( + +
Level Up
- -
-
{availableStatPoints} Stat Points
-
+ +
+
{availableStatPoints} Stat Points
+
- - -
- {stats.map((stat, index) => ( - handleStatChange(index, value)} - currentPlayerStat={stat.currentStatPoints} - /> - ))} -
- - - + + +
+ {stats.map((stat, index) => ( + + handleStatChange(index, value) + } + currentPlayerStat={stat.currentStatPoints} + /> + ))} +
+ + + + +
+
-
-
-
- ); + ); }; interface LevelUpBarProps { - currentStatPoints: number; - stat: string; - description: string; - onLevelUp: () => void; + currentStatPoints: number; + stat: string; + description: string; + onLevelUp: () => void; } export const LevelUpBar = ({ - level, - availableStatPoints, - currentValue, - onStatChange, - currentPlayerStat, + level, + availableStatPoints, + currentValue, + onStatChange, + currentPlayerStat, }: { - level: LevelUpBarProps; - availableStatPoints: number; - currentValue: number; - onStatChange: (value: number) => void; - currentPlayerStat: number; // Add this line + level: LevelUpBarProps; + availableStatPoints: number; + currentValue: number; + onStatChange: (value: number) => void; + currentPlayerStat: number; // Add this line }) => { - return ( -
-
- {level.stat} - onStatChange(value)} - /> -
- +{currentValue} - [{currentPlayerStat}] + return ( +
+
+ {level.stat} + onStatChange(value)} + /> +
+ +{currentValue} + + [{currentPlayerStat}] + +
+
+
{level.description}
-
-
{level.description}
-
- ); + ); }; diff --git a/clients/react-vite/src/components/game/LootMarket.tsx b/clients/react-vite/src/components/game/LootMarket.tsx index 6708b90..40a452b 100644 --- a/clients/react-vite/src/components/game/LootMarket.tsx +++ b/clients/react-vite/src/components/game/LootMarket.tsx @@ -3,260 +3,260 @@ import { Button } from "../ui/button"; import { RoundedContainer } from "./RoundedContainer"; const items = [ - { - id: 1, - name: "Sword", - tier: 1, - slot: "Weapon", - type: "Sword", - cost: 100, - }, - { - id: 2, - name: "Axe", - tier: 1, - slot: "Weapon", - type: "Axe", - cost: 100, - }, - { - id: 3, - name: "Shield", - tier: 1, - slot: "Offhand", - type: "Shield", - cost: 100, - }, - { - id: 4, - name: "Helmet", - tier: 1, - slot: "Head", - type: "Helmet", - cost: 100, - }, - { - id: 5, - name: "Chestplate", - tier: 1, - slot: "Chest", - type: "Chestplate", - cost: 100, - }, - { - id: 6, - name: "Boots", - tier: 1, - slot: "Feet", - type: "Boots", - cost: 100, - }, - { - id: 7, - name: "Gloves", - tier: 1, - slot: "Hands", - type: "Gloves", - cost: 100, - }, - { - id: 4, - name: "Helmet", - tier: 1, - slot: "Head", - type: "Helmet", - cost: 100, - }, - { - id: 5, - name: "Chestplate", - tier: 1, - slot: "Chest", - type: "Chestplate", - cost: 100, - }, - { - id: 6, - name: "Boots", - tier: 1, - slot: "Feet", - type: "Boots", - cost: 100, - }, - { - id: 7, - name: "Gloves", - tier: 1, - slot: "Hands", - type: "Gloves", - cost: 100, - }, - { - id: 5, - name: "Chestplate", - tier: 1, - slot: "Chest", - type: "Chestplate", - cost: 100, - }, - { - id: 6, - name: "Boots", - tier: 1, - slot: "Feet", - type: "Boots", - cost: 100, - }, - { - id: 7, - name: "Gloves", - tier: 1, - slot: "Hands", - type: "Gloves", - cost: 100, - }, - { - id: 5, - name: "Chestplate", - tier: 1, - slot: "Chest", - type: "Chestplate", - cost: 100, - }, - { - id: 6, - name: "Boots", - tier: 1, - slot: "Feet", - type: "Boots", - cost: 100, - }, - { - id: 7, - name: "Gloves", - tier: 1, - slot: "Hands", - type: "Gloves", - cost: 100, - }, - { - id: 5, - name: "Chestplate", - tier: 1, - slot: "Chest", - type: "Chestplate", - cost: 100, - }, - { - id: 6, - name: "Boots", - tier: 1, - slot: "Feet", - type: "Boots", - cost: 100, - }, - { - id: 7, - name: "Gloves", - tier: 1, - slot: "Hands", - type: "Gloves", - cost: 100, - }, + { + id: 1, + name: "Sword", + tier: 1, + slot: "Weapon", + type: "Sword", + cost: 100, + }, + { + id: 2, + name: "Axe", + tier: 1, + slot: "Weapon", + type: "Axe", + cost: 100, + }, + { + id: 3, + name: "Shield", + tier: 1, + slot: "Offhand", + type: "Shield", + cost: 100, + }, + { + id: 4, + name: "Helmet", + tier: 1, + slot: "Head", + type: "Helmet", + cost: 100, + }, + { + id: 5, + name: "Chestplate", + tier: 1, + slot: "Chest", + type: "Chestplate", + cost: 100, + }, + { + id: 6, + name: "Boots", + tier: 1, + slot: "Feet", + type: "Boots", + cost: 100, + }, + { + id: 7, + name: "Gloves", + tier: 1, + slot: "Hands", + type: "Gloves", + cost: 100, + }, + { + id: 4, + name: "Helmet", + tier: 1, + slot: "Head", + type: "Helmet", + cost: 100, + }, + { + id: 5, + name: "Chestplate", + tier: 1, + slot: "Chest", + type: "Chestplate", + cost: 100, + }, + { + id: 6, + name: "Boots", + tier: 1, + slot: "Feet", + type: "Boots", + cost: 100, + }, + { + id: 7, + name: "Gloves", + tier: 1, + slot: "Hands", + type: "Gloves", + cost: 100, + }, + { + id: 5, + name: "Chestplate", + tier: 1, + slot: "Chest", + type: "Chestplate", + cost: 100, + }, + { + id: 6, + name: "Boots", + tier: 1, + slot: "Feet", + type: "Boots", + cost: 100, + }, + { + id: 7, + name: "Gloves", + tier: 1, + slot: "Hands", + type: "Gloves", + cost: 100, + }, + { + id: 5, + name: "Chestplate", + tier: 1, + slot: "Chest", + type: "Chestplate", + cost: 100, + }, + { + id: 6, + name: "Boots", + tier: 1, + slot: "Feet", + type: "Boots", + cost: 100, + }, + { + id: 7, + name: "Gloves", + tier: 1, + slot: "Hands", + type: "Gloves", + cost: 100, + }, + { + id: 5, + name: "Chestplate", + tier: 1, + slot: "Chest", + type: "Chestplate", + cost: 100, + }, + { + id: 6, + name: "Boots", + tier: 1, + slot: "Feet", + type: "Boots", + cost: 100, + }, + { + id: 7, + name: "Gloves", + tier: 1, + slot: "Hands", + type: "Gloves", + cost: 100, + }, ]; export const LootMarket = () => { - return ( - -
Loot Market
+ return ( + +
Loot Market
- -
-
Purchase cost: 100
-
Potions
-
+ +
+
Purchase cost: 100
+
Potions
+
- -
-
item
-
Tier
-
Slot
-
Type
-
Cost
-
Actions
-
+ +
+
item
+
Tier
+
Slot
+
Type
+
Cost
+
Actions
+
- -
- {items.map((item) => ( - - ))} -
- - - + +
+ {items.map((item) => ( + + ))} +
+ + + + +
+
-
-
-
- ); + ); }; interface Item { - id: number; - name: string; - tier: number; - slot: string; - type: string; - cost: number; + id: number; + name: string; + tier: number; + slot: string; + type: string; + cost: number; } export const LootMarketItem = ({ item }: { item: Item }) => { - return ( -
-
{item.name}
-
{item.tier}
-
{item.slot}
-
{item.type}
-
{item.cost}
-
- -
-
- ); + return ( +
+
{item.name}
+
{item.tier}
+
{item.slot}
+
{item.type}
+
{item.cost}
+
+ +
+
+ ); }; export const ConfirmButton = ({ primaryText }: { primaryText: string }) => { - const [showOptions, setShowOptions] = useState(false); + const [showOptions, setShowOptions] = useState(false); - const handlePrimaryClick = () => { - setShowOptions(true); - }; + const handlePrimaryClick = () => { + setShowOptions(true); + }; - const handleOptionClick = () => { - setShowOptions(false); - }; + const handleOptionClick = () => { + setShowOptions(false); + }; - return ( -
- {!showOptions ? ( - - ) : ( -
- - + return ( +
+ {!showOptions ? ( + + ) : ( +
+ + +
+ )}
- )} -
- ); + ); }; diff --git a/clients/react-vite/src/components/game/PlayerCard.tsx b/clients/react-vite/src/components/game/PlayerCard.tsx index 60a249b..212e1bd 100644 --- a/clients/react-vite/src/components/game/PlayerCard.tsx +++ b/clients/react-vite/src/components/game/PlayerCard.tsx @@ -3,23 +3,23 @@ import { PlayerTabs } from "./PlayerTabs"; import { RoundedContainer } from "./RoundedContainer"; export const PlayerCard = () => { - return ( - -
- -
+ return ( + +
+ +
- -
- ); + +
+ ); }; diff --git a/clients/react-vite/src/components/game/PlayerPage.tsx b/clients/react-vite/src/components/game/PlayerPage.tsx index 88a0f4f..fc177dc 100644 --- a/clients/react-vite/src/components/game/PlayerPage.tsx +++ b/clients/react-vite/src/components/game/PlayerPage.tsx @@ -4,42 +4,42 @@ import { RoundedContainer } from "./RoundedContainer"; import Ring from "@/components/icons/ring.svg"; export const PlayerPage = () => { - const menuItems = [ - { - label: "Profile", - value: "profile", - icon: , - }, - { - label: "Inventory", - value: "inventory", - icon: , - }, - { - label: "Settings", - value: "settings", - icon: , - }, - ]; - return ( - -
- {menuItems.map((item) => ( - - ))} -
+ const menuItems = [ + { + label: "Profile", + value: "profile", + icon: , + }, + { + label: "Inventory", + value: "inventory", + icon: , + }, + { + label: "Settings", + value: "settings", + icon: , + }, + ]; + return ( + +
+ {menuItems.map((item) => ( + + ))} +
- + -
- {menuItems.map((item) => ( - - ))} -
-
- ); +
+ {menuItems.map((item) => ( + + ))} +
+
+ ); }; diff --git a/clients/react-vite/src/components/game/PlayerProfile.tsx b/clients/react-vite/src/components/game/PlayerProfile.tsx index 2138bb7..c08ebf1 100644 --- a/clients/react-vite/src/components/game/PlayerProfile.tsx +++ b/clients/react-vite/src/components/game/PlayerProfile.tsx @@ -1,97 +1,100 @@ import { motion } from "framer-motion"; export interface PlayerProfileProps { - name: string; - id: number; - avatar: string; - gold: number; - health: number; - maxHealth: number; - level: number; + name: string; + id: number; + avatar: string; + gold: number; + health: number; + maxHealth: number; + level: number; } export const PlayerProfile = ({ player }: { player: PlayerProfileProps }) => { - return ( -
- -
-
#{player.id}
-
{player.name}
-
- - + return ( +
+ +
+
#{player.id}
+
{player.name}
+
+ + - + +
+
-
-
- ); + ); }; export const GoldBar = ({ gold }: { gold: number }) => { - return ( -
-
Gold: {gold}
-
- ); + return ( +
+
Gold: {gold}
+
+ ); }; export const XpBar = ({ - level, - xp, - maxXp, + level, + xp, + maxXp, }: { - level: number; - xp: number; - maxXp: number; + level: number; + xp: number; + maxXp: number; }) => { - return ( -
-
- -
-
-
- Level: {level} - XP: {xp}/{maxXp} + return ( +
+
+ +
+
+
+ Level: {level} - XP: {xp}/{maxXp} +
+
-
-
- ); + ); }; export const HealthBar = ({ - health, - maxHealth, + health, + maxHealth, }: { - health: number; - maxHealth: number; + health: number; + maxHealth: number; }) => { - return ( -
-
- -
- {health}/{maxHealth} HP + return ( +
+
+ +
+ {health}/{maxHealth} HP +
+
-
-
- ); + ); }; diff --git a/clients/react-vite/src/components/game/PlayerTabs.tsx b/clients/react-vite/src/components/game/PlayerTabs.tsx index 4f75ddd..12a7618 100644 --- a/clients/react-vite/src/components/game/PlayerTabs.tsx +++ b/clients/react-vite/src/components/game/PlayerTabs.tsx @@ -5,104 +5,108 @@ import { ItemBarList } from "./ItemBarList"; import { Item } from "./ItemBar"; const items: Item[] = [ - { - id: 1, - name: "ā€œbane benderā€ katana of Power", - greatness: 10, - type: "Weapon", - }, - { - id: 2, - name: "ā€œbane benderā€ katana of Power", - greatness: 20, - type: "Weapon", - }, - { - id: 3, - name: "ā€œbane benderā€ katana of Power", - greatness: 10, - type: "Weapon", - }, - { - id: 4, - name: "ā€œbane benderā€ katana of Power", - greatness: 30, - type: "Weapon", - }, - { - id: 5, - name: "ā€œbane benderā€ katana of Power", - greatness: 40, - type: "Weapon", - }, - { - id: 6, - name: "ā€œbane benderā€ katana of Power", - greatness: 2, - type: "Weapon", - }, - { - id: 7, - name: "ā€œbane benderā€ katana of Power", - greatness: 69, - type: "Weapon", - }, - { - id: 8, - name: "ā€œbane benderā€ katana of Power", - greatness: 10, - type: "Weapon", - }, -]; - -export const PlayerTabs = () => { - const tabs = useMemo(() => { - return [ - { + { id: 1, - name: "Equipped", - content: , - }, - { + name: "ā€œbane benderā€ katana of Power", + greatness: 10, + type: "Weapon", + }, + { id: 2, - name: "Bag", - content: "Change your password here.", - }, - { + name: "ā€œbane benderā€ katana of Power", + greatness: 20, + type: "Weapon", + }, + { id: 3, - name: "History", - content: "Change your password here.", - }, - { + name: "ā€œbane benderā€ katana of Power", + greatness: 10, + type: "Weapon", + }, + { id: 4, - name: "Actions", - content: "Change your password here.", - }, - { + name: "ā€œbane benderā€ katana of Power", + greatness: 30, + type: "Weapon", + }, + { id: 5, - name: "Future", - content: "Change your password here.", - }, - ]; - }, []); + name: "ā€œbane benderā€ katana of Power", + greatness: 40, + type: "Weapon", + }, + { + id: 6, + name: "ā€œbane benderā€ katana of Power", + greatness: 2, + type: "Weapon", + }, + { + id: 7, + name: "ā€œbane benderā€ katana of Power", + greatness: 69, + type: "Weapon", + }, + { + id: 8, + name: "ā€œbane benderā€ katana of Power", + greatness: 10, + type: "Weapon", + }, +]; + +export const PlayerTabs = () => { + const tabs = useMemo(() => { + return [ + { + id: 1, + name: "Equipped", + content: , + }, + { + id: 2, + name: "Bag", + content: "Change your password here.", + }, + { + id: 3, + name: "History", + content: "Change your password here.", + }, + { + id: 4, + name: "Actions", + content: "Change your password here.", + }, + { + id: 5, + name: "Future", + content: "Change your password here.", + }, + ]; + }, []); - return ( - - - - {tabs.map((tab) => ( - - {tab.name} - - ))} - + return ( + + + + {tabs.map((tab) => ( + + {tab.name} + + ))} + - {tabs.map((tab) => ( - - {tab.content} - - ))} - - - ); + {tabs.map((tab) => ( + + {tab.content} + + ))} + + + ); }; diff --git a/clients/react-vite/src/components/game/RoundedContainer.tsx b/clients/react-vite/src/components/game/RoundedContainer.tsx index cba7742..894a2f8 100644 --- a/clients/react-vite/src/components/game/RoundedContainer.tsx +++ b/clients/react-vite/src/components/game/RoundedContainer.tsx @@ -1,17 +1,17 @@ export const RoundedContainer = ({ - children, - className, - inner, + children, + className, + inner, }: { - children: React.ReactNode; - className?: string; - inner?: boolean; + children: React.ReactNode; + className?: string; + inner?: boolean; }) => { - return ( -
- {children} -
- ); + return ( +
+ {children} +
+ ); }; diff --git a/clients/react-vite/src/components/pages/LandingPage.tsx b/clients/react-vite/src/components/pages/LandingPage.tsx index 0b123b0..85ed66c 100644 --- a/clients/react-vite/src/components/pages/LandingPage.tsx +++ b/clients/react-vite/src/components/pages/LandingPage.tsx @@ -1,11 +1,11 @@ import { useAdventurersByXPWithScores } from "@/hooks"; import { - Pagination, - PaginationContent, - PaginationItem, - PaginationLink, - PaginationNext, - PaginationPrevious, + Pagination, + PaginationContent, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, } from "@/components/ui/pagination"; import { useConnect } from "@starknet-react/core"; @@ -13,111 +13,137 @@ import { useState } from "react"; import { AnimatedNumber } from "../ui/animatedNumber"; export const LandingPage = () => { - const { connect, connectors } = useConnect(); + const { connect, connectors } = useConnect(); - const [page, setPage] = useState(1); + const [page, setPage] = useState(1); - const handlePreviousPage = () => { - setPage((prev) => Math.max(prev - 1, 1)); - }; + const handlePreviousPage = () => { + setPage((prev) => Math.max(prev - 1, 1)); + }; - const handleNextPage = () => { - setPage((prev) => Math.min(prev + 1, totalPages)); - }; + const handleNextPage = () => { + setPage((prev) => Math.min(prev + 1, totalPages)); + }; - const { adventurersWithScores, isLoading, isError } = - useAdventurersByXPWithScores({ page }); + const { adventurersWithScores, isLoading, isError } = + useAdventurersByXPWithScores({ page }); - const itemsPerPage = 10; - const totalPages = 5; - const startingRank = (page - 1) * itemsPerPage + 1; + const itemsPerPage = 10; + const totalPages = 5; + const startingRank = (page - 1) * itemsPerPage + 1; - return ( -
-
-
Leaderboard
-
-
- - - - - - - - - - - {isLoading &&
Loading...
} - {isError &&
Error
} - {adventurersWithScores?.slice(0, 1).map((adventurer, index) => ( - - - - - - - ))} - {adventurersWithScores - ?.slice(1, 12) - .map((adventurer, index) => ( - - - - - - - ))} - -
- Rank - - Player - - Score - - Lords Payout -
- {startingRank} - - {adventurer.name} - - {adventurer.xp} - - -
- {startingRank + index + 1} - - {adventurer.name} - - {adventurer.xp} - - -
-
- - - - - - {[...Array(totalPages)].map((_, i) => ( - - setPage(i + 1)} - isActive={page === i + 1} - > - {i + 1} - - - ))} - - - - - + return ( +
+
+
Leaderboard
+
+
+ + + + + + + + + + + + + + + {adventurersWithScores + ?.slice(0, 1) + .map((adventurer, index) => ( + + + + + + + ))} + {adventurersWithScores + ?.slice(1, 12) + .map((adventurer, index) => ( + + + + + + + ))} + +
+ Rank + + Player + + Score + + Lords Payout +
+ {isLoading && ( + + Loading... + + )} + {isError && Error} +
+ {startingRank} + + {adventurer.name} + + {adventurer.xp} + + +
+ {startingRank + index + 1} + + {adventurer.name} + + {adventurer.xp} + + +
+
+ + + + + + {[...Array(totalPages)].map((_, i) => ( + + setPage(i + 1)} + isActive={page === i + 1} + > + {i + 1} + + + ))} + + + + + +
+
{" "}
-
{" "} -
- ); + ); }; diff --git a/clients/react-vite/src/components/providers/QueryProvider.tsx b/clients/react-vite/src/components/providers/QueryProvider.tsx index 87c4d08..5f950b8 100644 --- a/clients/react-vite/src/components/providers/QueryProvider.tsx +++ b/clients/react-vite/src/components/providers/QueryProvider.tsx @@ -1,16 +1,18 @@ import React from "react"; import { - useQuery, - useMutation, - useQueryClient, - QueryClient, - QueryClientProvider, + useQuery, + useMutation, + useQueryClient, + QueryClient, + QueryClientProvider, } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function QueryProvider({ children }: { children: React.ReactNode }) { - return ( - {children} - ); + return ( + + {children} + + ); } diff --git a/clients/react-vite/src/components/providers/StarknetProvider.tsx b/clients/react-vite/src/components/providers/StarknetProvider.tsx index 809734b..4b6afec 100644 --- a/clients/react-vite/src/components/providers/StarknetProvider.tsx +++ b/clients/react-vite/src/components/providers/StarknetProvider.tsx @@ -4,16 +4,16 @@ import { sepolia, mainnet } from "@starknet-react/chains"; import { StarknetConfig, publicProvider, voyager } from "@starknet-react/core"; export function StarknetProvider({ children }: { children: React.ReactNode }) { - const cartridge = new CartridgeConnector([]); + const cartridge = new CartridgeConnector([]); - return ( - - {children} - - ); + return ( + + {children} + + ); } diff --git a/clients/react-vite/src/components/ui/animatedNumber.tsx b/clients/react-vite/src/components/ui/animatedNumber.tsx index cdd9ec5..c70e726 100644 --- a/clients/react-vite/src/components/ui/animatedNumber.tsx +++ b/clients/react-vite/src/components/ui/animatedNumber.tsx @@ -1,13 +1,13 @@ import { motion, useMotionValue, useTransform, animate } from "framer-motion"; import { useEffect } from "react"; export const AnimatedNumber = ({ value }: { value: number }) => { - const count = useMotionValue(0); - const rounded = useTransform(count, (latest) => latest.toFixed(2)); + const count = useMotionValue(0); + const rounded = useTransform(count, (latest) => latest.toFixed(2)); - useEffect(() => { - const controls = animate(count, value, { duration: 1 }); - return controls.stop; - }, [count, value]); + useEffect(() => { + const controls = animate(count, value, { duration: 1 }); + return controls.stop; + }, [count, value]); - return {rounded}; + return {rounded}; }; diff --git a/clients/react-vite/src/components/ui/button.tsx b/clients/react-vite/src/components/ui/button.tsx index 5f25ecc..4b73f04 100644 --- a/clients/react-vite/src/components/ui/button.tsx +++ b/clients/react-vite/src/components/ui/button.tsx @@ -5,52 +5,52 @@ import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors uppercase focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", - { - variants: { - variant: { - default: - "bg-primary text-primary-foreground hover:bg-primary/60 bg-primary/40 text-primary border-primary border", - destructive: - "bg-destructive/40 text-destructive-foreground border-destructive border-red-800 border hover:bg-destructive/90", - outline: - "border border-input bg-transparent border-primary text-primary hover:bg-primary/40 ", - secondary: - "bg-secondary text-secondary-foreground hover:bg-secondary/80", - ghost: "hover:bg-primary hover:text-accent-foreground", - link: "text-primary underline-offset-4 hover:underline", - }, - size: { - default: "h-10 px-4 py-2", - sm: "h-9 rounded-md px-3", - lg: "h-11 rounded-md px-8", - icon: "h-10 w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - } + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors uppercase focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground hover:bg-primary/60 bg-primary/40 text-primary border-primary border", + destructive: + "bg-destructive/40 text-destructive-foreground border-destructive border-red-800 border hover:bg-destructive/90", + outline: + "border border-input bg-transparent border-primary text-primary hover:bg-primary/40 ", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-primary hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } ); export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean; + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean; } const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button"; - return ( - - ); - } + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; + return ( + + ); + } ); Button.displayName = "Button"; diff --git a/clients/react-vite/src/components/ui/pagination.tsx b/clients/react-vite/src/components/ui/pagination.tsx index ea40d19..2703458 100644 --- a/clients/react-vite/src/components/ui/pagination.tsx +++ b/clients/react-vite/src/components/ui/pagination.tsx @@ -1,117 +1,117 @@ -import * as React from "react" -import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react" +import * as React from "react"; +import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"; -import { cn } from "@/lib/utils" -import { ButtonProps, buttonVariants } from "@/components/ui/button" +import { cn } from "@/lib/utils"; +import { ButtonProps, buttonVariants } from "@/components/ui/button"; const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => ( -
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/objects/prediction.ts.html b/packages/core/coverage/src/objects/prediction.ts.html index e3a22a1..0c30fcf 100644 --- a/packages/core/coverage/src/objects/prediction.ts.html +++ b/packages/core/coverage/src/objects/prediction.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/objects/prediction.ts + + + + + + + - - Code coverage report for src/objects/prediction.ts - - - - - - - - - -
-
-

All files / src/objects prediction.ts

-
- -
- 0% - Statements - 0/178 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/178 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -722,13 +723,20 @@

All files / src/objects< }  

-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/objects/survivor.ts.html b/packages/core/coverage/src/objects/survivor.ts.html index 8a424a1..903215d 100644 --- a/packages/core/coverage/src/objects/survivor.ts.html +++ b/packages/core/coverage/src/objects/survivor.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/objects/survivor.ts + + + + + + + - - Code coverage report for src/objects/survivor.ts - - - - - - - - - -
-
-

All files / src/objects survivor.ts

-
- -
- 44.25% - Statements - 235/531 -
- - -
- 54.34% - Branches - 25/46 -
- - -
- 33.33% - Functions - 17/51 -
- - -
- 44.25% - Lines - 235/531 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -1922,13 +1923,20 @@

All files / src/objects< }  

-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/provider/execute.ts.html b/packages/core/coverage/src/provider/execute.ts.html index 53beb69..ad2507f 100644 --- a/packages/core/coverage/src/provider/execute.ts.html +++ b/packages/core/coverage/src/provider/execute.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/provider/execute.ts + + + + + + + - - Code coverage report for src/provider/execute.ts - - - - - - - - - -
-
-

All files / src/provider execute.ts

-
- -
- 0% - Statements - 0/199 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/199 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -773,13 +774,20 @@

All files / src/provider }  

-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/provider/index.html b/packages/core/coverage/src/provider/index.html index 0a127c8..a1cb770 100644 --- a/packages/core/coverage/src/provider/index.html +++ b/packages/core/coverage/src/provider/index.html @@ -1,123 +1,211 @@ - + + Code coverage report for src/provider + + + + + + + - - Code coverage report for src/provider - - - - - - - - - -
-
-

All files src/provider

-
- -
- 0% - Statements - 0/245 -
- - -
- 0% - Branches - 0/2 -
- - -
- 0% - Functions - 0/2 -
- - -
- 0% - Lines - 0/245 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - + +
+
+

All files src/provider

+
+
+ 0% + Statements + 0/245 +
+ +
+ 0% + Branches + 0/2 +
+ +
+ 0% + Functions + 0/2 +
-
- - - - - - - - - - - +
+ 0% + Lines + 0/245 +
+ +

+ Press n or j to go to the next uncovered + block, b, p or k for the previous + block. +

+ + +
+
+
FileStatementsBranchesFunctionsLines
execute.ts -
-
0%0/1990%0/10%0/10%0/199
index.ts -
-
0%0/460%0/10%0/10%0/46
+ + + + + + + + + + + + + + + + + + + + + + + + + + + - -
+ File + + Statements + + Branches + + Functions + + Lines +
+ execute.ts + +
+
+
+
+
0%0/1990%0/10%0/10%0/199
-
-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/provider/index.ts.html b/packages/core/coverage/src/provider/index.ts.html index 408f567..f05b3b6 100644 --- a/packages/core/coverage/src/provider/index.ts.html +++ b/packages/core/coverage/src/provider/index.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/provider/index.ts + + + + + + + - - Code coverage report for src/provider/index.ts - - - - - - - - - -
-
-

All files / src/provider index.ts

-
- -
- 0% - Statements - 0/46 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -248,13 +249,20 @@

All files / src/provider }  

-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/state/format.ts.html b/packages/core/coverage/src/state/format.ts.html index e4b5b65..5d9f574 100644 --- a/packages/core/coverage/src/state/format.ts.html +++ b/packages/core/coverage/src/state/format.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/state/format.ts + + + + + + + - - Code coverage report for src/state/format.ts - - - - - - - - - -
-
-

All files / src/state format.ts

-
- -
- 16.59% - Statements - 124/747 -
- - -
- 100% - Branches - 4/4 -
- - -
- 10.52% - Functions - 4/38 -
- - -
- 16.59% - Lines - 124/747 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -2597,13 +2598,20 @@

All files / src/state}  

-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/state/index.html b/packages/core/coverage/src/state/index.html index 5fa9fab..8f82c6f 100644 --- a/packages/core/coverage/src/state/index.html +++ b/packages/core/coverage/src/state/index.html @@ -1,138 +1,237 @@ - + + Code coverage report for src/state + + + + + + + - - Code coverage report for src/state - - - - - - - - - -
-
-

All files src/state

-
- -
- 48.64% - Statements - 594/1221 -
- - -
- 100% - Branches - 23/23 -
- - -
- 20% - Functions - 9/45 -
- - -
- 48.64% - Lines - 594/1221 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - + +
+
+

All files src/state

+
+
+ 48.64% + Statements + 594/1221 +
+ +
+ 100% + Branches + 23/23 +
+ +
+ 20% + Functions + 9/45 +
-
- - - - - - - - - - - +
+ 48.64% + Lines + 594/1221 +
+ +

+ Press n or j to go to the next uncovered + block, b, p or k for the previous + block. +

+ + +
+
+
FileStatementsBranchesFunctionsLines
format.ts -
-
16.59%124/747100%4/410.52%4/3816.59%124/747
index.ts -
-
81.81%18/22100%3/350%2/481.81%18/22
+ + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - -
+ File + + Statements + + Branches + + Functions + + Lines +
+ format.ts + +
+
+
+
+
16.59%124/747100%4/410.52%4/3816.59%124/747
mock.ts -
-
100%452/452100%16/16100%3/3100%452/452
+ index.ts + +
+
+
+
+
81.81%18/22100%3/350%2/481.81%18/22
-
-
-
- +
+ +
+ + - \ No newline at end of file diff --git a/packages/core/coverage/src/state/index.ts.html b/packages/core/coverage/src/state/index.ts.html index d96c22b..c32e172 100644 --- a/packages/core/coverage/src/state/index.ts.html +++ b/packages/core/coverage/src/state/index.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/state/index.ts + + + + + + + - - Code coverage report for src/state/index.ts - - - - - - - - - -
-
-

All files / src/state index.ts

-
- -
- 81.81% - Statements - 18/22 -
- - -
- 100% - Branches - 3/3 -
- - -
- 50% - Functions - 2/4 -
- - -
- 81.81% - Lines - 18/22 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -173,13 +174,20 @@

All files / src/state

-
-
- +
+ + + + - \ No newline at end of file diff --git a/packages/core/coverage/src/state/mock.ts.html b/packages/core/coverage/src/state/mock.ts.html index 708f948..2ac5a2f 100644 --- a/packages/core/coverage/src/state/mock.ts.html +++ b/packages/core/coverage/src/state/mock.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/state/mock.ts + + + + + + + - - Code coverage report for src/state/mock.ts - - - - - - - - - -
-
-

All files / src/state mock.ts

-
- -
- 100% - Statements - 452/452 -
- - -
- 100% - Branches - 16/16 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 452/452 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -1523,13 +1524,20 @@

All files / src/state

-
-
- +
+ + + + - \ No newline at end of file diff --git a/packages/core/coverage/src/type/events.ts.html b/packages/core/coverage/src/type/events.ts.html index 7fa51d6..a896464 100644 --- a/packages/core/coverage/src/type/events.ts.html +++ b/packages/core/coverage/src/type/events.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/type/events.ts + + + + + + + - - Code coverage report for src/type/events.ts - - - - - - - - - -
-
-

All files / src/type events.ts

-
- -
- 100% - Statements - 24/24 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 24/24 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -1088,13 +1089,20 @@

All files / src/type };  

-
-
- +
+ + + + - \ No newline at end of file diff --git a/packages/core/coverage/src/type/index.html b/packages/core/coverage/src/type/index.html index 6c25aa6..085c7ac 100644 --- a/packages/core/coverage/src/type/index.html +++ b/packages/core/coverage/src/type/index.html @@ -1,123 +1,211 @@ - + + Code coverage report for src/type + + + + + + + - - Code coverage report for src/type - - - - - - - - - -
-
-

All files src/type

-
- -
- 100% - Statements - 557/557 -
- - -
- 100% - Branches - 19/19 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 557/557 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - + +
+
+

All files src/type

+
+
+ 100% + Statements + 557/557 +
+ +
+ 100% + Branches + 19/19 +
+ +
+ 100% + Functions + 0/0 +
-
- - - - - - - - - - - +
+ 100% + Lines + 557/557 +
+ +

+ Press n or j to go to the next uncovered + block, b, p or k for the previous + block. +

+ + +
+
+
FileStatementsBranchesFunctionsLines
events.ts -
-
100%24/24100%3/3100%0/0100%24/24
index.ts -
-
100%533/533100%16/16100%0/0100%533/533
+ + + + + + + + + + + + + + + + + + + + + + + + + + + - -
+ File + + Statements + + Branches + + Functions + + Lines +
+ events.ts + +
+
+
+
+
100%24/24100%3/3100%0/0100%24/24
-
-
-
- +
+ + + + - \ No newline at end of file diff --git a/packages/core/coverage/src/type/index.ts.html b/packages/core/coverage/src/type/index.ts.html index f5cf297..4c5d5ee 100644 --- a/packages/core/coverage/src/type/index.ts.html +++ b/packages/core/coverage/src/type/index.ts.html @@ -1,68 +1,69 @@ - + + Code coverage report for src/type/index.ts + + + + + + + - - Code coverage report for src/type/index.ts - - - - - - - - - -
-
-

All files / src/type index.ts

-
- -
- 100% - Statements - 533/533 -
- - -
- 100% - Branches - 16/16 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 533/533 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

+            
+
1 2 3 @@ -2429,13 +2430,20 @@

All files / src/type };  

-
-
- +
+ + + + - \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index 5ae2c8f..c75028d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,34 +1,34 @@ { - "name": "@lootsurvivor/core", - "version": "0.0.1", - "description": "", - "main": "./dist/index.js", - "source": "src/index.ts", - "scripts": { - "build": "tsup --format cjs,esm --dts", - "test": "vitest run --coverage" - }, - "types": "./dist/index.d.ts", - "exports": { - ".": { - "require": "./dist/index.js", - "import": "./dist/index.mjs", - "types": "./dist/index.d.ts" + "name": "@lootsurvivor/core", + "version": "0.0.1", + "description": "", + "main": "./dist/index.js", + "source": "src/index.ts", + "scripts": { + "build": "tsup --format cjs,esm --dts", + "test": "vitest run --coverage" + }, + "types": "./dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + } + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "graphql": "^16.9.0", + "graphql-request": "^7.1.0", + "starknet": "^6.11.0", + "tsup": "^8.1.0", + "typescript": "^5.5.3", + "vitest": "^2.0.2", + "zustand": "^4.5.4" + }, + "devDependencies": { + "@vitest/coverage-v8": "^2.0.2" } - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "graphql": "^16.9.0", - "graphql-request": "^7.1.0", - "starknet": "^6.11.0", - "tsup": "^8.1.0", - "typescript": "^5.5.3", - "vitest": "^2.0.2", - "zustand": "^4.5.4" - }, - "devDependencies": { - "@vitest/coverage-v8": "^2.0.2" - } } diff --git a/packages/core/src/constants/index.ts b/packages/core/src/constants/index.ts index 2aae874..f182ba8 100644 --- a/packages/core/src/constants/index.ts +++ b/packages/core/src/constants/index.ts @@ -1,5 +1,5 @@ export const S3_BUCKET = - "https://loot-survivor.s3.ap-northeast-1.amazonaws.com/"; + "https://loot-survivor.s3.ap-northeast-1.amazonaws.com/"; export const ITEM_CHARISMA_DISCOUNT = 1; export const ITEM_BASE_PRICE = 4; diff --git a/packages/core/src/objects/beasts.test.ts b/packages/core/src/objects/beasts.test.ts index 1b69feb..c9dfee4 100644 --- a/packages/core/src/objects/beasts.test.ts +++ b/packages/core/src/objects/beasts.test.ts @@ -4,111 +4,117 @@ import { Beasts, BeastType, AttackType, ArmorType } from "../type"; import { S3_BUCKET } from "../constants"; describe("BeastManager", () => { - let beastManager: BeastManager; + let beastManager: BeastManager; - beforeEach(() => { - beastManager = new BeastManager(); - }); - - describe("getBeastName", () => { - it("should return the correct beast name for a given beast number", () => { - expect(beastManager.getBeastName(Beasts.Bear)).toBe("Bear"); - expect(beastManager.getBeastName(Beasts.Wolf)).toBe("Wolf"); + beforeEach(() => { + beastManager = new BeastManager(); }); - }); - describe("getBeastNumber", () => { - it("should return the correct beast number for a given beast name", () => { - expect(beastManager.getBeastNumber("Bear")).toBe(Beasts.Bear); - expect(beastManager.getBeastNumber("Wolf")).toBe(Beasts.Wolf); + describe("getBeastName", () => { + it("should return the correct beast name for a given beast number", () => { + expect(beastManager.getBeastName(Beasts.Bear)).toBe("Bear"); + expect(beastManager.getBeastName(Beasts.Wolf)).toBe("Wolf"); + }); }); - it("should return undefined for an invalid beast name", () => { - expect(beastManager.getBeastNumber("InvalidBeast")).toBeUndefined(); + describe("getBeastNumber", () => { + it("should return the correct beast number for a given beast name", () => { + expect(beastManager.getBeastNumber("Bear")).toBe(Beasts.Bear); + expect(beastManager.getBeastNumber("Wolf")).toBe(Beasts.Wolf); + }); + + it("should return undefined for an invalid beast name", () => { + expect(beastManager.getBeastNumber("InvalidBeast")).toBeUndefined(); + }); }); - }); - describe("getBeastTier", () => { - it("should return the correct type and tier for a given beast", () => { - const bearTier = beastManager.getBeastTier(Beasts.Bear); - expect(bearTier).toEqual({ type: BeastType.Hunter, tier: 5 }); + describe("getBeastTier", () => { + it("should return the correct type and tier for a given beast", () => { + const bearTier = beastManager.getBeastTier(Beasts.Bear); + expect(bearTier).toEqual({ type: BeastType.Hunter, tier: 5 }); + }); }); - }); - describe("getAttackType", () => { - it("should return the correct attack type for a given beast type", () => { - expect(beastManager.getAttackType(BeastType.Magical)).toBe( - AttackType.Magic - ); - expect(beastManager.getAttackType(BeastType.Hunter)).toBe( - AttackType.Blade - ); - expect(beastManager.getAttackType(BeastType.Brute)).toBe( - AttackType.Bludgeon - ); + describe("getAttackType", () => { + it("should return the correct attack type for a given beast type", () => { + expect(beastManager.getAttackType(BeastType.Magical)).toBe( + AttackType.Magic + ); + expect(beastManager.getAttackType(BeastType.Hunter)).toBe( + AttackType.Blade + ); + expect(beastManager.getAttackType(BeastType.Brute)).toBe( + AttackType.Bludgeon + ); + }); }); - }); - describe("getArmorType", () => { - it("should return the correct armor type for a given beast type", () => { - expect(beastManager.getArmorType(BeastType.Magical)).toBe( - ArmorType.Cloth - ); - expect(beastManager.getArmorType(BeastType.Hunter)).toBe(ArmorType.Hide); - expect(beastManager.getArmorType(BeastType.Brute)).toBe(ArmorType.Metal); + describe("getArmorType", () => { + it("should return the correct armor type for a given beast type", () => { + expect(beastManager.getArmorType(BeastType.Magical)).toBe( + ArmorType.Cloth + ); + expect(beastManager.getArmorType(BeastType.Hunter)).toBe( + ArmorType.Hide + ); + expect(beastManager.getArmorType(BeastType.Brute)).toBe( + ArmorType.Metal + ); + }); }); - }); - describe("getBeastType", () => { - it("should return the correct beast type for a given beast", () => { - expect(beastManager.getBeastType(Beasts.Bear)).toBe(BeastType.Hunter); + describe("getBeastType", () => { + it("should return the correct beast type for a given beast", () => { + expect(beastManager.getBeastType(Beasts.Bear)).toBe( + BeastType.Hunter + ); + }); }); - }); - describe("maxBeastId", () => { - it("should return the highest beast id", () => { - const maxId = beastManager.maxBeastId(); - expect(maxId).toBeGreaterThan(0); - expect(typeof maxId).toBe("number"); + describe("maxBeastId", () => { + it("should return the highest beast id", () => { + const maxId = beastManager.maxBeastId(); + expect(maxId).toBeGreaterThan(0); + expect(typeof maxId).toBe("number"); + }); }); - }); - describe("getBeastImage", () => { - it("should return the correct image URL for a given beast", () => { - const imageUrl = beastManager.getBeastImage(Beasts.Bear); - expect(imageUrl).toContain(S3_BUCKET); - expect(imageUrl).toContain("/monsters/bear.png"); + describe("getBeastImage", () => { + it("should return the correct image URL for a given beast", () => { + const imageUrl = beastManager.getBeastImage(Beasts.Bear); + expect(imageUrl).toContain(S3_BUCKET); + expect(imageUrl).toContain("/monsters/bear.png"); + }); }); - }); - describe("elementalAdjustedDamage", () => { - it("should increase damage for effective weapon-armor pairs", () => { - const baseDamage = 100; - const adjustedDamage = beastManager.elementalAdjustedDamage( - baseDamage, - "Magic", - "Metal" - ); - expect(adjustedDamage).toBe(150); - }); + describe("elementalAdjustedDamage", () => { + it("should increase damage for effective weapon-armor pairs", () => { + const baseDamage = 100; + const adjustedDamage = beastManager.elementalAdjustedDamage( + baseDamage, + "Magic", + "Metal" + ); + expect(adjustedDamage).toBe(150); + }); - it("should decrease damage for ineffective weapon-armor pairs", () => { - const baseDamage = 100; - const adjustedDamage = beastManager.elementalAdjustedDamage( - baseDamage, - "Magic", - "Hide" - ); - expect(adjustedDamage).toBe(50); - }); + it("should decrease damage for ineffective weapon-armor pairs", () => { + const baseDamage = 100; + const adjustedDamage = beastManager.elementalAdjustedDamage( + baseDamage, + "Magic", + "Hide" + ); + expect(adjustedDamage).toBe(50); + }); - it("should not change damage for neutral weapon-armor pairs", () => { - const baseDamage = 100; - const adjustedDamage = beastManager.elementalAdjustedDamage( - baseDamage, - "Magic", - "Cloth" - ); - expect(adjustedDamage).toBe(100); + it("should not change damage for neutral weapon-armor pairs", () => { + const baseDamage = 100; + const adjustedDamage = beastManager.elementalAdjustedDamage( + baseDamage, + "Magic", + "Cloth" + ); + expect(adjustedDamage).toBe(100); + }); }); - }); }); diff --git a/packages/core/src/objects/beasts.ts b/packages/core/src/objects/beasts.ts index 404f6f3..5dea16f 100644 --- a/packages/core/src/objects/beasts.ts +++ b/packages/core/src/objects/beasts.ts @@ -2,245 +2,246 @@ import { S3_BUCKET } from "../constants"; import { ArmorType, AttackType, BeastType, Beasts } from "../type"; export class BeastManager { - private static readonly BEAST_ATTACK_TYPES: Record = { - [BeastType.Magical]: AttackType.Magic, - [BeastType.Hunter]: AttackType.Blade, - [BeastType.Brute]: AttackType.Bludgeon, - }; - - private static readonly BEAST_ARMOR_TYPES: Record = { - [BeastType.Magical]: ArmorType.Cloth, - [BeastType.Hunter]: ArmorType.Hide, - [BeastType.Brute]: ArmorType.Metal, - }; - - // pass in alternateImagePath to use a different image path - private alternateImagePath: string = ""; - - constructor(alternateImagePath?: string) { - this.alternateImagePath = alternateImagePath || ""; - } - - getBeastName(beast: Beasts): string { - return Beasts[beast]; - } - - getBeastNumber(beastName: string): Beasts | undefined { - return Beasts[beastName as keyof typeof Beasts]; - } - - getBeastTier(beast: Beasts): { type: BeastType; tier: number } { - return BEAST_TIERS[beast]; - } - - getAttackType(beastType: BeastType): AttackType { - return BeastManager.BEAST_ATTACK_TYPES[beastType]; - } - - getArmorType(beastType: BeastType): ArmorType { - return BeastManager.BEAST_ARMOR_TYPES[beastType]; - } - - getBeastType(beast: Beasts): BeastType { - return BEAST_TIERS[beast].type; - } - - maxBeastId(): number { - return Math.max( - ...Object.values(Beasts).filter( - (value): value is number => typeof value === "number" - ) - ); - } - - getBeastImage(beast: Beasts): string { - if (this.alternateImagePath) { - return this.alternateImagePath + BEAST_IMAGES[beast]; - } - return S3_BUCKET + BEAST_IMAGES[beast]; - } - - elementalAdjustedDamage( - base_attack: number, - weapon_type: string, - armor_type: string - ): number { - const ELEMENTAL_EFFECT = Math.floor(base_attack / 2); - const EFFECTIVE_PAIRS: Record = { - Magic: "Metal", - Blade: "Cloth", - Bludgeon: "Hide", - }; - const INEFFECTIVE_PAIRS: Record = { - Magic: "Hide", - Blade: "Metal", - Bludgeon: "Cloth", + private static readonly BEAST_ATTACK_TYPES: Record = + { + [BeastType.Magical]: AttackType.Magic, + [BeastType.Hunter]: AttackType.Blade, + [BeastType.Brute]: AttackType.Bludgeon, + }; + + private static readonly BEAST_ARMOR_TYPES: Record = { + [BeastType.Magical]: ArmorType.Cloth, + [BeastType.Hunter]: ArmorType.Hide, + [BeastType.Brute]: ArmorType.Metal, }; - if (EFFECTIVE_PAIRS[weapon_type] === armor_type) { - return base_attack + ELEMENTAL_EFFECT; + // pass in alternateImagePath to use a different image path + private alternateImagePath: string = ""; + + constructor(alternateImagePath?: string) { + this.alternateImagePath = alternateImagePath || ""; + } + + getBeastName(beast: Beasts): string { + return Beasts[beast]; + } + + getBeastNumber(beastName: string): Beasts | undefined { + return Beasts[beastName as keyof typeof Beasts]; + } + + getBeastTier(beast: Beasts): { type: BeastType; tier: number } { + return BEAST_TIERS[beast]; } - if (INEFFECTIVE_PAIRS[weapon_type] === armor_type) { - return base_attack - ELEMENTAL_EFFECT; + getAttackType(beastType: BeastType): AttackType { + return BeastManager.BEAST_ATTACK_TYPES[beastType]; } - return base_attack; - } + getArmorType(beastType: BeastType): ArmorType { + return BeastManager.BEAST_ARMOR_TYPES[beastType]; + } + + getBeastType(beast: Beasts): BeastType { + return BEAST_TIERS[beast].type; + } + + maxBeastId(): number { + return Math.max( + ...Object.values(Beasts).filter( + (value): value is number => typeof value === "number" + ) + ); + } + + getBeastImage(beast: Beasts): string { + if (this.alternateImagePath) { + return this.alternateImagePath + BEAST_IMAGES[beast]; + } + return S3_BUCKET + BEAST_IMAGES[beast]; + } + + elementalAdjustedDamage( + base_attack: number, + weapon_type: string, + armor_type: string + ): number { + const ELEMENTAL_EFFECT = Math.floor(base_attack / 2); + const EFFECTIVE_PAIRS: Record = { + Magic: "Metal", + Blade: "Cloth", + Bludgeon: "Hide", + }; + const INEFFECTIVE_PAIRS: Record = { + Magic: "Hide", + Blade: "Metal", + Bludgeon: "Cloth", + }; + + if (EFFECTIVE_PAIRS[weapon_type] === armor_type) { + return base_attack + ELEMENTAL_EFFECT; + } + + if (INEFFECTIVE_PAIRS[weapon_type] === armor_type) { + return base_attack - ELEMENTAL_EFFECT; + } + + return base_attack; + } } export const BEAST_TIERS: Record = { - [Beasts.Warlock]: { type: BeastType.Magical, tier: 1 }, - [Beasts.Typhon]: { type: BeastType.Magical, tier: 1 }, - [Beasts.Jiangshi]: { type: BeastType.Magical, tier: 1 }, - [Beasts.Anansi]: { type: BeastType.Magical, tier: 1 }, - [Beasts.Basilisk]: { type: BeastType.Magical, tier: 1 }, - [Beasts.Gorgon]: { type: BeastType.Magical, tier: 2 }, - [Beasts.Kitsune]: { type: BeastType.Magical, tier: 2 }, - [Beasts.Lich]: { type: BeastType.Magical, tier: 2 }, - [Beasts.Chimera]: { type: BeastType.Magical, tier: 2 }, - [Beasts.Wendigo]: { type: BeastType.Magical, tier: 2 }, - [Beasts.Rakshasa]: { type: BeastType.Magical, tier: 3 }, - [Beasts.Werewolf]: { type: BeastType.Magical, tier: 3 }, - [Beasts.Banshee]: { type: BeastType.Magical, tier: 3 }, - [Beasts.Draugr]: { type: BeastType.Magical, tier: 3 }, - [Beasts.Vampire]: { type: BeastType.Magical, tier: 3 }, - [Beasts.Goblin]: { type: BeastType.Magical, tier: 4 }, - [Beasts.Ghoul]: { type: BeastType.Magical, tier: 4 }, - [Beasts.Wraith]: { type: BeastType.Magical, tier: 4 }, - [Beasts.Sprite]: { type: BeastType.Magical, tier: 4 }, - [Beasts.Kappa]: { type: BeastType.Magical, tier: 4 }, - [Beasts.Fairy]: { type: BeastType.Magical, tier: 5 }, - [Beasts.Leprechaun]: { type: BeastType.Magical, tier: 5 }, - [Beasts.Kelpie]: { type: BeastType.Magical, tier: 5 }, - [Beasts.Pixie]: { type: BeastType.Magical, tier: 5 }, - [Beasts.Gnome]: { type: BeastType.Magical, tier: 5 }, - [Beasts.Griffin]: { type: BeastType.Hunter, tier: 1 }, - [Beasts.Manticore]: { type: BeastType.Hunter, tier: 1 }, - [Beasts.Phoenix]: { type: BeastType.Hunter, tier: 1 }, - [Beasts.Dragon]: { type: BeastType.Hunter, tier: 1 }, - [Beasts.Minotaur]: { type: BeastType.Hunter, tier: 1 }, - [Beasts.Qilin]: { type: BeastType.Hunter, tier: 2 }, - [Beasts.Ammit]: { type: BeastType.Hunter, tier: 2 }, - [Beasts.Nue]: { type: BeastType.Hunter, tier: 2 }, - [Beasts.Skinwalker]: { type: BeastType.Hunter, tier: 2 }, - [Beasts.Chupacabra]: { type: BeastType.Hunter, tier: 2 }, - [Beasts.Weretiger]: { type: BeastType.Hunter, tier: 3 }, - [Beasts.Wyvern]: { type: BeastType.Hunter, tier: 3 }, - [Beasts.Roc]: { type: BeastType.Hunter, tier: 3 }, - [Beasts.Harpy]: { type: BeastType.Hunter, tier: 3 }, - [Beasts.Pegasus]: { type: BeastType.Hunter, tier: 3 }, - [Beasts.Hippogriff]: { type: BeastType.Hunter, tier: 4 }, - [Beasts.Fenrir]: { type: BeastType.Hunter, tier: 4 }, - [Beasts.Jaguar]: { type: BeastType.Hunter, tier: 4 }, - [Beasts.Satori]: { type: BeastType.Hunter, tier: 4 }, - [Beasts.DireWolf]: { type: BeastType.Hunter, tier: 4 }, - [Beasts.Bear]: { type: BeastType.Hunter, tier: 5 }, - [Beasts.Wolf]: { type: BeastType.Hunter, tier: 5 }, - [Beasts.Mantis]: { type: BeastType.Hunter, tier: 5 }, - [Beasts.Spider]: { type: BeastType.Hunter, tier: 5 }, - [Beasts.Rat]: { type: BeastType.Hunter, tier: 5 }, - [Beasts.Kraken]: { type: BeastType.Brute, tier: 1 }, - [Beasts.Colossus]: { type: BeastType.Brute, tier: 1 }, - [Beasts.Balrog]: { type: BeastType.Brute, tier: 1 }, - [Beasts.Leviathan]: { type: BeastType.Brute, tier: 1 }, - [Beasts.Tarrasque]: { type: BeastType.Brute, tier: 1 }, - [Beasts.Titan]: { type: BeastType.Brute, tier: 2 }, - [Beasts.Nephilim]: { type: BeastType.Brute, tier: 2 }, - [Beasts.Behemoth]: { type: BeastType.Brute, tier: 2 }, - [Beasts.Hydra]: { type: BeastType.Brute, tier: 2 }, - [Beasts.Juggernaut]: { type: BeastType.Brute, tier: 2 }, - [Beasts.Oni]: { type: BeastType.Brute, tier: 3 }, - [Beasts.Jotunn]: { type: BeastType.Brute, tier: 3 }, - [Beasts.Ettin]: { type: BeastType.Brute, tier: 3 }, - [Beasts.Cyclops]: { type: BeastType.Brute, tier: 3 }, - [Beasts.Giant]: { type: BeastType.Brute, tier: 3 }, - [Beasts.NemeanLion]: { type: BeastType.Brute, tier: 4 }, - [Beasts.Berserker]: { type: BeastType.Brute, tier: 4 }, - [Beasts.Yeti]: { type: BeastType.Brute, tier: 4 }, - [Beasts.Golem]: { type: BeastType.Brute, tier: 4 }, - [Beasts.Ent]: { type: BeastType.Brute, tier: 4 }, - [Beasts.Troll]: { type: BeastType.Brute, tier: 5 }, - [Beasts.Bigfoot]: { type: BeastType.Brute, tier: 5 }, - [Beasts.Ogre]: { type: BeastType.Brute, tier: 5 }, - [Beasts.Orc]: { type: BeastType.Brute, tier: 5 }, - [Beasts.Skeleton]: { type: BeastType.Brute, tier: 5 }, + [Beasts.Warlock]: { type: BeastType.Magical, tier: 1 }, + [Beasts.Typhon]: { type: BeastType.Magical, tier: 1 }, + [Beasts.Jiangshi]: { type: BeastType.Magical, tier: 1 }, + [Beasts.Anansi]: { type: BeastType.Magical, tier: 1 }, + [Beasts.Basilisk]: { type: BeastType.Magical, tier: 1 }, + [Beasts.Gorgon]: { type: BeastType.Magical, tier: 2 }, + [Beasts.Kitsune]: { type: BeastType.Magical, tier: 2 }, + [Beasts.Lich]: { type: BeastType.Magical, tier: 2 }, + [Beasts.Chimera]: { type: BeastType.Magical, tier: 2 }, + [Beasts.Wendigo]: { type: BeastType.Magical, tier: 2 }, + [Beasts.Rakshasa]: { type: BeastType.Magical, tier: 3 }, + [Beasts.Werewolf]: { type: BeastType.Magical, tier: 3 }, + [Beasts.Banshee]: { type: BeastType.Magical, tier: 3 }, + [Beasts.Draugr]: { type: BeastType.Magical, tier: 3 }, + [Beasts.Vampire]: { type: BeastType.Magical, tier: 3 }, + [Beasts.Goblin]: { type: BeastType.Magical, tier: 4 }, + [Beasts.Ghoul]: { type: BeastType.Magical, tier: 4 }, + [Beasts.Wraith]: { type: BeastType.Magical, tier: 4 }, + [Beasts.Sprite]: { type: BeastType.Magical, tier: 4 }, + [Beasts.Kappa]: { type: BeastType.Magical, tier: 4 }, + [Beasts.Fairy]: { type: BeastType.Magical, tier: 5 }, + [Beasts.Leprechaun]: { type: BeastType.Magical, tier: 5 }, + [Beasts.Kelpie]: { type: BeastType.Magical, tier: 5 }, + [Beasts.Pixie]: { type: BeastType.Magical, tier: 5 }, + [Beasts.Gnome]: { type: BeastType.Magical, tier: 5 }, + [Beasts.Griffin]: { type: BeastType.Hunter, tier: 1 }, + [Beasts.Manticore]: { type: BeastType.Hunter, tier: 1 }, + [Beasts.Phoenix]: { type: BeastType.Hunter, tier: 1 }, + [Beasts.Dragon]: { type: BeastType.Hunter, tier: 1 }, + [Beasts.Minotaur]: { type: BeastType.Hunter, tier: 1 }, + [Beasts.Qilin]: { type: BeastType.Hunter, tier: 2 }, + [Beasts.Ammit]: { type: BeastType.Hunter, tier: 2 }, + [Beasts.Nue]: { type: BeastType.Hunter, tier: 2 }, + [Beasts.Skinwalker]: { type: BeastType.Hunter, tier: 2 }, + [Beasts.Chupacabra]: { type: BeastType.Hunter, tier: 2 }, + [Beasts.Weretiger]: { type: BeastType.Hunter, tier: 3 }, + [Beasts.Wyvern]: { type: BeastType.Hunter, tier: 3 }, + [Beasts.Roc]: { type: BeastType.Hunter, tier: 3 }, + [Beasts.Harpy]: { type: BeastType.Hunter, tier: 3 }, + [Beasts.Pegasus]: { type: BeastType.Hunter, tier: 3 }, + [Beasts.Hippogriff]: { type: BeastType.Hunter, tier: 4 }, + [Beasts.Fenrir]: { type: BeastType.Hunter, tier: 4 }, + [Beasts.Jaguar]: { type: BeastType.Hunter, tier: 4 }, + [Beasts.Satori]: { type: BeastType.Hunter, tier: 4 }, + [Beasts.DireWolf]: { type: BeastType.Hunter, tier: 4 }, + [Beasts.Bear]: { type: BeastType.Hunter, tier: 5 }, + [Beasts.Wolf]: { type: BeastType.Hunter, tier: 5 }, + [Beasts.Mantis]: { type: BeastType.Hunter, tier: 5 }, + [Beasts.Spider]: { type: BeastType.Hunter, tier: 5 }, + [Beasts.Rat]: { type: BeastType.Hunter, tier: 5 }, + [Beasts.Kraken]: { type: BeastType.Brute, tier: 1 }, + [Beasts.Colossus]: { type: BeastType.Brute, tier: 1 }, + [Beasts.Balrog]: { type: BeastType.Brute, tier: 1 }, + [Beasts.Leviathan]: { type: BeastType.Brute, tier: 1 }, + [Beasts.Tarrasque]: { type: BeastType.Brute, tier: 1 }, + [Beasts.Titan]: { type: BeastType.Brute, tier: 2 }, + [Beasts.Nephilim]: { type: BeastType.Brute, tier: 2 }, + [Beasts.Behemoth]: { type: BeastType.Brute, tier: 2 }, + [Beasts.Hydra]: { type: BeastType.Brute, tier: 2 }, + [Beasts.Juggernaut]: { type: BeastType.Brute, tier: 2 }, + [Beasts.Oni]: { type: BeastType.Brute, tier: 3 }, + [Beasts.Jotunn]: { type: BeastType.Brute, tier: 3 }, + [Beasts.Ettin]: { type: BeastType.Brute, tier: 3 }, + [Beasts.Cyclops]: { type: BeastType.Brute, tier: 3 }, + [Beasts.Giant]: { type: BeastType.Brute, tier: 3 }, + [Beasts.NemeanLion]: { type: BeastType.Brute, tier: 4 }, + [Beasts.Berserker]: { type: BeastType.Brute, tier: 4 }, + [Beasts.Yeti]: { type: BeastType.Brute, tier: 4 }, + [Beasts.Golem]: { type: BeastType.Brute, tier: 4 }, + [Beasts.Ent]: { type: BeastType.Brute, tier: 4 }, + [Beasts.Troll]: { type: BeastType.Brute, tier: 5 }, + [Beasts.Bigfoot]: { type: BeastType.Brute, tier: 5 }, + [Beasts.Ogre]: { type: BeastType.Brute, tier: 5 }, + [Beasts.Orc]: { type: BeastType.Brute, tier: 5 }, + [Beasts.Skeleton]: { type: BeastType.Brute, tier: 5 }, }; export const BEAST_IMAGES: Record = { - [Beasts.Warlock]: "/monsters/warlock.png", - [Beasts.Typhon]: "/monsters/typhon.png", - [Beasts.Jiangshi]: "/monsters/jiangshi.png", - [Beasts.Anansi]: "/monsters/anansi.png", - [Beasts.Basilisk]: "/monsters/basilisk.png", - [Beasts.Gorgon]: "/monsters/gorgon.png", - [Beasts.Kitsune]: "/monsters/kitsune.png", - [Beasts.Lich]: "/monsters/lich.png", - [Beasts.Chimera]: "/monsters/chimera.png", - [Beasts.Wendigo]: "/monsters/wendigo.png", - [Beasts.Rakshasa]: "/monsters/rakshasa.png", - [Beasts.Werewolf]: "/monsters/werewolf.png", - [Beasts.Banshee]: "/monsters/banshee.png", - [Beasts.Draugr]: "/monsters/draugr.png", - [Beasts.Vampire]: "/monsters/vampire.png", - [Beasts.Goblin]: "/monsters/goblin.png", - [Beasts.Ghoul]: "/monsters/ghoul.png", - [Beasts.Wraith]: "/monsters/wraith.png", - [Beasts.Sprite]: "/monsters/sprite.png", - [Beasts.Kappa]: "/monsters/kappa.png", - [Beasts.Fairy]: "/monsters/fairy.png", - [Beasts.Leprechaun]: "/monsters/leprechaun.png", - [Beasts.Kelpie]: "/monsters/kelpie.png", - [Beasts.Pixie]: "/monsters/pixie.png", - [Beasts.Gnome]: "/monsters/gnome.png", - [Beasts.Griffin]: "/monsters/griffin.png", - [Beasts.Manticore]: "/monsters/manticore.png", - [Beasts.Phoenix]: "/monsters/phoenix.png", - [Beasts.Dragon]: "/monsters/dragon.png", - [Beasts.Minotaur]: "/monsters/minotaur.png", - [Beasts.Qilin]: "/monsters/qilin.png", - [Beasts.Ammit]: "/monsters/ammit.png", - [Beasts.Nue]: "/monsters/nue.png", - [Beasts.Skinwalker]: "/monsters/skinwalker.png", - [Beasts.Chupacabra]: "/monsters/chupacabra.png", - [Beasts.Weretiger]: "/monsters/weretiger.png", - [Beasts.Wyvern]: "/monsters/wyvern.png", - [Beasts.Roc]: "/monsters/roc.png", - [Beasts.Harpy]: "/monsters/harpy.png", - [Beasts.Pegasus]: "/monsters/pegasus.png", - [Beasts.Hippogriff]: "/monsters/hippogriff.png", - [Beasts.Fenrir]: "/monsters/fenrir.png", - [Beasts.Jaguar]: "/monsters/jaguar.png", - [Beasts.Satori]: "/monsters/satori.png", - [Beasts.DireWolf]: "/monsters/direwolf.png", - [Beasts.Bear]: "/monsters/bear.png", - [Beasts.Wolf]: "/monsters/wolf.png", - [Beasts.Mantis]: "/monsters/mantis.png", - [Beasts.Spider]: "/monsters/spider.png", - [Beasts.Rat]: "/monsters/rat.png", - [Beasts.Kraken]: "/monsters/kraken.png", - [Beasts.Colossus]: "/monsters/colossus.png", - [Beasts.Balrog]: "/monsters/balrog.png", - [Beasts.Leviathan]: "/monsters/leviathan.png", - [Beasts.Tarrasque]: "/monsters/tarrasque.png", - [Beasts.Titan]: "/monsters/titan.png", - [Beasts.Nephilim]: "/monsters/nephilim.png", - [Beasts.Behemoth]: "/monsters/behemoth.png", - [Beasts.Hydra]: "/monsters/hydra.png", - [Beasts.Juggernaut]: "/monsters/juggernaut.png", - [Beasts.Oni]: "/monsters/oni.png", - [Beasts.Jotunn]: "/monsters/jotunn.png", - [Beasts.Ettin]: "/monsters/ettin.png", - [Beasts.Cyclops]: "/monsters/cyclops.png", - [Beasts.Giant]: "/monsters/giant.png", - [Beasts.NemeanLion]: "/monsters/nemeanlion.png", - [Beasts.Berserker]: "/monsters/berserker.png", - [Beasts.Yeti]: "/monsters/yeti.png", - [Beasts.Golem]: "/monsters/golem.png", - [Beasts.Ent]: "/monsters/ent.png", - [Beasts.Troll]: "/monsters/troll.png", - [Beasts.Bigfoot]: "/monsters/bigfoot.png", - [Beasts.Ogre]: "/monsters/ogre.png", - [Beasts.Orc]: "/monsters/orc.png", - [Beasts.Skeleton]: "/monsters/skeleton.png", + [Beasts.Warlock]: "/monsters/warlock.png", + [Beasts.Typhon]: "/monsters/typhon.png", + [Beasts.Jiangshi]: "/monsters/jiangshi.png", + [Beasts.Anansi]: "/monsters/anansi.png", + [Beasts.Basilisk]: "/monsters/basilisk.png", + [Beasts.Gorgon]: "/monsters/gorgon.png", + [Beasts.Kitsune]: "/monsters/kitsune.png", + [Beasts.Lich]: "/monsters/lich.png", + [Beasts.Chimera]: "/monsters/chimera.png", + [Beasts.Wendigo]: "/monsters/wendigo.png", + [Beasts.Rakshasa]: "/monsters/rakshasa.png", + [Beasts.Werewolf]: "/monsters/werewolf.png", + [Beasts.Banshee]: "/monsters/banshee.png", + [Beasts.Draugr]: "/monsters/draugr.png", + [Beasts.Vampire]: "/monsters/vampire.png", + [Beasts.Goblin]: "/monsters/goblin.png", + [Beasts.Ghoul]: "/monsters/ghoul.png", + [Beasts.Wraith]: "/monsters/wraith.png", + [Beasts.Sprite]: "/monsters/sprite.png", + [Beasts.Kappa]: "/monsters/kappa.png", + [Beasts.Fairy]: "/monsters/fairy.png", + [Beasts.Leprechaun]: "/monsters/leprechaun.png", + [Beasts.Kelpie]: "/monsters/kelpie.png", + [Beasts.Pixie]: "/monsters/pixie.png", + [Beasts.Gnome]: "/monsters/gnome.png", + [Beasts.Griffin]: "/monsters/griffin.png", + [Beasts.Manticore]: "/monsters/manticore.png", + [Beasts.Phoenix]: "/monsters/phoenix.png", + [Beasts.Dragon]: "/monsters/dragon.png", + [Beasts.Minotaur]: "/monsters/minotaur.png", + [Beasts.Qilin]: "/monsters/qilin.png", + [Beasts.Ammit]: "/monsters/ammit.png", + [Beasts.Nue]: "/monsters/nue.png", + [Beasts.Skinwalker]: "/monsters/skinwalker.png", + [Beasts.Chupacabra]: "/monsters/chupacabra.png", + [Beasts.Weretiger]: "/monsters/weretiger.png", + [Beasts.Wyvern]: "/monsters/wyvern.png", + [Beasts.Roc]: "/monsters/roc.png", + [Beasts.Harpy]: "/monsters/harpy.png", + [Beasts.Pegasus]: "/monsters/pegasus.png", + [Beasts.Hippogriff]: "/monsters/hippogriff.png", + [Beasts.Fenrir]: "/monsters/fenrir.png", + [Beasts.Jaguar]: "/monsters/jaguar.png", + [Beasts.Satori]: "/monsters/satori.png", + [Beasts.DireWolf]: "/monsters/direwolf.png", + [Beasts.Bear]: "/monsters/bear.png", + [Beasts.Wolf]: "/monsters/wolf.png", + [Beasts.Mantis]: "/monsters/mantis.png", + [Beasts.Spider]: "/monsters/spider.png", + [Beasts.Rat]: "/monsters/rat.png", + [Beasts.Kraken]: "/monsters/kraken.png", + [Beasts.Colossus]: "/monsters/colossus.png", + [Beasts.Balrog]: "/monsters/balrog.png", + [Beasts.Leviathan]: "/monsters/leviathan.png", + [Beasts.Tarrasque]: "/monsters/tarrasque.png", + [Beasts.Titan]: "/monsters/titan.png", + [Beasts.Nephilim]: "/monsters/nephilim.png", + [Beasts.Behemoth]: "/monsters/behemoth.png", + [Beasts.Hydra]: "/monsters/hydra.png", + [Beasts.Juggernaut]: "/monsters/juggernaut.png", + [Beasts.Oni]: "/monsters/oni.png", + [Beasts.Jotunn]: "/monsters/jotunn.png", + [Beasts.Ettin]: "/monsters/ettin.png", + [Beasts.Cyclops]: "/monsters/cyclops.png", + [Beasts.Giant]: "/monsters/giant.png", + [Beasts.NemeanLion]: "/monsters/nemeanlion.png", + [Beasts.Berserker]: "/monsters/berserker.png", + [Beasts.Yeti]: "/monsters/yeti.png", + [Beasts.Golem]: "/monsters/golem.png", + [Beasts.Ent]: "/monsters/ent.png", + [Beasts.Troll]: "/monsters/troll.png", + [Beasts.Bigfoot]: "/monsters/bigfoot.png", + [Beasts.Ogre]: "/monsters/ogre.png", + [Beasts.Orc]: "/monsters/orc.png", + [Beasts.Skeleton]: "/monsters/skeleton.png", }; diff --git a/packages/core/src/objects/loot.test.ts b/packages/core/src/objects/loot.test.ts index 64a5566..54a5350 100644 --- a/packages/core/src/objects/loot.test.ts +++ b/packages/core/src/objects/loot.test.ts @@ -1,91 +1,91 @@ import { describe, it, expect, vi } from "vitest"; import { LootManager } from "./loot"; import { - Loot, - ItemNamePrefix, - ItemNameSuffix, - ItemSuffix, - ItemType, - ItemSlot, - StatBoost, - StatType, + Loot, + ItemNamePrefix, + ItemNameSuffix, + ItemSuffix, + ItemType, + ItemSlot, + StatBoost, + StatType, } from "../type"; describe("LootManager", () => { - const lootManager = new LootManager(Loot.Pendant, 1000, BigInt(1234567)); - - it("should return the correct item name", () => { - expect(lootManager.getItemName()).toBe("Pendant"); - }); - - it("should return the correct item number", () => { - expect(lootManager.getItemNumber("Pendant")).toBe(Loot.Pendant); - }); - - it("should return the correct item type", () => { - expect(lootManager.getItemType()).toBe(ItemType.Necklace); - }); - - it("should return the correct item slot", () => { - expect(lootManager.getItemSlot()).toBe(ItemSlot.Neck); - }); - - it("should return the correct item name prefix", () => { - expect(lootManager.getItemNamePrefix(ItemNamePrefix.Dire)).toBe("Dire"); - }); - - it("should return the correct item name prefix number", () => { - expect(lootManager.getItemNamePrefixNumber("Agony")).toBe( - ItemNamePrefix.Agony - ); - }); - - it("should return the correct item name suffix", () => { - expect(lootManager.getItemNameSuffix(ItemNameSuffix.Bane)).toBe("Bane"); - }); - - it("should return the correct item name suffix number", () => { - expect(lootManager.getItemNameSuffixNumber("Bane")).toBe( - ItemNameSuffix.Bane - ); - }); - - it("should return the correct item suffix number", () => { - expect(lootManager.getItemSuffixNumber("Of Anger")).toBe( - ItemSuffix.OfAnger - ); - }); - - it("should return the correct item suffix boost string", () => { - const expectedBoostString = "Strength +2 Dexterity +1"; - expect(lootManager.getItemSuffixBoostString(ItemSuffix.OfAnger)).toBe( - expectedBoostString - ); - }); - - it("should return the correct item suffix boost string", () => { - const expectedBoostString = "Strength +2 Dexterity +1"; - expect(lootManager.getItemSuffixBoostString(ItemSuffix.OfAnger)).toBe( - expectedBoostString - ); - }); - - it("should return the correct item slot number", () => { - expect(lootManager.getItemSlotNumber(ItemSlot.Neck)).toBe(7); - }); - - it("should return the correct item slot from number", () => { - expect(lootManager.getItemSlotFromNumber(1)).toBe(ItemSlot.Weapon); - }); - describe("getFullItemName", () => { - it("should return a full item name with all components", () => { - // Mock the necessary methods - - const result = lootManager.getFullItemName(); - - expect(result).toBe( - "Whisper Lights Pendant Of Anger (Strength +2 Dexterity +1)" - ); + const lootManager = new LootManager(Loot.Pendant, 1000, BigInt(1234567)); + + it("should return the correct item name", () => { + expect(lootManager.getItemName()).toBe("Pendant"); + }); + + it("should return the correct item number", () => { + expect(lootManager.getItemNumber("Pendant")).toBe(Loot.Pendant); + }); + + it("should return the correct item type", () => { + expect(lootManager.getItemType()).toBe(ItemType.Necklace); + }); + + it("should return the correct item slot", () => { + expect(lootManager.getItemSlot()).toBe(ItemSlot.Neck); + }); + + it("should return the correct item name prefix", () => { + expect(lootManager.getItemNamePrefix(ItemNamePrefix.Dire)).toBe("Dire"); + }); + + it("should return the correct item name prefix number", () => { + expect(lootManager.getItemNamePrefixNumber("Agony")).toBe( + ItemNamePrefix.Agony + ); + }); + + it("should return the correct item name suffix", () => { + expect(lootManager.getItemNameSuffix(ItemNameSuffix.Bane)).toBe("Bane"); + }); + + it("should return the correct item name suffix number", () => { + expect(lootManager.getItemNameSuffixNumber("Bane")).toBe( + ItemNameSuffix.Bane + ); + }); + + it("should return the correct item suffix number", () => { + expect(lootManager.getItemSuffixNumber("Of Anger")).toBe( + ItemSuffix.OfAnger + ); + }); + + it("should return the correct item suffix boost string", () => { + const expectedBoostString = "Strength +2 Dexterity +1"; + expect(lootManager.getItemSuffixBoostString(ItemSuffix.OfAnger)).toBe( + expectedBoostString + ); + }); + + it("should return the correct item suffix boost string", () => { + const expectedBoostString = "Strength +2 Dexterity +1"; + expect(lootManager.getItemSuffixBoostString(ItemSuffix.OfAnger)).toBe( + expectedBoostString + ); + }); + + it("should return the correct item slot number", () => { + expect(lootManager.getItemSlotNumber(ItemSlot.Neck)).toBe(7); + }); + + it("should return the correct item slot from number", () => { + expect(lootManager.getItemSlotFromNumber(1)).toBe(ItemSlot.Weapon); + }); + describe("getFullItemName", () => { + it("should return a full item name with all components", () => { + // Mock the necessary methods + + const result = lootManager.getFullItemName(); + + expect(result).toBe( + "Whisper Lights Pendant Of Anger (Strength +2 Dexterity +1)" + ); + }); }); - }); }); diff --git a/packages/core/src/objects/loot.ts b/packages/core/src/objects/loot.ts index 1733a90..b5b0581 100644 --- a/packages/core/src/objects/loot.ts +++ b/packages/core/src/objects/loot.ts @@ -1,509 +1,516 @@ import { - ITEM_SLOT_TO_NUMBER, - ITEM_SUFFIX_BOOST, - ItemNamePrefix, - ItemNameSuffix, - ItemSlot, - ItemSuffix, - ItemType, - Loot, - NUMBER_TO_ITEM_SLOT, - StatBoost, - StatType, + ITEM_SLOT_TO_NUMBER, + ITEM_SUFFIX_BOOST, + ItemNamePrefix, + ItemNameSuffix, + ItemSlot, + ItemSuffix, + ItemType, + Loot, + NUMBER_TO_ITEM_SLOT, + StatBoost, + StatType, } from "../type"; export class LootManager { - private static TWO_POW_64 = BigInt("0x10000000000000000"); - private static NUM_ITEMS = 101; - - private static SUFFIX_UNLOCK_GREATNESS = 15; - private static PREFIXES_UNLOCK_GREATNESS = 19; - - private item: Loot; - private xp: number; - private seed: bigint; - - constructor(item: Loot, xp: number, seed: bigint) { - this.item = item; - this.xp = xp; - this.seed = seed; - } - - getFullItemName(): string { - const itemName = this.getItemName(); - const specials = this.getSpecials( - this.item, - this.calculateGreatness(this.xp), - this.seed - ); - - let name = itemName; - - if (specials.special1 !== 0) { - const suffix = this.getItemSuffixName(specials.special1); - const boostString = this.getItemSuffixBoostString(specials.special1); - name += ` ${suffix} (${boostString})`; + private static TWO_POW_64 = BigInt("0x10000000000000000"); + private static NUM_ITEMS = 101; + + private static SUFFIX_UNLOCK_GREATNESS = 15; + private static PREFIXES_UNLOCK_GREATNESS = 19; + + private item: Loot; + private xp: number; + private seed: bigint; + + constructor(item: Loot, xp: number, seed: bigint) { + this.item = item; + this.xp = xp; + this.seed = seed; } - if (specials.special2 !== 0) { - const prefix1 = this.getItemNamePrefix(specials.special2); - name = `${prefix1} ${name}`; + getFullItemName(): string { + const itemName = this.getItemName(); + const specials = this.getSpecials( + this.item, + this.calculateGreatness(this.xp), + this.seed + ); + + let name = itemName; + + if (specials.special1 !== 0) { + const suffix = this.getItemSuffixName(specials.special1); + const boostString = this.getItemSuffixBoostString( + specials.special1 + ); + name += ` ${suffix} (${boostString})`; + } + + if (specials.special2 !== 0) { + const prefix1 = this.getItemNamePrefix(specials.special2); + name = `${prefix1} ${name}`; + } + + if (specials.special3 !== 0) { + const prefix2 = this.getItemNameSuffix(specials.special3); + name = `${prefix2} ${name}`; + } + + return name.trim(); } - if (specials.special3 !== 0) { - const prefix2 = this.getItemNameSuffix(specials.special3); - name = `${prefix2} ${name}`; + private getSpecials( + item: Loot, + greatness: number, + seed: bigint + ): { special1: number; special2: number; special3: number } { + if (greatness < LootManager.SUFFIX_UNLOCK_GREATNESS) { + return { special1: 0, special2: 0, special3: 0 }; + } else if (greatness < LootManager.PREFIXES_UNLOCK_GREATNESS) { + return { + special1: this.getItemSuffix(item, seed), + special2: 0, + special3: 0, + }; + } else { + return { + special1: this.getItemSuffix(item, seed), + special2: this.getPrefix1(item, seed), + special3: this.getPrefix2(item, seed), + }; + } } - return name.trim(); - } - - private getSpecials( - item: Loot, - greatness: number, - seed: bigint - ): { special1: number; special2: number; special3: number } { - if (greatness < LootManager.SUFFIX_UNLOCK_GREATNESS) { - return { special1: 0, special2: 0, special3: 0 }; - } else if (greatness < LootManager.PREFIXES_UNLOCK_GREATNESS) { - return { - special1: this.getItemSuffix(item, seed), - special2: 0, - special3: 0, - }; - } else { - return { - special1: this.getItemSuffix(item, seed), - special2: this.getPrefix1(item, seed), - special3: this.getPrefix2(item, seed), - }; + getItemName(): string { + return Loot[this.item]; } - } - - getItemName(): string { - return Loot[this.item]; - } - - getItemNumber(itemName: string): Loot | undefined { - return Loot[itemName as keyof typeof Loot]; - } - - getItemType(): ItemType { - return ITEM_TYPES[this.item]; - } - - getItemSlot(): ItemSlot { - return ITEM_SLOTS[this.item]; - } - - getItemNamePrefix(prefix: ItemNamePrefix): string { - return ItemNamePrefix[prefix]; - } - - getItemNamePrefixNumber(prefixName: string): ItemNamePrefix | undefined { - return ItemNamePrefix[prefixName as keyof typeof ItemNamePrefix]; - } - - getItemNameSuffix(suffix: ItemNameSuffix): string { - return ItemNameSuffix[suffix]; - } - - getItemNameSuffixNumber(suffixName: string): ItemNameSuffix | undefined { - return ItemNameSuffix[suffixName as keyof typeof ItemNameSuffix]; - } - - getItemSuffix(itemId: number, seed: bigint): ItemSuffix { - const namingSeed = this.generateNamingSeed(itemId, seed); - const suffixIndex = Number( - (namingSeed % BigInt(Object.keys(ItemSuffix).length / 2)) + BigInt(1) - ); - return suffixIndex as ItemSuffix; - } - - private generateNamingSeed(itemId: number, seed: bigint): bigint { - const nameSeedU64 = seed % LootManager.TWO_POW_64; - - let itemEntropy: bigint; - const sum = nameSeedU64 + BigInt(itemId); - if (sum < LootManager.TWO_POW_64) { - itemEntropy = sum; - } else { - itemEntropy = nameSeedU64 - BigInt(itemId); + + getItemNumber(itemName: string): Loot | undefined { + return Loot[itemName as keyof typeof Loot]; + } + + getItemType(): ItemType { + return ITEM_TYPES[this.item]; } - const rnd = itemEntropy % BigInt(LootManager.NUM_ITEMS); - return ( - rnd * BigInt(this.getSlotLength(this.getSlot(itemId))) + BigInt(itemId) - ); - } - - getItemSuffixName(suffix: ItemSuffix): string { - return ItemSuffix[suffix].replace(/([A-Z])/g, " $1").trim(); - } - - private getSlot(itemId: number): ItemSlot { - return ITEM_SLOTS[itemId as Loot]; - } - - private getSlotLength(slot: ItemSlot): number { - return Object.values(ITEM_SLOTS).filter((s) => s === slot).length; - } - - getItemSuffixNumber(suffixName: string): ItemSuffix | undefined { - const formattedName = suffixName.replace(/\s+/g, ""); - return ItemSuffix[formattedName as keyof typeof ItemSuffix]; - } - - calculateGreatness(xp: number) { - return Math.max(Math.floor(Math.sqrt(xp)), 1); - } - - getItemSuffixBoost(suffix: ItemSuffix): StatBoost { - return ITEM_SUFFIX_BOOST[suffix]; - } - - getItemSuffixBoostString(suffix: ItemSuffix): string { - const boost = ITEM_SUFFIX_BOOST[suffix]; - return Object.entries(boost) - .map( - ([stat, value]) => `${StatType[stat as unknown as StatType]} +${value}` - ) - .join(" "); - } - - getItemSlotNumber(slot: ItemSlot): number { - return ITEM_SLOT_TO_NUMBER[slot]; - } - - getItemSlotFromNumber(number: number): ItemSlot | undefined { - return NUMBER_TO_ITEM_SLOT[number]; - } - - getPrefix1(itemId: number, seed: bigint): ItemNamePrefix { - const namingSeed = this.generateNamingSeed(itemId, seed); - const prefixIndex = Number( - (namingSeed % BigInt(Object.keys(ItemNamePrefix).length / 2)) + BigInt(1) - ); - return prefixIndex as ItemNamePrefix; - } - - getPrefix2(itemId: number, seed: bigint): ItemNameSuffix { - const namingSeed = this.generateNamingSeed(itemId, seed); - const suffixIndex = Number( - (namingSeed % BigInt(Object.keys(ItemNameSuffix).length / 2)) + BigInt(1) - ); - return suffixIndex as ItemNameSuffix; - } + getItemSlot(): ItemSlot { + return ITEM_SLOTS[this.item]; + } + + getItemNamePrefix(prefix: ItemNamePrefix): string { + return ItemNamePrefix[prefix]; + } + + getItemNamePrefixNumber(prefixName: string): ItemNamePrefix | undefined { + return ItemNamePrefix[prefixName as keyof typeof ItemNamePrefix]; + } + + getItemNameSuffix(suffix: ItemNameSuffix): string { + return ItemNameSuffix[suffix]; + } + + getItemNameSuffixNumber(suffixName: string): ItemNameSuffix | undefined { + return ItemNameSuffix[suffixName as keyof typeof ItemNameSuffix]; + } + + getItemSuffix(itemId: number, seed: bigint): ItemSuffix { + const namingSeed = this.generateNamingSeed(itemId, seed); + const suffixIndex = Number( + (namingSeed % BigInt(Object.keys(ItemSuffix).length / 2)) + + BigInt(1) + ); + return suffixIndex as ItemSuffix; + } + + private generateNamingSeed(itemId: number, seed: bigint): bigint { + const nameSeedU64 = seed % LootManager.TWO_POW_64; + + let itemEntropy: bigint; + const sum = nameSeedU64 + BigInt(itemId); + if (sum < LootManager.TWO_POW_64) { + itemEntropy = sum; + } else { + itemEntropy = nameSeedU64 - BigInt(itemId); + } + + const rnd = itemEntropy % BigInt(LootManager.NUM_ITEMS); + return ( + rnd * BigInt(this.getSlotLength(this.getSlot(itemId))) + + BigInt(itemId) + ); + } + + getItemSuffixName(suffix: ItemSuffix): string { + return ItemSuffix[suffix].replace(/([A-Z])/g, " $1").trim(); + } + + private getSlot(itemId: number): ItemSlot { + return ITEM_SLOTS[itemId as Loot]; + } + + private getSlotLength(slot: ItemSlot): number { + return Object.values(ITEM_SLOTS).filter((s) => s === slot).length; + } + + getItemSuffixNumber(suffixName: string): ItemSuffix | undefined { + const formattedName = suffixName.replace(/\s+/g, ""); + return ItemSuffix[formattedName as keyof typeof ItemSuffix]; + } + + calculateGreatness(xp: number) { + return Math.max(Math.floor(Math.sqrt(xp)), 1); + } + + getItemSuffixBoost(suffix: ItemSuffix): StatBoost { + return ITEM_SUFFIX_BOOST[suffix]; + } + + getItemSuffixBoostString(suffix: ItemSuffix): string { + const boost = ITEM_SUFFIX_BOOST[suffix]; + return Object.entries(boost) + .map( + ([stat, value]) => + `${StatType[stat as unknown as StatType]} +${value}` + ) + .join(" "); + } + + getItemSlotNumber(slot: ItemSlot): number { + return ITEM_SLOT_TO_NUMBER[slot]; + } + + getItemSlotFromNumber(number: number): ItemSlot | undefined { + return NUMBER_TO_ITEM_SLOT[number]; + } + + getPrefix1(itemId: number, seed: bigint): ItemNamePrefix { + const namingSeed = this.generateNamingSeed(itemId, seed); + const prefixIndex = Number( + (namingSeed % BigInt(Object.keys(ItemNamePrefix).length / 2)) + + BigInt(1) + ); + return prefixIndex as ItemNamePrefix; + } + + getPrefix2(itemId: number, seed: bigint): ItemNameSuffix { + const namingSeed = this.generateNamingSeed(itemId, seed); + const suffixIndex = Number( + (namingSeed % BigInt(Object.keys(ItemNameSuffix).length / 2)) + + BigInt(1) + ); + return suffixIndex as ItemNameSuffix; + } } export const ITEM_TYPES: Record = { - [Loot.Pendant]: ItemType.Necklace, - [Loot.Necklace]: ItemType.Necklace, - [Loot.Amulet]: ItemType.Necklace, - [Loot.SilverRing]: ItemType.Ring, - [Loot.BronzeRing]: ItemType.Ring, - [Loot.PlatinumRing]: ItemType.Ring, - [Loot.TitaniumRing]: ItemType.Ring, - [Loot.GoldRing]: ItemType.Ring, - [Loot.GhostWand]: ItemType.Magic, - [Loot.GraveWand]: ItemType.Magic, - [Loot.BoneWand]: ItemType.Magic, - [Loot.Wand]: ItemType.Magic, - [Loot.Grimoire]: ItemType.Magic, - [Loot.Chronicle]: ItemType.Magic, - [Loot.Tome]: ItemType.Magic, - [Loot.Book]: ItemType.Magic, - [Loot.DivineRobe]: ItemType.Cloth, - [Loot.SilkRobe]: ItemType.Cloth, - [Loot.LinenRobe]: ItemType.Cloth, - [Loot.Robe]: ItemType.Cloth, - [Loot.Shirt]: ItemType.Cloth, - [Loot.Crown]: ItemType.Cloth, - [Loot.DivineHood]: ItemType.Cloth, - [Loot.SilkHood]: ItemType.Cloth, - [Loot.LinenHood]: ItemType.Cloth, - [Loot.Hood]: ItemType.Cloth, - [Loot.BrightsilkSash]: ItemType.Cloth, - [Loot.SilkSash]: ItemType.Cloth, - [Loot.WoolSash]: ItemType.Cloth, - [Loot.LinenSash]: ItemType.Cloth, - [Loot.Sash]: ItemType.Cloth, - [Loot.DivineSlippers]: ItemType.Cloth, - [Loot.SilkSlippers]: ItemType.Cloth, - [Loot.WoolShoes]: ItemType.Cloth, - [Loot.LinenShoes]: ItemType.Cloth, - [Loot.Shoes]: ItemType.Cloth, - [Loot.DivineGloves]: ItemType.Cloth, - [Loot.SilkGloves]: ItemType.Cloth, - [Loot.WoolGloves]: ItemType.Cloth, - [Loot.LinenGloves]: ItemType.Cloth, - [Loot.Gloves]: ItemType.Cloth, - [Loot.Katana]: ItemType.Blade, - [Loot.Falchion]: ItemType.Blade, - [Loot.Scimitar]: ItemType.Blade, - [Loot.LongSword]: ItemType.Blade, - [Loot.ShortSword]: ItemType.Blade, - [Loot.DemonHusk]: ItemType.Hide, - [Loot.DragonskinArmor]: ItemType.Hide, - [Loot.StuddedLeatherArmor]: ItemType.Hide, - [Loot.HardLeatherArmor]: ItemType.Hide, - [Loot.LeatherArmor]: ItemType.Hide, - [Loot.DemonCrown]: ItemType.Hide, - [Loot.DragonsCrown]: ItemType.Hide, - [Loot.WarCap]: ItemType.Hide, - [Loot.LeatherCap]: ItemType.Hide, - [Loot.Cap]: ItemType.Hide, - [Loot.DemonhideBelt]: ItemType.Hide, - [Loot.DragonskinBelt]: ItemType.Hide, - [Loot.StuddedLeatherBelt]: ItemType.Hide, - [Loot.HardLeatherBelt]: ItemType.Hide, - [Loot.LeatherBelt]: ItemType.Hide, - [Loot.DemonhideBoots]: ItemType.Hide, - [Loot.DragonskinBoots]: ItemType.Hide, - [Loot.StuddedLeatherBoots]: ItemType.Hide, - [Loot.HardLeatherBoots]: ItemType.Hide, - [Loot.LeatherBoots]: ItemType.Hide, - [Loot.DemonsHands]: ItemType.Hide, - [Loot.DragonskinGloves]: ItemType.Hide, - [Loot.StuddedLeatherGloves]: ItemType.Hide, - [Loot.HardLeatherGloves]: ItemType.Hide, - [Loot.LeatherGloves]: ItemType.Hide, - [Loot.Warhammer]: ItemType.Bludgeon, - [Loot.Quarterstaff]: ItemType.Bludgeon, - [Loot.Maul]: ItemType.Bludgeon, - [Loot.Mace]: ItemType.Bludgeon, - [Loot.Club]: ItemType.Bludgeon, - [Loot.HolyChestplate]: ItemType.Metal, - [Loot.OrnateChestplate]: ItemType.Metal, - [Loot.PlateMail]: ItemType.Metal, - [Loot.ChainMail]: ItemType.Metal, - [Loot.RingMail]: ItemType.Metal, - [Loot.AncientHelm]: ItemType.Metal, - [Loot.OrnateHelm]: ItemType.Metal, - [Loot.GreatHelm]: ItemType.Metal, - [Loot.FullHelm]: ItemType.Metal, - [Loot.Helm]: ItemType.Metal, - [Loot.OrnateBelt]: ItemType.Metal, - [Loot.WarBelt]: ItemType.Metal, - [Loot.PlatedBelt]: ItemType.Metal, - [Loot.MeshBelt]: ItemType.Metal, - [Loot.HeavyBelt]: ItemType.Metal, - [Loot.HolyGreaves]: ItemType.Metal, - [Loot.OrnateGreaves]: ItemType.Metal, - [Loot.Greaves]: ItemType.Metal, - [Loot.ChainBoots]: ItemType.Metal, - [Loot.HeavyBoots]: ItemType.Metal, - [Loot.HolyGauntlets]: ItemType.Metal, - [Loot.OrnateGauntlets]: ItemType.Metal, - [Loot.Gauntlets]: ItemType.Metal, - [Loot.ChainGloves]: ItemType.Metal, - [Loot.HeavyGloves]: ItemType.Metal, + [Loot.Pendant]: ItemType.Necklace, + [Loot.Necklace]: ItemType.Necklace, + [Loot.Amulet]: ItemType.Necklace, + [Loot.SilverRing]: ItemType.Ring, + [Loot.BronzeRing]: ItemType.Ring, + [Loot.PlatinumRing]: ItemType.Ring, + [Loot.TitaniumRing]: ItemType.Ring, + [Loot.GoldRing]: ItemType.Ring, + [Loot.GhostWand]: ItemType.Magic, + [Loot.GraveWand]: ItemType.Magic, + [Loot.BoneWand]: ItemType.Magic, + [Loot.Wand]: ItemType.Magic, + [Loot.Grimoire]: ItemType.Magic, + [Loot.Chronicle]: ItemType.Magic, + [Loot.Tome]: ItemType.Magic, + [Loot.Book]: ItemType.Magic, + [Loot.DivineRobe]: ItemType.Cloth, + [Loot.SilkRobe]: ItemType.Cloth, + [Loot.LinenRobe]: ItemType.Cloth, + [Loot.Robe]: ItemType.Cloth, + [Loot.Shirt]: ItemType.Cloth, + [Loot.Crown]: ItemType.Cloth, + [Loot.DivineHood]: ItemType.Cloth, + [Loot.SilkHood]: ItemType.Cloth, + [Loot.LinenHood]: ItemType.Cloth, + [Loot.Hood]: ItemType.Cloth, + [Loot.BrightsilkSash]: ItemType.Cloth, + [Loot.SilkSash]: ItemType.Cloth, + [Loot.WoolSash]: ItemType.Cloth, + [Loot.LinenSash]: ItemType.Cloth, + [Loot.Sash]: ItemType.Cloth, + [Loot.DivineSlippers]: ItemType.Cloth, + [Loot.SilkSlippers]: ItemType.Cloth, + [Loot.WoolShoes]: ItemType.Cloth, + [Loot.LinenShoes]: ItemType.Cloth, + [Loot.Shoes]: ItemType.Cloth, + [Loot.DivineGloves]: ItemType.Cloth, + [Loot.SilkGloves]: ItemType.Cloth, + [Loot.WoolGloves]: ItemType.Cloth, + [Loot.LinenGloves]: ItemType.Cloth, + [Loot.Gloves]: ItemType.Cloth, + [Loot.Katana]: ItemType.Blade, + [Loot.Falchion]: ItemType.Blade, + [Loot.Scimitar]: ItemType.Blade, + [Loot.LongSword]: ItemType.Blade, + [Loot.ShortSword]: ItemType.Blade, + [Loot.DemonHusk]: ItemType.Hide, + [Loot.DragonskinArmor]: ItemType.Hide, + [Loot.StuddedLeatherArmor]: ItemType.Hide, + [Loot.HardLeatherArmor]: ItemType.Hide, + [Loot.LeatherArmor]: ItemType.Hide, + [Loot.DemonCrown]: ItemType.Hide, + [Loot.DragonsCrown]: ItemType.Hide, + [Loot.WarCap]: ItemType.Hide, + [Loot.LeatherCap]: ItemType.Hide, + [Loot.Cap]: ItemType.Hide, + [Loot.DemonhideBelt]: ItemType.Hide, + [Loot.DragonskinBelt]: ItemType.Hide, + [Loot.StuddedLeatherBelt]: ItemType.Hide, + [Loot.HardLeatherBelt]: ItemType.Hide, + [Loot.LeatherBelt]: ItemType.Hide, + [Loot.DemonhideBoots]: ItemType.Hide, + [Loot.DragonskinBoots]: ItemType.Hide, + [Loot.StuddedLeatherBoots]: ItemType.Hide, + [Loot.HardLeatherBoots]: ItemType.Hide, + [Loot.LeatherBoots]: ItemType.Hide, + [Loot.DemonsHands]: ItemType.Hide, + [Loot.DragonskinGloves]: ItemType.Hide, + [Loot.StuddedLeatherGloves]: ItemType.Hide, + [Loot.HardLeatherGloves]: ItemType.Hide, + [Loot.LeatherGloves]: ItemType.Hide, + [Loot.Warhammer]: ItemType.Bludgeon, + [Loot.Quarterstaff]: ItemType.Bludgeon, + [Loot.Maul]: ItemType.Bludgeon, + [Loot.Mace]: ItemType.Bludgeon, + [Loot.Club]: ItemType.Bludgeon, + [Loot.HolyChestplate]: ItemType.Metal, + [Loot.OrnateChestplate]: ItemType.Metal, + [Loot.PlateMail]: ItemType.Metal, + [Loot.ChainMail]: ItemType.Metal, + [Loot.RingMail]: ItemType.Metal, + [Loot.AncientHelm]: ItemType.Metal, + [Loot.OrnateHelm]: ItemType.Metal, + [Loot.GreatHelm]: ItemType.Metal, + [Loot.FullHelm]: ItemType.Metal, + [Loot.Helm]: ItemType.Metal, + [Loot.OrnateBelt]: ItemType.Metal, + [Loot.WarBelt]: ItemType.Metal, + [Loot.PlatedBelt]: ItemType.Metal, + [Loot.MeshBelt]: ItemType.Metal, + [Loot.HeavyBelt]: ItemType.Metal, + [Loot.HolyGreaves]: ItemType.Metal, + [Loot.OrnateGreaves]: ItemType.Metal, + [Loot.Greaves]: ItemType.Metal, + [Loot.ChainBoots]: ItemType.Metal, + [Loot.HeavyBoots]: ItemType.Metal, + [Loot.HolyGauntlets]: ItemType.Metal, + [Loot.OrnateGauntlets]: ItemType.Metal, + [Loot.Gauntlets]: ItemType.Metal, + [Loot.ChainGloves]: ItemType.Metal, + [Loot.HeavyGloves]: ItemType.Metal, }; export const ITEM_TIERS: Record = { - [Loot.Pendant]: 1, - [Loot.Necklace]: 1, - [Loot.Amulet]: 1, - [Loot.SilverRing]: 2, - [Loot.BronzeRing]: 3, - [Loot.PlatinumRing]: 1, - [Loot.TitaniumRing]: 1, - [Loot.GoldRing]: 1, - [Loot.GhostWand]: 1, - [Loot.GraveWand]: 2, - [Loot.BoneWand]: 3, - [Loot.Wand]: 5, - [Loot.Grimoire]: 1, - [Loot.Chronicle]: 2, - [Loot.Tome]: 3, - [Loot.Book]: 5, - [Loot.DivineRobe]: 1, - [Loot.SilkRobe]: 2, - [Loot.LinenRobe]: 3, - [Loot.Robe]: 4, - [Loot.Shirt]: 5, - [Loot.Crown]: 1, - [Loot.DivineHood]: 2, - [Loot.SilkHood]: 3, - [Loot.LinenHood]: 4, - [Loot.Hood]: 5, - [Loot.BrightsilkSash]: 1, - [Loot.SilkSash]: 2, - [Loot.WoolSash]: 3, - [Loot.LinenSash]: 4, - [Loot.Sash]: 5, - [Loot.DivineSlippers]: 1, - [Loot.SilkSlippers]: 2, - [Loot.WoolShoes]: 3, - [Loot.LinenShoes]: 4, - [Loot.Shoes]: 5, - [Loot.DivineGloves]: 1, - [Loot.SilkGloves]: 2, - [Loot.WoolGloves]: 3, - [Loot.LinenGloves]: 4, - [Loot.Gloves]: 5, - [Loot.Katana]: 1, - [Loot.Falchion]: 2, - [Loot.Scimitar]: 3, - [Loot.LongSword]: 4, - [Loot.ShortSword]: 5, - [Loot.DemonHusk]: 1, - [Loot.DragonskinArmor]: 2, - [Loot.StuddedLeatherArmor]: 3, - [Loot.HardLeatherArmor]: 4, - [Loot.LeatherArmor]: 5, - [Loot.DemonCrown]: 1, - [Loot.DragonsCrown]: 2, - [Loot.WarCap]: 3, - [Loot.LeatherCap]: 4, - [Loot.Cap]: 5, - [Loot.DemonhideBelt]: 1, - [Loot.DragonskinBelt]: 2, - [Loot.StuddedLeatherBelt]: 3, - [Loot.HardLeatherBelt]: 4, - [Loot.LeatherBelt]: 5, - [Loot.DemonhideBoots]: 1, - [Loot.DragonskinBoots]: 2, - [Loot.StuddedLeatherBoots]: 3, - [Loot.HardLeatherBoots]: 4, - [Loot.LeatherBoots]: 5, - [Loot.DemonsHands]: 1, - [Loot.DragonskinGloves]: 2, - [Loot.StuddedLeatherGloves]: 3, - [Loot.HardLeatherGloves]: 4, - [Loot.LeatherGloves]: 5, - [Loot.Warhammer]: 1, - [Loot.Quarterstaff]: 2, - [Loot.Maul]: 3, - [Loot.Mace]: 4, - [Loot.Club]: 5, - [Loot.HolyChestplate]: 1, - [Loot.OrnateChestplate]: 2, - [Loot.PlateMail]: 3, - [Loot.ChainMail]: 4, - [Loot.RingMail]: 5, - [Loot.AncientHelm]: 1, - [Loot.OrnateHelm]: 2, - [Loot.GreatHelm]: 3, - [Loot.FullHelm]: 4, - [Loot.Helm]: 5, - [Loot.OrnateBelt]: 1, - [Loot.WarBelt]: 2, - [Loot.PlatedBelt]: 3, - [Loot.MeshBelt]: 4, - [Loot.HeavyBelt]: 5, - [Loot.HolyGreaves]: 1, - [Loot.OrnateGreaves]: 2, - [Loot.Greaves]: 3, - [Loot.ChainBoots]: 4, - [Loot.HeavyBoots]: 5, - [Loot.HolyGauntlets]: 1, - [Loot.OrnateGauntlets]: 2, - [Loot.Gauntlets]: 3, - [Loot.ChainGloves]: 4, - [Loot.HeavyGloves]: 5, + [Loot.Pendant]: 1, + [Loot.Necklace]: 1, + [Loot.Amulet]: 1, + [Loot.SilverRing]: 2, + [Loot.BronzeRing]: 3, + [Loot.PlatinumRing]: 1, + [Loot.TitaniumRing]: 1, + [Loot.GoldRing]: 1, + [Loot.GhostWand]: 1, + [Loot.GraveWand]: 2, + [Loot.BoneWand]: 3, + [Loot.Wand]: 5, + [Loot.Grimoire]: 1, + [Loot.Chronicle]: 2, + [Loot.Tome]: 3, + [Loot.Book]: 5, + [Loot.DivineRobe]: 1, + [Loot.SilkRobe]: 2, + [Loot.LinenRobe]: 3, + [Loot.Robe]: 4, + [Loot.Shirt]: 5, + [Loot.Crown]: 1, + [Loot.DivineHood]: 2, + [Loot.SilkHood]: 3, + [Loot.LinenHood]: 4, + [Loot.Hood]: 5, + [Loot.BrightsilkSash]: 1, + [Loot.SilkSash]: 2, + [Loot.WoolSash]: 3, + [Loot.LinenSash]: 4, + [Loot.Sash]: 5, + [Loot.DivineSlippers]: 1, + [Loot.SilkSlippers]: 2, + [Loot.WoolShoes]: 3, + [Loot.LinenShoes]: 4, + [Loot.Shoes]: 5, + [Loot.DivineGloves]: 1, + [Loot.SilkGloves]: 2, + [Loot.WoolGloves]: 3, + [Loot.LinenGloves]: 4, + [Loot.Gloves]: 5, + [Loot.Katana]: 1, + [Loot.Falchion]: 2, + [Loot.Scimitar]: 3, + [Loot.LongSword]: 4, + [Loot.ShortSword]: 5, + [Loot.DemonHusk]: 1, + [Loot.DragonskinArmor]: 2, + [Loot.StuddedLeatherArmor]: 3, + [Loot.HardLeatherArmor]: 4, + [Loot.LeatherArmor]: 5, + [Loot.DemonCrown]: 1, + [Loot.DragonsCrown]: 2, + [Loot.WarCap]: 3, + [Loot.LeatherCap]: 4, + [Loot.Cap]: 5, + [Loot.DemonhideBelt]: 1, + [Loot.DragonskinBelt]: 2, + [Loot.StuddedLeatherBelt]: 3, + [Loot.HardLeatherBelt]: 4, + [Loot.LeatherBelt]: 5, + [Loot.DemonhideBoots]: 1, + [Loot.DragonskinBoots]: 2, + [Loot.StuddedLeatherBoots]: 3, + [Loot.HardLeatherBoots]: 4, + [Loot.LeatherBoots]: 5, + [Loot.DemonsHands]: 1, + [Loot.DragonskinGloves]: 2, + [Loot.StuddedLeatherGloves]: 3, + [Loot.HardLeatherGloves]: 4, + [Loot.LeatherGloves]: 5, + [Loot.Warhammer]: 1, + [Loot.Quarterstaff]: 2, + [Loot.Maul]: 3, + [Loot.Mace]: 4, + [Loot.Club]: 5, + [Loot.HolyChestplate]: 1, + [Loot.OrnateChestplate]: 2, + [Loot.PlateMail]: 3, + [Loot.ChainMail]: 4, + [Loot.RingMail]: 5, + [Loot.AncientHelm]: 1, + [Loot.OrnateHelm]: 2, + [Loot.GreatHelm]: 3, + [Loot.FullHelm]: 4, + [Loot.Helm]: 5, + [Loot.OrnateBelt]: 1, + [Loot.WarBelt]: 2, + [Loot.PlatedBelt]: 3, + [Loot.MeshBelt]: 4, + [Loot.HeavyBelt]: 5, + [Loot.HolyGreaves]: 1, + [Loot.OrnateGreaves]: 2, + [Loot.Greaves]: 3, + [Loot.ChainBoots]: 4, + [Loot.HeavyBoots]: 5, + [Loot.HolyGauntlets]: 1, + [Loot.OrnateGauntlets]: 2, + [Loot.Gauntlets]: 3, + [Loot.ChainGloves]: 4, + [Loot.HeavyGloves]: 5, }; export const ITEM_SLOTS: Record = { - [Loot.Pendant]: ItemSlot.Neck, - [Loot.Necklace]: ItemSlot.Neck, - [Loot.Amulet]: ItemSlot.Neck, - [Loot.SilverRing]: ItemSlot.Ring, - [Loot.BronzeRing]: ItemSlot.Ring, - [Loot.PlatinumRing]: ItemSlot.Ring, - [Loot.TitaniumRing]: ItemSlot.Ring, - [Loot.GoldRing]: ItemSlot.Ring, - [Loot.GhostWand]: ItemSlot.Weapon, - [Loot.GraveWand]: ItemSlot.Weapon, - [Loot.BoneWand]: ItemSlot.Weapon, - [Loot.Wand]: ItemSlot.Weapon, - [Loot.Grimoire]: ItemSlot.Weapon, - [Loot.Chronicle]: ItemSlot.Weapon, - [Loot.Tome]: ItemSlot.Weapon, - [Loot.Book]: ItemSlot.Weapon, - [Loot.DivineRobe]: ItemSlot.Chest, - [Loot.SilkRobe]: ItemSlot.Chest, - [Loot.LinenRobe]: ItemSlot.Chest, - [Loot.Robe]: ItemSlot.Chest, - [Loot.Shirt]: ItemSlot.Chest, - [Loot.Crown]: ItemSlot.Head, - [Loot.DivineHood]: ItemSlot.Head, - [Loot.SilkHood]: ItemSlot.Head, - [Loot.LinenHood]: ItemSlot.Head, - [Loot.Hood]: ItemSlot.Head, - [Loot.BrightsilkSash]: ItemSlot.Waist, - [Loot.SilkSash]: ItemSlot.Waist, - [Loot.WoolSash]: ItemSlot.Waist, - [Loot.LinenSash]: ItemSlot.Waist, - [Loot.Sash]: ItemSlot.Waist, - [Loot.DivineSlippers]: ItemSlot.Foot, - [Loot.SilkSlippers]: ItemSlot.Foot, - [Loot.WoolShoes]: ItemSlot.Foot, - [Loot.LinenShoes]: ItemSlot.Foot, - [Loot.Shoes]: ItemSlot.Foot, - [Loot.DivineGloves]: ItemSlot.Hand, - [Loot.SilkGloves]: ItemSlot.Hand, - [Loot.WoolGloves]: ItemSlot.Hand, - [Loot.LinenGloves]: ItemSlot.Hand, - [Loot.Gloves]: ItemSlot.Hand, - [Loot.Katana]: ItemSlot.Weapon, - [Loot.Falchion]: ItemSlot.Weapon, - [Loot.Scimitar]: ItemSlot.Weapon, - [Loot.LongSword]: ItemSlot.Weapon, - [Loot.ShortSword]: ItemSlot.Weapon, - [Loot.DemonHusk]: ItemSlot.Chest, - [Loot.DragonskinArmor]: ItemSlot.Chest, - [Loot.StuddedLeatherArmor]: ItemSlot.Chest, - [Loot.HardLeatherArmor]: ItemSlot.Chest, - [Loot.LeatherArmor]: ItemSlot.Chest, - [Loot.DemonCrown]: ItemSlot.Head, - [Loot.DragonsCrown]: ItemSlot.Head, - [Loot.WarCap]: ItemSlot.Head, - [Loot.LeatherCap]: ItemSlot.Head, - [Loot.Cap]: ItemSlot.Head, - [Loot.DemonhideBelt]: ItemSlot.Waist, - [Loot.DragonskinBelt]: ItemSlot.Waist, - [Loot.StuddedLeatherBelt]: ItemSlot.Waist, - [Loot.HardLeatherBelt]: ItemSlot.Waist, - [Loot.LeatherBelt]: ItemSlot.Waist, - [Loot.DemonhideBoots]: ItemSlot.Foot, - [Loot.DragonskinBoots]: ItemSlot.Foot, - [Loot.StuddedLeatherBoots]: ItemSlot.Foot, - [Loot.HardLeatherBoots]: ItemSlot.Foot, - [Loot.LeatherBoots]: ItemSlot.Foot, - [Loot.DemonsHands]: ItemSlot.Hand, - [Loot.DragonskinGloves]: ItemSlot.Hand, - [Loot.StuddedLeatherGloves]: ItemSlot.Hand, - [Loot.HardLeatherGloves]: ItemSlot.Hand, - [Loot.LeatherGloves]: ItemSlot.Hand, - [Loot.Warhammer]: ItemSlot.Weapon, - [Loot.Quarterstaff]: ItemSlot.Weapon, - [Loot.Maul]: ItemSlot.Weapon, - [Loot.Mace]: ItemSlot.Weapon, - [Loot.Club]: ItemSlot.Weapon, - [Loot.HolyChestplate]: ItemSlot.Chest, - [Loot.OrnateChestplate]: ItemSlot.Chest, - [Loot.PlateMail]: ItemSlot.Chest, - [Loot.ChainMail]: ItemSlot.Chest, - [Loot.RingMail]: ItemSlot.Chest, - [Loot.AncientHelm]: ItemSlot.Head, - [Loot.OrnateHelm]: ItemSlot.Head, - [Loot.GreatHelm]: ItemSlot.Head, - [Loot.FullHelm]: ItemSlot.Head, - [Loot.Helm]: ItemSlot.Head, - [Loot.OrnateBelt]: ItemSlot.Waist, - [Loot.WarBelt]: ItemSlot.Waist, - [Loot.PlatedBelt]: ItemSlot.Waist, - [Loot.MeshBelt]: ItemSlot.Waist, - [Loot.HeavyBelt]: ItemSlot.Waist, - [Loot.HolyGreaves]: ItemSlot.Foot, - [Loot.OrnateGreaves]: ItemSlot.Foot, - [Loot.Greaves]: ItemSlot.Foot, - [Loot.ChainBoots]: ItemSlot.Foot, - [Loot.HeavyBoots]: ItemSlot.Foot, - [Loot.HolyGauntlets]: ItemSlot.Hand, - [Loot.OrnateGauntlets]: ItemSlot.Hand, - [Loot.Gauntlets]: ItemSlot.Hand, - [Loot.ChainGloves]: ItemSlot.Hand, - [Loot.HeavyGloves]: ItemSlot.Hand, + [Loot.Pendant]: ItemSlot.Neck, + [Loot.Necklace]: ItemSlot.Neck, + [Loot.Amulet]: ItemSlot.Neck, + [Loot.SilverRing]: ItemSlot.Ring, + [Loot.BronzeRing]: ItemSlot.Ring, + [Loot.PlatinumRing]: ItemSlot.Ring, + [Loot.TitaniumRing]: ItemSlot.Ring, + [Loot.GoldRing]: ItemSlot.Ring, + [Loot.GhostWand]: ItemSlot.Weapon, + [Loot.GraveWand]: ItemSlot.Weapon, + [Loot.BoneWand]: ItemSlot.Weapon, + [Loot.Wand]: ItemSlot.Weapon, + [Loot.Grimoire]: ItemSlot.Weapon, + [Loot.Chronicle]: ItemSlot.Weapon, + [Loot.Tome]: ItemSlot.Weapon, + [Loot.Book]: ItemSlot.Weapon, + [Loot.DivineRobe]: ItemSlot.Chest, + [Loot.SilkRobe]: ItemSlot.Chest, + [Loot.LinenRobe]: ItemSlot.Chest, + [Loot.Robe]: ItemSlot.Chest, + [Loot.Shirt]: ItemSlot.Chest, + [Loot.Crown]: ItemSlot.Head, + [Loot.DivineHood]: ItemSlot.Head, + [Loot.SilkHood]: ItemSlot.Head, + [Loot.LinenHood]: ItemSlot.Head, + [Loot.Hood]: ItemSlot.Head, + [Loot.BrightsilkSash]: ItemSlot.Waist, + [Loot.SilkSash]: ItemSlot.Waist, + [Loot.WoolSash]: ItemSlot.Waist, + [Loot.LinenSash]: ItemSlot.Waist, + [Loot.Sash]: ItemSlot.Waist, + [Loot.DivineSlippers]: ItemSlot.Foot, + [Loot.SilkSlippers]: ItemSlot.Foot, + [Loot.WoolShoes]: ItemSlot.Foot, + [Loot.LinenShoes]: ItemSlot.Foot, + [Loot.Shoes]: ItemSlot.Foot, + [Loot.DivineGloves]: ItemSlot.Hand, + [Loot.SilkGloves]: ItemSlot.Hand, + [Loot.WoolGloves]: ItemSlot.Hand, + [Loot.LinenGloves]: ItemSlot.Hand, + [Loot.Gloves]: ItemSlot.Hand, + [Loot.Katana]: ItemSlot.Weapon, + [Loot.Falchion]: ItemSlot.Weapon, + [Loot.Scimitar]: ItemSlot.Weapon, + [Loot.LongSword]: ItemSlot.Weapon, + [Loot.ShortSword]: ItemSlot.Weapon, + [Loot.DemonHusk]: ItemSlot.Chest, + [Loot.DragonskinArmor]: ItemSlot.Chest, + [Loot.StuddedLeatherArmor]: ItemSlot.Chest, + [Loot.HardLeatherArmor]: ItemSlot.Chest, + [Loot.LeatherArmor]: ItemSlot.Chest, + [Loot.DemonCrown]: ItemSlot.Head, + [Loot.DragonsCrown]: ItemSlot.Head, + [Loot.WarCap]: ItemSlot.Head, + [Loot.LeatherCap]: ItemSlot.Head, + [Loot.Cap]: ItemSlot.Head, + [Loot.DemonhideBelt]: ItemSlot.Waist, + [Loot.DragonskinBelt]: ItemSlot.Waist, + [Loot.StuddedLeatherBelt]: ItemSlot.Waist, + [Loot.HardLeatherBelt]: ItemSlot.Waist, + [Loot.LeatherBelt]: ItemSlot.Waist, + [Loot.DemonhideBoots]: ItemSlot.Foot, + [Loot.DragonskinBoots]: ItemSlot.Foot, + [Loot.StuddedLeatherBoots]: ItemSlot.Foot, + [Loot.HardLeatherBoots]: ItemSlot.Foot, + [Loot.LeatherBoots]: ItemSlot.Foot, + [Loot.DemonsHands]: ItemSlot.Hand, + [Loot.DragonskinGloves]: ItemSlot.Hand, + [Loot.StuddedLeatherGloves]: ItemSlot.Hand, + [Loot.HardLeatherGloves]: ItemSlot.Hand, + [Loot.LeatherGloves]: ItemSlot.Hand, + [Loot.Warhammer]: ItemSlot.Weapon, + [Loot.Quarterstaff]: ItemSlot.Weapon, + [Loot.Maul]: ItemSlot.Weapon, + [Loot.Mace]: ItemSlot.Weapon, + [Loot.Club]: ItemSlot.Weapon, + [Loot.HolyChestplate]: ItemSlot.Chest, + [Loot.OrnateChestplate]: ItemSlot.Chest, + [Loot.PlateMail]: ItemSlot.Chest, + [Loot.ChainMail]: ItemSlot.Chest, + [Loot.RingMail]: ItemSlot.Chest, + [Loot.AncientHelm]: ItemSlot.Head, + [Loot.OrnateHelm]: ItemSlot.Head, + [Loot.GreatHelm]: ItemSlot.Head, + [Loot.FullHelm]: ItemSlot.Head, + [Loot.Helm]: ItemSlot.Head, + [Loot.OrnateBelt]: ItemSlot.Waist, + [Loot.WarBelt]: ItemSlot.Waist, + [Loot.PlatedBelt]: ItemSlot.Waist, + [Loot.MeshBelt]: ItemSlot.Waist, + [Loot.HeavyBelt]: ItemSlot.Waist, + [Loot.HolyGreaves]: ItemSlot.Foot, + [Loot.OrnateGreaves]: ItemSlot.Foot, + [Loot.Greaves]: ItemSlot.Foot, + [Loot.ChainBoots]: ItemSlot.Foot, + [Loot.HeavyBoots]: ItemSlot.Foot, + [Loot.HolyGauntlets]: ItemSlot.Hand, + [Loot.OrnateGauntlets]: ItemSlot.Hand, + [Loot.Gauntlets]: ItemSlot.Hand, + [Loot.ChainGloves]: ItemSlot.Hand, + [Loot.HeavyGloves]: ItemSlot.Hand, }; diff --git a/packages/core/src/objects/obstacles.ts b/packages/core/src/objects/obstacles.ts index 9021953..b612a9f 100644 --- a/packages/core/src/objects/obstacles.ts +++ b/packages/core/src/objects/obstacles.ts @@ -1,14 +1,14 @@ import { Obstacles } from "../type"; export class ObstacleManager { - constructor() {} + constructor() {} - getObstacleName(obstacle: Obstacles): string { - return Obstacles[obstacle].replace(/([A-Z])/g, " $1").trim(); - } + getObstacleName(obstacle: Obstacles): string { + return Obstacles[obstacle].replace(/([A-Z])/g, " $1").trim(); + } - getObstacleNumber(obstacleName: string): Obstacles | undefined { - const formattedName = obstacleName.replace(/\s+/g, ""); - return Obstacles[formattedName as keyof typeof Obstacles]; - } + getObstacleNumber(obstacleName: string): Obstacles | undefined { + const formattedName = obstacleName.replace(/\s+/g, ""); + return Obstacles[formattedName as keyof typeof Obstacles]; + } } diff --git a/packages/core/src/objects/prediction.ts b/packages/core/src/objects/prediction.ts index 7b589d5..db1a227 100644 --- a/packages/core/src/objects/prediction.ts +++ b/packages/core/src/objects/prediction.ts @@ -5,214 +5,217 @@ import { Survivor } from "./survivor"; // import { LootManager } from "./loot"; export class PredictionManager { - private beasts: BeastManager = new BeastManager(); - private survivor: Survivor = new Survivor(); - // private lootManager: LootManager = new LootManager(); - - constructor() {} - - getRandomness( - xp: number, - adventurerEntropy: bigint - ): { rnd1: bigint; rnd2: bigint } { - const params = [BigInt(xp), adventurerEntropy]; - const poseidon = hash.computePoseidonHashOnElements(params); - - return { - rnd1: BigInt(poseidon) % UINT_128_MAX, - rnd2: BigInt(poseidon) / UINT_128_MAX, - }; - } - - beastEncounters(xpList: number[], adventurerEntropy: bigint): any[] { - return xpList.map((xp) => { - const level = BigInt(Math.floor(Math.sqrt(xp))); - const { rnd2 } = this.getRandomness(xp, adventurerEntropy); - - return { - ...this.beastEncounter(adventurerEntropy, level, xp, rnd2), - adventurerLevel: Math.floor(Math.sqrt(xp)), - xp: xp, - }; - }); - } - - getBeastHealth(level: bigint, seed: bigint): bigint { - const baseHealth = BigInt(1) + (seed % (level * BigInt(20))); - const levelBonus = this.getLevelBonus(level); - const totalHealth = baseHealth + levelBonus; - - return totalHealth > 511 ? BigInt(511) : totalHealth; - } - - private getLevelBonus(level: bigint): bigint { - if (level >= 50) return BigInt(500); - if (level >= 40) return BigInt(400); - if (level >= 30) return BigInt(200); - if (level >= 20) return BigInt(100); - return BigInt(10); - } - - getObstacleLevel(level: bigint, entropy: bigint): bigint { - let obstacleLevel = BigInt(1) + (entropy % (level * BigInt(3))); - - if (level >= 50) { - obstacleLevel += BigInt(80); - } else if (level >= 40) { - obstacleLevel += BigInt(40); - } else if (level >= 30) { - obstacleLevel += BigInt(20); - } else if (level >= 20) { - obstacleLevel += BigInt(10); + private beasts: BeastManager = new BeastManager(); + private survivor: Survivor = new Survivor(); + // private lootManager: LootManager = new LootManager(); + + constructor() {} + + getRandomness( + xp: number, + adventurerEntropy: bigint + ): { rnd1: bigint; rnd2: bigint } { + const params = [BigInt(xp), adventurerEntropy]; + const poseidon = hash.computePoseidonHashOnElements(params); + + return { + rnd1: BigInt(poseidon) % UINT_128_MAX, + rnd2: BigInt(poseidon) / UINT_128_MAX, + }; } - return obstacleLevel; - } + beastEncounters(xpList: number[], adventurerEntropy: bigint): any[] { + return xpList.map((xp) => { + const level = BigInt(Math.floor(Math.sqrt(xp))); + const { rnd2 } = this.getRandomness(xp, adventurerEntropy); + + return { + ...this.beastEncounter(adventurerEntropy, level, xp, rnd2), + adventurerLevel: Math.floor(Math.sqrt(xp)), + xp: xp, + }; + }); + } - getAttackLocation(entropy: bigint): string { - const locations = ["Chest", "Head", "Waist", "Foot", "Hand"]; - const index = Number(entropy % BigInt(locations.length)); - return locations[index]; - } + getBeastHealth(level: bigint, seed: bigint): bigint { + const baseHealth = BigInt(1) + (seed % (level * BigInt(20))); + const levelBonus = this.getLevelBonus(level); + const totalHealth = baseHealth + levelBonus; - getXpReward(level: bigint, tier: bigint): bigint { - let xp = ((BigInt(6) - tier) * level) / BigInt(2); + return totalHealth > 511 ? BigInt(511) : totalHealth; + } - if (xp < 4) { - return BigInt(4); + private getLevelBonus(level: bigint): bigint { + if (level >= 50) return BigInt(500); + if (level >= 40) return BigInt(400); + if (level >= 30) return BigInt(200); + if (level >= 20) return BigInt(100); + return BigInt(10); } - return xp; - } + getObstacleLevel(level: bigint, entropy: bigint): bigint { + let obstacleLevel = BigInt(1) + (entropy % (level * BigInt(3))); - abilityBasedAvoidThreat(level: bigint, entropy: bigint): bigint { - return entropy % level; - } + if (level >= 50) { + obstacleLevel += BigInt(80); + } else if (level >= 40) { + obstacleLevel += BigInt(40); + } else if (level >= 30) { + obstacleLevel += BigInt(20); + } else if (level >= 20) { + obstacleLevel += BigInt(10); + } - criticalMultiplier(luck: number, entropy: bigint): number { - if (luck > Number(entropy % BigInt(100))) { - return Number(entropy % BigInt(5)) + 1; + return obstacleLevel; } - return 0; - } - - criticalHitBonus( - base_damage: number, - luck: number, - ring: Item | undefined, - entropy: bigint - ): number { - let total = 0; - - if (luck > Number(entropy % BigInt(100))) { - let damage_boost_base = Math.floor(base_damage / 5); - let damage_multiplier = Number(entropy % BigInt(5)) + 1; - total = damage_boost_base * damage_multiplier; - - if (ring?.item === "Titanium Ring" && total > 0) { - total += Math.floor( - (total * 3 * Math.floor(Math.sqrt(ring.xp!))) / 100 - ); - } + getAttackLocation(entropy: bigint): string { + const locations = ["Chest", "Head", "Waist", "Foot", "Hand"]; + const index = Number(entropy % BigInt(locations.length)); + return locations[index]; + } + + getXpReward(level: bigint, tier: bigint): bigint { + let xp = ((BigInt(6) - tier) * level) / BigInt(2); + + if (xp < 4) { + return BigInt(4); + } + + return xp; + } + + abilityBasedAvoidThreat(level: bigint, entropy: bigint): bigint { + return entropy % level; + } + + criticalMultiplier(luck: number, entropy: bigint): number { + if (luck > Number(entropy % BigInt(100))) { + return Number(entropy % BigInt(5)) + 1; + } + + return 0; } - return total; - } - - calculateEncounterDamage( - type: string | undefined, - tier: number, - level: number, - adventurerArmor: Item | undefined, - entropy: bigint, - minimumDmg: number - ) { - if (!type) return minimumDmg; - - let base_attack = level * (6 - tier!); - - let base_armor = 0; - let elemental_damage = 0; - - if (adventurerArmor) { - base_armor = - this.survivor.calculateLevel() * (6 - adventurerArmor?.tier!); - elemental_damage = this.beasts.elementalAdjustedDamage( - base_attack, - type, - adventurerArmor?.type! - ); - } else { - elemental_damage = base_attack * 1.5; + criticalHitBonus( + base_damage: number, + luck: number, + ring: Item | undefined, + entropy: bigint + ): number { + let total = 0; + + if (luck > Number(entropy % BigInt(100))) { + let damage_boost_base = Math.floor(base_damage / 5); + let damage_multiplier = Number(entropy % BigInt(5)) + 1; + total = damage_boost_base * damage_multiplier; + + if (ring?.item === "Titanium Ring" && total > 0) { + total += Math.floor( + (total * 3 * Math.floor(Math.sqrt(ring.xp!))) / 100 + ); + } + } + + return total; } - let crit_bonus = this.criticalHitBonus( - elemental_damage, - 10, - undefined, - entropy - ); - - let total_attack = elemental_damage + crit_bonus; - let total_damage = Math.floor(total_attack - base_armor); - - return Math.max(minimumDmg, total_damage); - } - - beastEncounter( - adventurerEntropy: bigint, - level: bigint, - xp: number, - rnd2: bigint, - items?: Item[] - ): BeastEncounter { - const seed = this.getRandomness(xp, adventurerEntropy).rnd1; - - const beast_id = (Number(seed) % this.beasts.maxBeastId()) + 1; - - const beast_health = this.getBeastHealth(level, seed); - - const beast_tier = this.beasts.getBeastTier(Number(beast_id)); - - const beast_type = this.beasts.getAttackType( - this.beasts.getBeastType(Number(beast_id)) - ); - - const beast_level = this.getObstacleLevel(level, seed); - - const ambush_location = this.getAttackLocation(rnd2); - const roll = this.abilityBasedAvoidThreat(level, seed); - const xp_reward = this.getXpReward(beast_level, BigInt(beast_tier.tier)); - // const specialName = this.lootManager.getSpecialName(seed); - const criticalMultiplier = this.criticalMultiplier(10, rnd2); - - const adventurerArmor = items?.find( - (item) => item.slot === ambush_location - ); - - const damage = this.calculateEncounterDamage( - beast_type, - Number(beast_tier), - Number(beast_level), - adventurerArmor, - rnd2, - 2 - ); - - return { - encounter: "Beast", - id: BigInt(beast_id), - type: beast_type, - tier: Number(beast_tier), - level: Number(beast_level), - health: Number(beast_health), - location: ambush_location, - dodgeRoll: Number(roll) + 1, - nextXp: xp + Number(xp_reward), - specialName: "", - criticalMultiplier, - damage, - }; - } + calculateEncounterDamage( + type: string | undefined, + tier: number, + level: number, + adventurerArmor: Item | undefined, + entropy: bigint, + minimumDmg: number + ) { + if (!type) return minimumDmg; + + let base_attack = level * (6 - tier!); + + let base_armor = 0; + let elemental_damage = 0; + + if (adventurerArmor) { + base_armor = + this.survivor.calculateLevel() * (6 - adventurerArmor?.tier!); + elemental_damage = this.beasts.elementalAdjustedDamage( + base_attack, + type, + adventurerArmor?.type! + ); + } else { + elemental_damage = base_attack * 1.5; + } + + let crit_bonus = this.criticalHitBonus( + elemental_damage, + 10, + undefined, + entropy + ); + + let total_attack = elemental_damage + crit_bonus; + let total_damage = Math.floor(total_attack - base_armor); + + return Math.max(minimumDmg, total_damage); + } + + beastEncounter( + adventurerEntropy: bigint, + level: bigint, + xp: number, + rnd2: bigint, + items?: Item[] + ): BeastEncounter { + const seed = this.getRandomness(xp, adventurerEntropy).rnd1; + + const beast_id = (Number(seed) % this.beasts.maxBeastId()) + 1; + + const beast_health = this.getBeastHealth(level, seed); + + const beast_tier = this.beasts.getBeastTier(Number(beast_id)); + + const beast_type = this.beasts.getAttackType( + this.beasts.getBeastType(Number(beast_id)) + ); + + const beast_level = this.getObstacleLevel(level, seed); + + const ambush_location = this.getAttackLocation(rnd2); + const roll = this.abilityBasedAvoidThreat(level, seed); + const xp_reward = this.getXpReward( + beast_level, + BigInt(beast_tier.tier) + ); + // const specialName = this.lootManager.getSpecialName(seed); + const criticalMultiplier = this.criticalMultiplier(10, rnd2); + + const adventurerArmor = items?.find( + (item) => item.slot === ambush_location + ); + + const damage = this.calculateEncounterDamage( + beast_type, + Number(beast_tier), + Number(beast_level), + adventurerArmor, + rnd2, + 2 + ); + + return { + encounter: "Beast", + id: BigInt(beast_id), + type: beast_type, + tier: Number(beast_tier), + level: Number(beast_level), + health: Number(beast_health), + location: ambush_location, + dodgeRoll: Number(roll) + 1, + nextXp: xp + Number(xp_reward), + specialName: "", + criticalMultiplier, + damage, + }; + } } diff --git a/packages/core/src/objects/survivor.test.ts b/packages/core/src/objects/survivor.test.ts index 6631f40..a4aec47 100644 --- a/packages/core/src/objects/survivor.test.ts +++ b/packages/core/src/objects/survivor.test.ts @@ -4,206 +4,208 @@ import { SELECTORS } from "../type"; import { beforeEach, describe, expect, it } from "vitest"; import { - mockStartGameEvent, - mockAdventurerUpgradedEvent, - mockDiscoveredHealthEvent, - mockDiscoveredGoldEvent, - mockDiscoveredXPEvent, - mockEquipmentChangedEvent, + mockStartGameEvent, + mockAdventurerUpgradedEvent, + mockDiscoveredHealthEvent, + mockDiscoveredGoldEvent, + mockDiscoveredXPEvent, + mockEquipmentChangedEvent, } from "../state/mock"; describe("Survivor", () => { - let survivor: Survivor; - - beforeEach(() => { - survivor = new Survivor(); - }); - - describe("updateFromEvent", () => { - it("should handle StartGame event", () => { - survivor.updateFromEvent({ - name: SELECTORS.StartGame, - event: mockStartGameEvent, - }); - - expect(survivor.id).toBe(1); - expect(survivor.name).toBe(mockStartGameEvent.adventurerMeta.name); - expect(survivor.owner).toBe(mockStartGameEvent.adventurerState.owner); - expect(survivor.health).toBe(100); - expect(survivor.maxHealth).toBe(100); - expect(survivor.xp).toBe(0); - expect(survivor.level).toBe(1); - expect(survivor.gold).toBe(0); - expect(survivor.stats).toEqual( - mockStartGameEvent.adventurerMeta.startingStats - ); - expect(survivor.startEntropy).toBe( - mockStartGameEvent.adventurerMeta.startEntropy - ); - expect(survivor.startingStats).toEqual( - mockStartGameEvent.adventurerMeta.startingStats - ); - expect(survivor.interfaceCamel).toBe( - mockStartGameEvent.adventurerMeta.interfaceCamel - ); - expect(survivor.revealBlock).toBe(mockStartGameEvent.revealBlock); + let survivor: Survivor; + + beforeEach(() => { + survivor = new Survivor(); }); - }); - it("should handle AdventurerUpgraded event", () => { - survivor.updateFromEvent({ - name: SELECTORS.AdventurerUpgraded, - event: mockAdventurerUpgradedEvent, + describe("updateFromEvent", () => { + it("should handle StartGame event", () => { + survivor.updateFromEvent({ + name: SELECTORS.StartGame, + event: mockStartGameEvent, + }); + + expect(survivor.id).toBe(1); + expect(survivor.name).toBe(mockStartGameEvent.adventurerMeta.name); + expect(survivor.owner).toBe( + mockStartGameEvent.adventurerState.owner + ); + expect(survivor.health).toBe(100); + expect(survivor.maxHealth).toBe(100); + expect(survivor.xp).toBe(0); + expect(survivor.level).toBe(1); + expect(survivor.gold).toBe(0); + expect(survivor.stats).toEqual( + mockStartGameEvent.adventurerMeta.startingStats + ); + expect(survivor.startEntropy).toBe( + mockStartGameEvent.adventurerMeta.startEntropy + ); + expect(survivor.startingStats).toEqual( + mockStartGameEvent.adventurerMeta.startingStats + ); + expect(survivor.interfaceCamel).toBe( + mockStartGameEvent.adventurerMeta.interfaceCamel + ); + expect(survivor.revealBlock).toBe(mockStartGameEvent.revealBlock); + }); }); - expect(survivor.id).toBe( - mockAdventurerUpgradedEvent.adventurerStateWithBag.adventurerState - .adventurerId - ); - expect(survivor.stats).toEqual( - mockAdventurerUpgradedEvent.adventurerStateWithBag.adventurerState - .adventurer.stats - ); - expect(survivor.bag).toEqual( - mockAdventurerUpgradedEvent.adventurerStateWithBag.bag - ); - }); - - it("should handle DiscoveredHealth event", () => { - survivor.updateFromEvent({ - name: SELECTORS.DiscoveredHealth, - event: mockDiscoveredHealthEvent, + it("should handle AdventurerUpgraded event", () => { + survivor.updateFromEvent({ + name: SELECTORS.AdventurerUpgraded, + event: mockAdventurerUpgradedEvent, + }); + + expect(survivor.id).toBe( + mockAdventurerUpgradedEvent.adventurerStateWithBag.adventurerState + .adventurerId + ); + expect(survivor.stats).toEqual( + mockAdventurerUpgradedEvent.adventurerStateWithBag.adventurerState + .adventurer.stats + ); + expect(survivor.bag).toEqual( + mockAdventurerUpgradedEvent.adventurerStateWithBag.bag + ); }); - expect(survivor.health).toBe( - mockDiscoveredHealthEvent.adventurerState.adventurer.health - ); - }); + it("should handle DiscoveredHealth event", () => { + survivor.updateFromEvent({ + name: SELECTORS.DiscoveredHealth, + event: mockDiscoveredHealthEvent, + }); - it("should handle DiscoveredGold event", () => { - survivor.updateFromEvent({ - name: SELECTORS.DiscoveredGold, - event: mockDiscoveredGoldEvent, + expect(survivor.health).toBe( + mockDiscoveredHealthEvent.adventurerState.adventurer.health + ); }); - expect(survivor.gold).toBe( - mockDiscoveredGoldEvent.adventurerState.adventurer.gold - ); - }); + it("should handle DiscoveredGold event", () => { + survivor.updateFromEvent({ + name: SELECTORS.DiscoveredGold, + event: mockDiscoveredGoldEvent, + }); - it("should handle DiscoveredXP event", () => { - survivor.updateFromEvent({ - name: SELECTORS.DiscoveredXP, - event: mockDiscoveredXPEvent, + expect(survivor.gold).toBe( + mockDiscoveredGoldEvent.adventurerState.adventurer.gold + ); }); - expect(survivor.xp).toBe( - mockDiscoveredXPEvent.adventurerState.adventurer.xp - ); - }); + it("should handle DiscoveredXP event", () => { + survivor.updateFromEvent({ + name: SELECTORS.DiscoveredXP, + event: mockDiscoveredXPEvent, + }); - it("should handle EquipmentChanged event", () => { - survivor.updateFromEvent({ - name: SELECTORS.EquipmentChanged, - event: mockEquipmentChangedEvent, + expect(survivor.xp).toBe( + mockDiscoveredXPEvent.adventurerState.adventurer.xp + ); }); - expect(survivor.items).toEqual({ - weapon: { slot: "weapon", xp: 0 }, - chest: { slot: "chest", xp: 0 }, - head: { slot: "head", xp: 0 }, - waist: { slot: "waist", xp: 0 }, - foot: { slot: "foot", xp: 0 }, - hand: { slot: "hand", xp: 0 }, - neck: { slot: "neck", xp: 0 }, - ring: { slot: "ring", xp: 0 }, - }); - expect(survivor.bag).toEqual( - mockEquipmentChangedEvent.adventurerStateWithBag.bag - ); - }); - - it("should set optimistic state", () => { - const newState = { - health: 80, - gold: 100, - xp: 50, - }; - - survivor.setOptimisticState(newState); - - expect(survivor.health).toBe(80); - expect(survivor.gold).toBe(100); - expect(survivor.xp).toBe(50); - expect(survivor.level).toBe(Math.floor(Math.sqrt(50))); // Check if level is updated - }); - - it("should revert optimistic state", () => { - const initialHealth = survivor.health; - const initialGold = survivor.gold; - const initialXp = survivor.xp; - - survivor.setOptimisticState({ - health: 80, - gold: 100, - xp: 50, + it("should handle EquipmentChanged event", () => { + survivor.updateFromEvent({ + name: SELECTORS.EquipmentChanged, + event: mockEquipmentChangedEvent, + }); + + expect(survivor.items).toEqual({ + weapon: { slot: "weapon", xp: 0 }, + chest: { slot: "chest", xp: 0 }, + head: { slot: "head", xp: 0 }, + waist: { slot: "waist", xp: 0 }, + foot: { slot: "foot", xp: 0 }, + hand: { slot: "hand", xp: 0 }, + neck: { slot: "neck", xp: 0 }, + ring: { slot: "ring", xp: 0 }, + }); + expect(survivor.bag).toEqual( + mockEquipmentChangedEvent.adventurerStateWithBag.bag + ); }); - survivor.revertOptimisticState(); + it("should set optimistic state", () => { + const newState = { + health: 80, + gold: 100, + xp: 50, + }; - expect(survivor.health).toBe(initialHealth); - expect(survivor.gold).toBe(initialGold); - expect(survivor.xp).toBe(initialXp); - }); + survivor.setOptimisticState(newState); - it("should confirm optimistic state", () => { - const newState = { - health: 80, - gold: 100, - xp: 50, - }; + expect(survivor.health).toBe(80); + expect(survivor.gold).toBe(100); + expect(survivor.xp).toBe(50); + expect(survivor.level).toBe(Math.floor(Math.sqrt(50))); // Check if level is updated + }); - survivor.setOptimisticState(newState); - survivor.confirmOptimisticState(); + it("should revert optimistic state", () => { + const initialHealth = survivor.health; + const initialGold = survivor.gold; + const initialXp = survivor.xp; - // Set a new optimistic state - survivor.setOptimisticState({ - health: 70, - gold: 150, - xp: 75, - }); + survivor.setOptimisticState({ + health: 80, + gold: 100, + xp: 50, + }); - // Revert the new state - survivor.revertOptimisticState(); + survivor.revertOptimisticState(); - // Check if it reverts to the confirmed state, not the initial state - expect(survivor.health).toBe(80); - expect(survivor.gold).toBe(100); - expect(survivor.xp).toBe(50); - }); + expect(survivor.health).toBe(initialHealth); + expect(survivor.gold).toBe(initialGold); + expect(survivor.xp).toBe(initialXp); + }); - it("should update derived properties when setting optimistic state", () => { - const newState = { - stats: { - ...survivor.stats, - vitality: survivor.stats.vitality + 10, - }, - xp: 400, - }; + it("should confirm optimistic state", () => { + const newState = { + health: 80, + gold: 100, + xp: 50, + }; + + survivor.setOptimisticState(newState); + survivor.confirmOptimisticState(); + + // Set a new optimistic state + survivor.setOptimisticState({ + health: 70, + gold: 150, + xp: 75, + }); + + // Revert the new state + survivor.revertOptimisticState(); + + // Check if it reverts to the confirmed state, not the initial state + expect(survivor.health).toBe(80); + expect(survivor.gold).toBe(100); + expect(survivor.xp).toBe(50); + }); + + it("should update derived properties when setting optimistic state", () => { + const newState = { + stats: { + ...survivor.stats, + vitality: survivor.stats.vitality + 10, + }, + xp: 400, + }; - survivor.setOptimisticState(newState); + survivor.setOptimisticState(newState); - expect(survivor.maxHealth).toBe(survivor.stats.vitality * 10); - expect(survivor.level).toBe(Math.floor(Math.sqrt(400))); - }); + expect(survivor.maxHealth).toBe(survivor.stats.vitality * 10); + expect(survivor.level).toBe(Math.floor(Math.sqrt(400))); + }); - it("should not revert state if no optimistic update was made", () => { - const initialHealth = survivor.health; - const initialGold = survivor.gold; + it("should not revert state if no optimistic update was made", () => { + const initialHealth = survivor.health; + const initialGold = survivor.gold; - survivor.revertOptimisticState(); + survivor.revertOptimisticState(); - expect(survivor.health).toBe(initialHealth); - expect(survivor.gold).toBe(initialGold); - }); + expect(survivor.health).toBe(initialHealth); + expect(survivor.gold).toBe(initialGold); + }); }); diff --git a/packages/core/src/objects/survivor.ts b/packages/core/src/objects/survivor.ts index 9848e6f..73d6880 100644 --- a/packages/core/src/objects/survivor.ts +++ b/packages/core/src/objects/survivor.ts @@ -1,21 +1,21 @@ import { - ITEM_BASE_PRICE, - ITEM_CHARISMA_DISCOUNT, - ITEM_MINIMUM_PRICE, - POTION_BASE_PRICE, + ITEM_BASE_PRICE, + ITEM_CHARISMA_DISCOUNT, + ITEM_MINIMUM_PRICE, + POTION_BASE_PRICE, } from "../constants"; import { useSurvivorStore } from "../state"; import { - Stats, - Item, - ItemSlot, - StatType, - Bag, - Beast, - Battle, - Discovery, - SELECTORS, - // Loot, + Stats, + Item, + ItemSlot, + StatType, + Bag, + Beast, + Battle, + Discovery, + SELECTORS, + // Loot, } from "../type"; import * as EventTypes from "../type/events"; @@ -23,597 +23,611 @@ import { BeastManager } from "./beasts"; import { LootManager } from "./loot"; export class Survivor { - private beasts: BeastManager = new BeastManager(); - private previousState: Partial | null = null; - - id: number | null = null; - name: number | null = null; - owner: string | null = null; - statUpgradesAvailable: number = 0; - stats: Stats = { - strength: 0, - dexterity: 0, - vitality: 0, - intelligence: 0, - wisdom: 0, - charisma: 0, - luck: 0, - }; - health: number = 0; - maxHealth: number = 0; - xp: number = 0; - level: number = 1; - gold: number = 0; - items: Record = { - [ItemSlot.Weapon]: { slot: ItemSlot.Weapon, xp: 0 }, - [ItemSlot.Chest]: { slot: ItemSlot.Chest, xp: 0 }, - [ItemSlot.Head]: { slot: ItemSlot.Head, xp: 0 }, - [ItemSlot.Waist]: { slot: ItemSlot.Waist, xp: 0 }, - [ItemSlot.Foot]: { slot: ItemSlot.Foot, xp: 0 }, - [ItemSlot.Hand]: { slot: ItemSlot.Hand, xp: 0 }, - [ItemSlot.Neck]: { slot: ItemSlot.Neck, xp: 0 }, - [ItemSlot.Ring]: { slot: ItemSlot.Ring, xp: 0 }, - }; - bag: Bag | null = null; - - beast: Beast | null = null; - - startEntropy: string | null = null; - adventurerEntropy: string | null = null; - startingStats: Stats | null = null; - interfaceCamel: boolean = false; - - battle: Battle | null = null; - - discovery: Discovery | null = null; - - revealBlock: number | null = null; - - constructor() {} - - getItemsWithBoosts(): Record { - return { - [ItemSlot.Weapon]: new LootManager( - parseInt(this.items[ItemSlot.Weapon]?.item!) ?? null, - this.items[ItemSlot.Weapon]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Chest]: new LootManager( - parseInt(this.items[ItemSlot.Chest]?.item!) ?? null, - this.items[ItemSlot.Chest]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Head]: new LootManager( - parseInt(this.items[ItemSlot.Head]?.item!) ?? null, - this.items[ItemSlot.Head]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Waist]: new LootManager( - parseInt(this.items[ItemSlot.Waist]?.item!) ?? null, - this.items[ItemSlot.Waist]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Foot]: new LootManager( - parseInt(this.items[ItemSlot.Foot]?.item!) ?? null, - this.items[ItemSlot.Foot]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Hand]: new LootManager( - parseInt(this.items[ItemSlot.Hand]?.item!) ?? null, - this.items[ItemSlot.Hand]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Neck]: new LootManager( - parseInt(this.items[ItemSlot.Neck]?.item!) ?? null, - this.items[ItemSlot.Neck]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), - [ItemSlot.Ring]: new LootManager( - parseInt(this.items[ItemSlot.Ring]?.item!) ?? null, - this.items[ItemSlot.Ring]?.xp ?? 0, - BigInt(this.adventurerEntropy ?? "0") - ), + private beasts: BeastManager = new BeastManager(); + private previousState: Partial | null = null; + + id: number | null = null; + name: number | null = null; + owner: string | null = null; + statUpgradesAvailable: number = 0; + stats: Stats = { + strength: 0, + dexterity: 0, + vitality: 0, + intelligence: 0, + wisdom: 0, + charisma: 0, + luck: 0, }; - } - - setOptimisticState(newState: Partial): void { - // Store the current state - this.previousState = { - health: this.health, - maxHealth: this.maxHealth, - xp: this.xp, - level: this.level, - gold: this.gold, - stats: { ...this.stats }, - items: { ...this.items }, - bag: this.bag, - beast: this.beast, - battle: this.battle, + health: number = 0; + maxHealth: number = 0; + xp: number = 0; + level: number = 1; + gold: number = 0; + items: Record = { + [ItemSlot.Weapon]: { slot: ItemSlot.Weapon, xp: 0 }, + [ItemSlot.Chest]: { slot: ItemSlot.Chest, xp: 0 }, + [ItemSlot.Head]: { slot: ItemSlot.Head, xp: 0 }, + [ItemSlot.Waist]: { slot: ItemSlot.Waist, xp: 0 }, + [ItemSlot.Foot]: { slot: ItemSlot.Foot, xp: 0 }, + [ItemSlot.Hand]: { slot: ItemSlot.Hand, xp: 0 }, + [ItemSlot.Neck]: { slot: ItemSlot.Neck, xp: 0 }, + [ItemSlot.Ring]: { slot: ItemSlot.Ring, xp: 0 }, }; + bag: Bag | null = null; + + beast: Beast | null = null; + + startEntropy: string | null = null; + adventurerEntropy: string | null = null; + startingStats: Stats | null = null; + interfaceCamel: boolean = false; + + battle: Battle | null = null; + + discovery: Discovery | null = null; + + revealBlock: number | null = null; + + constructor() {} + + getItemsWithBoosts(): Record { + return { + [ItemSlot.Weapon]: new LootManager( + parseInt(this.items[ItemSlot.Weapon]?.item!) ?? null, + this.items[ItemSlot.Weapon]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Chest]: new LootManager( + parseInt(this.items[ItemSlot.Chest]?.item!) ?? null, + this.items[ItemSlot.Chest]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Head]: new LootManager( + parseInt(this.items[ItemSlot.Head]?.item!) ?? null, + this.items[ItemSlot.Head]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Waist]: new LootManager( + parseInt(this.items[ItemSlot.Waist]?.item!) ?? null, + this.items[ItemSlot.Waist]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Foot]: new LootManager( + parseInt(this.items[ItemSlot.Foot]?.item!) ?? null, + this.items[ItemSlot.Foot]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Hand]: new LootManager( + parseInt(this.items[ItemSlot.Hand]?.item!) ?? null, + this.items[ItemSlot.Hand]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Neck]: new LootManager( + parseInt(this.items[ItemSlot.Neck]?.item!) ?? null, + this.items[ItemSlot.Neck]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + [ItemSlot.Ring]: new LootManager( + parseInt(this.items[ItemSlot.Ring]?.item!) ?? null, + this.items[ItemSlot.Ring]?.xp ?? 0, + BigInt(this.adventurerEntropy ?? "0") + ), + }; + } - // Apply the new state - Object.assign(this, newState); - - // Update derived properties - this.maxHealth = this.calculateMaxHealth(); - this.level = this.calculateLevel(); - - // Update the store - this.updateStore(); - } - - revertOptimisticState(): void { - if (this.previousState) { - Object.assign(this, this.previousState); - this.previousState = null; - this.updateStore(); - } - } - - confirmOptimisticState(): void { - // Clear the previous state - this.previousState = null; - } - - updateFromEvents(events: { name: string; event: any }[]): void { - for (const event of events) { - this.updateFromEvent(event); - } - } - - getItemPrice(tier: number) { - const price = - (6 - tier) * ITEM_BASE_PRICE - - ITEM_CHARISMA_DISCOUNT * this.stats.charisma; - if (price < ITEM_MINIMUM_PRICE) { - return ITEM_MINIMUM_PRICE; - } else { - return price; - } - } - - getPotionPrice() { - return Math.max( - this.calculateLevel() - POTION_BASE_PRICE * this.stats.charisma, - 1 - ); - } - - checkAvailableSlots(): boolean { - const equippedItemsCount = Object.values(this.items).filter( - (item) => item.xp !== undefined - ).length; - const bagItemsCount = this.bag - ? Object.keys(this.bag).filter((key) => key !== "mutated").length - : 0; - const totalItemsCount = equippedItemsCount + bagItemsCount; - - const maxItemSlots = 20; // Assuming the maximum is still 20 - - return totalItemsCount < maxItemSlots; - } - - updateFromEvent(event: { name: string; event: any }): void { - switch (event.name) { - case SELECTORS.StartGame: - this.handleStartGameEvent(event.event as EventTypes.StartGameEvent); - break; - case SELECTORS.AdventurerUpgraded: - this.handleAdventurerUpgradedEvent( - event.event as EventTypes.AdventurerUpgradedEvent - ); - break; - case SELECTORS.DiscoveredHealth: - this.handleDiscoveredHealthEvent( - event.event as EventTypes.DiscoveredHealthEvent - ); - break; - case SELECTORS.DiscoveredGold: - this.handleDiscoveredGoldEvent( - event.event as EventTypes.DiscoveredGoldEvent - ); - break; - case SELECTORS.DiscoveredXP: - this.handleDiscoveredXPEvent( - event.event as EventTypes.DiscoveredXPEvent - ); - break; - case SELECTORS.DiscoveredLoot: - this.handleDiscoveredLootEvent( - event.event as EventTypes.DiscoveredLootEvent - ); - break; - case SELECTORS.EquipmentChanged: - this.handleEquipmentChangedEvent( - event.event as EventTypes.EquipmentChangedEvent - ); - break; - case SELECTORS.DodgedObstacle: - this.handleDodgedObstacleEvent( - event.event as EventTypes.DodgedObstacleEvent - ); - break; - case SELECTORS.HitByObstacle: - this.handleHitByObstacleEvent( - event.event as EventTypes.HitByObstacleEvent - ); - break; - case SELECTORS.DiscoveredBeast: - this.handleDiscoveredBeastEvent( - event.event as EventTypes.DiscoveredBeastEvent - ); - break; - case SELECTORS.AmbushedByBeast: - this.handleAmbushedByBeastEvent( - event.event as EventTypes.AmbushedByBeastEvent - ); - break; - case SELECTORS.AttackedBeast: - this.handleAttackedBeastEvent( - event.event as EventTypes.AttackedBeastEvent - ); - break; - case SELECTORS.AttackedByBeast: - this.handleAttackedByBeastEvent( - event.event as EventTypes.AttackedByBeastEvent - ); - break; - case SELECTORS.SlayedBeast: - this.handleSlayedBeastEvent(event.event as EventTypes.SlayedBeastEvent); - break; - case SELECTORS.FleeFailed: - this.handleFleeFailedEvent(event.event as EventTypes.FleeFailedEvent); - break; - case SELECTORS.FleeSucceeded: - this.handleFleeSucceededEvent( - event.event as EventTypes.FleeSucceededEvent - ); - break; - case SELECTORS.PurchasedItems: - this.handlePurchasedItemsEvent( - event.event as EventTypes.PurchasedItemsEvent - ); - break; - case SELECTORS.PurchasedPotions: - this.handlePurchasedPotionsEvent( - event.event as EventTypes.PurchasedPotionsEvent - ); - break; - case SELECTORS.EquippedItems: - this.handleEquippedItemsEvent( - event.event as EventTypes.EquippedItemsEvent - ); - break; - case SELECTORS.DroppedItems: - this.handleDroppedItemsEvent( - event.event as EventTypes.DroppedItemsEvent - ); - break; - case SELECTORS.GreatnessIncreased: - this.handleGreatnessIncreasedEvent( - event.event as EventTypes.GreatnessIncreasedEvent - ); - break; - case SELECTORS.ItemsLeveledUp: - this.handleItemsLeveledUpEvent( - event.event as EventTypes.ItemsLeveledUpEvent + setOptimisticState(newState: Partial): void { + // Store the current state + this.previousState = { + health: this.health, + maxHealth: this.maxHealth, + xp: this.xp, + level: this.level, + gold: this.gold, + stats: { ...this.stats }, + items: { ...this.items }, + bag: this.bag, + beast: this.beast, + battle: this.battle, + }; + + // Apply the new state + Object.assign(this, newState); + + // Update derived properties + this.maxHealth = this.calculateMaxHealth(); + this.level = this.calculateLevel(); + + // Update the store + this.updateStore(); + } + + revertOptimisticState(): void { + if (this.previousState) { + Object.assign(this, this.previousState); + this.previousState = null; + this.updateStore(); + } + } + + confirmOptimisticState(): void { + // Clear the previous state + this.previousState = null; + } + + updateFromEvents(events: { name: string; event: any }[]): void { + for (const event of events) { + this.updateFromEvent(event); + } + } + + getItemPrice(tier: number) { + const price = + (6 - tier) * ITEM_BASE_PRICE - + ITEM_CHARISMA_DISCOUNT * this.stats.charisma; + if (price < ITEM_MINIMUM_PRICE) { + return ITEM_MINIMUM_PRICE; + } else { + return price; + } + } + + getPotionPrice() { + return Math.max( + this.calculateLevel() - POTION_BASE_PRICE * this.stats.charisma, + 1 ); - break; - case SELECTORS.NewHighScore: - this.handleNewHighScoreEvent( - event.event as EventTypes.NewHighScoreEvent + } + + checkAvailableSlots(): boolean { + const equippedItemsCount = Object.values(this.items).filter( + (item) => item.xp !== undefined + ).length; + const bagItemsCount = this.bag + ? Object.keys(this.bag).filter((key) => key !== "mutated").length + : 0; + const totalItemsCount = equippedItemsCount + bagItemsCount; + + const maxItemSlots = 20; // Assuming the maximum is still 20 + + return totalItemsCount < maxItemSlots; + } + + updateFromEvent(event: { name: string; event: any }): void { + switch (event.name) { + case SELECTORS.StartGame: + this.handleStartGameEvent( + event.event as EventTypes.StartGameEvent + ); + break; + case SELECTORS.AdventurerUpgraded: + this.handleAdventurerUpgradedEvent( + event.event as EventTypes.AdventurerUpgradedEvent + ); + break; + case SELECTORS.DiscoveredHealth: + this.handleDiscoveredHealthEvent( + event.event as EventTypes.DiscoveredHealthEvent + ); + break; + case SELECTORS.DiscoveredGold: + this.handleDiscoveredGoldEvent( + event.event as EventTypes.DiscoveredGoldEvent + ); + break; + case SELECTORS.DiscoveredXP: + this.handleDiscoveredXPEvent( + event.event as EventTypes.DiscoveredXPEvent + ); + break; + case SELECTORS.DiscoveredLoot: + this.handleDiscoveredLootEvent( + event.event as EventTypes.DiscoveredLootEvent + ); + break; + case SELECTORS.EquipmentChanged: + this.handleEquipmentChangedEvent( + event.event as EventTypes.EquipmentChangedEvent + ); + break; + case SELECTORS.DodgedObstacle: + this.handleDodgedObstacleEvent( + event.event as EventTypes.DodgedObstacleEvent + ); + break; + case SELECTORS.HitByObstacle: + this.handleHitByObstacleEvent( + event.event as EventTypes.HitByObstacleEvent + ); + break; + case SELECTORS.DiscoveredBeast: + this.handleDiscoveredBeastEvent( + event.event as EventTypes.DiscoveredBeastEvent + ); + break; + case SELECTORS.AmbushedByBeast: + this.handleAmbushedByBeastEvent( + event.event as EventTypes.AmbushedByBeastEvent + ); + break; + case SELECTORS.AttackedBeast: + this.handleAttackedBeastEvent( + event.event as EventTypes.AttackedBeastEvent + ); + break; + case SELECTORS.AttackedByBeast: + this.handleAttackedByBeastEvent( + event.event as EventTypes.AttackedByBeastEvent + ); + break; + case SELECTORS.SlayedBeast: + this.handleSlayedBeastEvent( + event.event as EventTypes.SlayedBeastEvent + ); + break; + case SELECTORS.FleeFailed: + this.handleFleeFailedEvent( + event.event as EventTypes.FleeFailedEvent + ); + break; + case SELECTORS.FleeSucceeded: + this.handleFleeSucceededEvent( + event.event as EventTypes.FleeSucceededEvent + ); + break; + case SELECTORS.PurchasedItems: + this.handlePurchasedItemsEvent( + event.event as EventTypes.PurchasedItemsEvent + ); + break; + case SELECTORS.PurchasedPotions: + this.handlePurchasedPotionsEvent( + event.event as EventTypes.PurchasedPotionsEvent + ); + break; + case SELECTORS.EquippedItems: + this.handleEquippedItemsEvent( + event.event as EventTypes.EquippedItemsEvent + ); + break; + case SELECTORS.DroppedItems: + this.handleDroppedItemsEvent( + event.event as EventTypes.DroppedItemsEvent + ); + break; + case SELECTORS.GreatnessIncreased: + this.handleGreatnessIncreasedEvent( + event.event as EventTypes.GreatnessIncreasedEvent + ); + break; + case SELECTORS.ItemsLeveledUp: + this.handleItemsLeveledUpEvent( + event.event as EventTypes.ItemsLeveledUpEvent + ); + break; + case SELECTORS.NewHighScore: + this.handleNewHighScoreEvent( + event.event as EventTypes.NewHighScoreEvent + ); + break; + case SELECTORS.AdventurerDied: + this.handleAdventurerDiedEvent( + event.event as EventTypes.AdventurerDiedEvent + ); + break; + case SELECTORS.AdventurerLeveledUp: + this.handleAdventurerLeveledUpEvent( + event.event as EventTypes.AdventurerLeveledUpEvent + ); + break; + case SELECTORS.UpgradesAvailable: + this.handleUpgradesAvailableEvent( + event.event as EventTypes.UpgradesAvailableEvent + ); + break; + default: + console.warn(`Unhandled event type: ${event.name}`); + } + this.updateStore(); + } + + private updateStore(): void { + useSurvivorStore.getState().updateSurvivor(this); + } + + private handleStartGameEvent(event: EventTypes.StartGameEvent): void { + const { adventurerState, adventurerMeta, revealBlock } = event; + this.updateFromAdventurerState(adventurerState); + this.startEntropy = adventurerMeta.startEntropy; + this.startingStats = adventurerMeta.startingStats; + this.interfaceCamel = adventurerMeta.interfaceCamel; + this.name = adventurerMeta.name; + this.revealBlock = revealBlock; + } + + private handleAdventurerUpgradedEvent( + event: EventTypes.AdventurerUpgradedEvent + ): void { + const { adventurerStateWithBag } = event; + this.updateFromAdventurerState(adventurerStateWithBag.adventurerState); + this.bag = adventurerStateWithBag.bag; + } + + private handleDiscoveredHealthEvent( + event: EventTypes.DiscoveredHealthEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleDiscoveredGoldEvent( + event: EventTypes.DiscoveredGoldEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleDiscoveredXPEvent(event: EventTypes.DiscoveredXPEvent): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleDiscoveredLootEvent( + event: EventTypes.DiscoveredLootEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleEquipmentChangedEvent( + event: EventTypes.EquipmentChangedEvent + ): void { + this.updateFromAdventurerState( + event.adventurerStateWithBag.adventurerState ); - break; - case SELECTORS.AdventurerDied: - this.handleAdventurerDiedEvent( - event.event as EventTypes.AdventurerDiedEvent + this.bag = event.adventurerStateWithBag.bag; + } + + private handleDodgedObstacleEvent( + event: EventTypes.DodgedObstacleEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleHitByObstacleEvent( + event: EventTypes.HitByObstacleEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleDiscoveredBeastEvent( + event: EventTypes.DiscoveredBeastEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + + this.beast = this.createBeastObject(event); + this.battle = this.createBattleObject(event, "adventurer"); + } + + private handleAmbushedByBeastEvent( + event: EventTypes.AmbushedByBeastEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + this.takeDamage(event.damage); + + this.beast = this.createBeastObject(event); + this.battle = this.createBattleObject(event, "beast"); + } + + private handleAttackedBeastEvent( + event: EventTypes.AttackedBeastEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + + this.beast = this.createBeastObject(event); + this.battle = this.createBattleObject(event, "adventurer"); + } + + private handleAttackedByBeastEvent( + event: EventTypes.AttackedByBeastEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + + this.beast = this.createBeastObject(event); + this.battle = this.createBattleObject(event, "beast"); + } + + private handleSlayedBeastEvent(event: EventTypes.SlayedBeastEvent): void { + this.updateFromAdventurerState(event.adventurerState); + this.beast = null; + this.battle = null; + } + + private handleFleeFailedEvent(event: EventTypes.FleeFailedEvent): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleFleeSucceededEvent( + event: EventTypes.FleeSucceededEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + this.beast = null; + this.battle = null; + } + + private handlePurchasedItemsEvent( + event: EventTypes.PurchasedItemsEvent + ): void { + this.updateFromAdventurerState( + event.adventurerStateWithBag.adventurerState ); - break; - case SELECTORS.AdventurerLeveledUp: - this.handleAdventurerLeveledUpEvent( - event.event as EventTypes.AdventurerLeveledUpEvent + this.bag = event.adventurerStateWithBag.bag; + } + + private handlePurchasedPotionsEvent( + event: EventTypes.PurchasedPotionsEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleEquippedItemsEvent( + event: EventTypes.EquippedItemsEvent + ): void { + this.updateFromAdventurerState( + event.adventurerStateWithBag.adventurerState ); - break; - case SELECTORS.UpgradesAvailable: - this.handleUpgradesAvailableEvent( - event.event as EventTypes.UpgradesAvailableEvent + this.bag = event.adventurerStateWithBag.bag; + } + + private handleDroppedItemsEvent(event: EventTypes.DroppedItemsEvent): void { + this.updateFromAdventurerState( + event.adventurerStateWithBag.adventurerState ); - break; - default: - console.warn(`Unhandled event type: ${event.name}`); - } - this.updateStore(); - } - - private updateStore(): void { - useSurvivorStore.getState().updateSurvivor(this); - } - - private handleStartGameEvent(event: EventTypes.StartGameEvent): void { - const { adventurerState, adventurerMeta, revealBlock } = event; - this.updateFromAdventurerState(adventurerState); - this.startEntropy = adventurerMeta.startEntropy; - this.startingStats = adventurerMeta.startingStats; - this.interfaceCamel = adventurerMeta.interfaceCamel; - this.name = adventurerMeta.name; - this.revealBlock = revealBlock; - } - - private handleAdventurerUpgradedEvent( - event: EventTypes.AdventurerUpgradedEvent - ): void { - const { adventurerStateWithBag } = event; - this.updateFromAdventurerState(adventurerStateWithBag.adventurerState); - this.bag = adventurerStateWithBag.bag; - } - - private handleDiscoveredHealthEvent( - event: EventTypes.DiscoveredHealthEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleDiscoveredGoldEvent( - event: EventTypes.DiscoveredGoldEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleDiscoveredXPEvent(event: EventTypes.DiscoveredXPEvent): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleDiscoveredLootEvent( - event: EventTypes.DiscoveredLootEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleEquipmentChangedEvent( - event: EventTypes.EquipmentChangedEvent - ): void { - this.updateFromAdventurerState( - event.adventurerStateWithBag.adventurerState - ); - this.bag = event.adventurerStateWithBag.bag; - } - - private handleDodgedObstacleEvent( - event: EventTypes.DodgedObstacleEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleHitByObstacleEvent(event: EventTypes.HitByObstacleEvent): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleDiscoveredBeastEvent( - event: EventTypes.DiscoveredBeastEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - - this.beast = this.createBeastObject(event); - this.battle = this.createBattleObject(event, "adventurer"); - } - - private handleAmbushedByBeastEvent( - event: EventTypes.AmbushedByBeastEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - this.takeDamage(event.damage); - - this.beast = this.createBeastObject(event); - this.battle = this.createBattleObject(event, "beast"); - } - - private handleAttackedBeastEvent(event: EventTypes.AttackedBeastEvent): void { - this.updateFromAdventurerState(event.adventurerState); - - this.beast = this.createBeastObject(event); - this.battle = this.createBattleObject(event, "adventurer"); - } - - private handleAttackedByBeastEvent( - event: EventTypes.AttackedByBeastEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - - this.beast = this.createBeastObject(event); - this.battle = this.createBattleObject(event, "beast"); - } - - private handleSlayedBeastEvent(event: EventTypes.SlayedBeastEvent): void { - this.updateFromAdventurerState(event.adventurerState); - this.beast = null; - this.battle = null; - } - - private handleFleeFailedEvent(event: EventTypes.FleeFailedEvent): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleFleeSucceededEvent(event: EventTypes.FleeSucceededEvent): void { - this.updateFromAdventurerState(event.adventurerState); - this.beast = null; - this.battle = null; - } - - private handlePurchasedItemsEvent( - event: EventTypes.PurchasedItemsEvent - ): void { - this.updateFromAdventurerState( - event.adventurerStateWithBag.adventurerState - ); - this.bag = event.adventurerStateWithBag.bag; - } - - private handlePurchasedPotionsEvent( - event: EventTypes.PurchasedPotionsEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleEquippedItemsEvent(event: EventTypes.EquippedItemsEvent): void { - this.updateFromAdventurerState( - event.adventurerStateWithBag.adventurerState - ); - this.bag = event.adventurerStateWithBag.bag; - } - - private handleDroppedItemsEvent(event: EventTypes.DroppedItemsEvent): void { - this.updateFromAdventurerState( - event.adventurerStateWithBag.adventurerState - ); - this.bag = event.adventurerStateWithBag.bag; - } - - private handleGreatnessIncreasedEvent( - event: EventTypes.GreatnessIncreasedEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleItemsLeveledUpEvent( - event: EventTypes.ItemsLeveledUpEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleNewHighScoreEvent(event: EventTypes.NewHighScoreEvent): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleAdventurerDiedEvent( - event: EventTypes.AdventurerDiedEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private handleAdventurerLeveledUpEvent( - event: EventTypes.AdventurerLeveledUpEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - this.level = event.newLevel; - } - - private handleUpgradesAvailableEvent( - event: EventTypes.UpgradesAvailableEvent - ): void { - this.updateFromAdventurerState(event.adventurerState); - } - - private updateFromAdventurerState(state: EventTypes.AdventurerState): void { - this.id = state.adventurerId; - this.owner = state.owner; - this.health = state.adventurer.health; - this.xp = state.adventurer.xp; - this.gold = state.adventurer.gold; - this.stats = state.adventurer.stats; - this.items = this.convertEquipmentToItems(state.adventurer.equipment); - this.maxHealth = this.calculateMaxHealth(); - this.level = this.calculateLevel(); - this.adventurerEntropy = state.adventurerEntropy; - this.statUpgradesAvailable = state.adventurer.statUpgradesAvailable; - } - - private createBeastObject(event: any): Beast { - return { - beast: this.beasts.getBeastName(event.id), - createdTime: new Date().getTime().toString(), - seed: event.seed.toString(), - level: event.beastSpecs.level, - slainOnTime: null, - special1: event.beastSpecs.specials.special1, - special2: event.beastSpecs.specials.special2, - special3: event.beastSpecs.specials.special3, - adventurerId: this.id as number, - lastUpdatedTime: new Date().getTime().toString(), - health: event.adventurerState.adventurer.beastHealth, - timestamp: new Date().getTime().toString(), - }; - } - - private createBattleObject( - event: any, - attacker: "adventurer" | "beast" - ): Battle { - return { - attacker, - adventurerId: this.id as number, - beast: this.beasts.getBeastName(event.id), - beastHealth: event.adventurerState.adventurer.beastHealth, - beastLevel: event.beastSpecs.level, - blockTime: new Date().toISOString(), - criticalHit: event.criticalHit, - damageDealt: attacker === "adventurer" ? event.damage : 0, - damageLocation: event.location.toString(), - damageTaken: attacker === "beast" ? event.damage : 0, - discoveryTime: new Date().toISOString(), - fled: false, - goldEarned: 0, - seed: event.seed.toString(), - special1: event.beastSpecs.specials.special1, - special2: event.beastSpecs.specials.special2, - special3: event.beastSpecs.specials.special3, - timestamp: new Date().getTime().toString(), - txHash: "", - xpEarnedAdventurer: 0, - xpEarnedItems: 0, - }; - } - - private convertEquipmentToItems( - equipment: Record - ): Record { - const items: Record = {} as Record; - for (const [slot, equip] of Object.entries(equipment)) { - items[slot as ItemSlot] = { - slot: slot as ItemSlot, - xp: equip.xp, - }; - } - return items; - } - - calculateMaxHealth(): number { - return this.stats.vitality * 10; - } - - calculateLevel(): number { - return Math.max(Math.floor(Math.sqrt(this.xp)), 1); - } - - getStat(stat: StatType): number { - return this.stats[StatType[stat].toLowerCase() as keyof Stats]; - } - - updateStat(stat: StatType, value: number): void { - const statKey = StatType[stat].toLowerCase() as keyof Stats; - this.stats[statKey] = value; - if (stat === StatType.Vitality) { - this.maxHealth = this.calculateMaxHealth(); - } - } - - unequipItem(slot: ItemSlot): void { - this.items[slot] = { slot }; - } - - addXp(amount: number): void { - this.xp += amount; - this.level = this.calculateLevel(); - } - - addGold(amount: number): void { - this.gold += amount; - } - - takeDamage(amount: number): void { - this.health = Math.max(0, this.health - amount); - } - - heal(amount: number): void { - this.health = Math.min(this.maxHealth, this.health + amount); - } + this.bag = event.adventurerStateWithBag.bag; + } + + private handleGreatnessIncreasedEvent( + event: EventTypes.GreatnessIncreasedEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleItemsLeveledUpEvent( + event: EventTypes.ItemsLeveledUpEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleNewHighScoreEvent(event: EventTypes.NewHighScoreEvent): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleAdventurerDiedEvent( + event: EventTypes.AdventurerDiedEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private handleAdventurerLeveledUpEvent( + event: EventTypes.AdventurerLeveledUpEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + this.level = event.newLevel; + } + + private handleUpgradesAvailableEvent( + event: EventTypes.UpgradesAvailableEvent + ): void { + this.updateFromAdventurerState(event.adventurerState); + } + + private updateFromAdventurerState(state: EventTypes.AdventurerState): void { + this.id = state.adventurerId; + this.owner = state.owner; + this.health = state.adventurer.health; + this.xp = state.adventurer.xp; + this.gold = state.adventurer.gold; + this.stats = state.adventurer.stats; + this.items = this.convertEquipmentToItems(state.adventurer.equipment); + this.maxHealth = this.calculateMaxHealth(); + this.level = this.calculateLevel(); + this.adventurerEntropy = state.adventurerEntropy; + this.statUpgradesAvailable = state.adventurer.statUpgradesAvailable; + } + + private createBeastObject(event: any): Beast { + return { + beast: this.beasts.getBeastName(event.id), + createdTime: new Date().getTime().toString(), + seed: event.seed.toString(), + level: event.beastSpecs.level, + slainOnTime: null, + special1: event.beastSpecs.specials.special1, + special2: event.beastSpecs.specials.special2, + special3: event.beastSpecs.specials.special3, + adventurerId: this.id as number, + lastUpdatedTime: new Date().getTime().toString(), + health: event.adventurerState.adventurer.beastHealth, + timestamp: new Date().getTime().toString(), + }; + } + + private createBattleObject( + event: any, + attacker: "adventurer" | "beast" + ): Battle { + return { + attacker, + adventurerId: this.id as number, + beast: this.beasts.getBeastName(event.id), + beastHealth: event.adventurerState.adventurer.beastHealth, + beastLevel: event.beastSpecs.level, + blockTime: new Date().toISOString(), + criticalHit: event.criticalHit, + damageDealt: attacker === "adventurer" ? event.damage : 0, + damageLocation: event.location.toString(), + damageTaken: attacker === "beast" ? event.damage : 0, + discoveryTime: new Date().toISOString(), + fled: false, + goldEarned: 0, + seed: event.seed.toString(), + special1: event.beastSpecs.specials.special1, + special2: event.beastSpecs.specials.special2, + special3: event.beastSpecs.specials.special3, + timestamp: new Date().getTime().toString(), + txHash: "", + xpEarnedAdventurer: 0, + xpEarnedItems: 0, + }; + } + + private convertEquipmentToItems( + equipment: Record + ): Record { + const items: Record = {} as Record; + for (const [slot, equip] of Object.entries(equipment)) { + items[slot as ItemSlot] = { + slot: slot as ItemSlot, + xp: equip.xp, + }; + } + return items; + } + + calculateMaxHealth(): number { + return this.stats.vitality * 10; + } + + calculateLevel(): number { + return Math.max(Math.floor(Math.sqrt(this.xp)), 1); + } + + getStat(stat: StatType): number { + return this.stats[StatType[stat].toLowerCase() as keyof Stats]; + } + + updateStat(stat: StatType, value: number): void { + const statKey = StatType[stat].toLowerCase() as keyof Stats; + this.stats[statKey] = value; + if (stat === StatType.Vitality) { + this.maxHealth = this.calculateMaxHealth(); + } + } + + unequipItem(slot: ItemSlot): void { + this.items[slot] = { slot }; + } + + addXp(amount: number): void { + this.xp += amount; + this.level = this.calculateLevel(); + } + + addGold(amount: number): void { + this.gold += amount; + } + + takeDamage(amount: number): void { + this.health = Math.max(0, this.health - amount); + } + + heal(amount: number): void { + this.health = Math.min(this.maxHealth, this.health + amount); + } } diff --git a/packages/core/src/provider/execute.ts b/packages/core/src/provider/execute.ts index dc3af99..27a3639 100644 --- a/packages/core/src/provider/execute.ts +++ b/packages/core/src/provider/execute.ts @@ -10,227 +10,243 @@ // * 5. Format txs and pipe back into the store import { - Account, - InvokeTransactionReceiptResponse, - RpcProvider, + Account, + InvokeTransactionReceiptResponse, + RpcProvider, } from "starknet"; import { ItemPurchase, MulticallEntry, Stats } from "../type"; import { parseEvents } from "../state/format"; import { useSurvivorStore } from "../state"; export class ExecuteProvider { - private lootSurvivorAddress!: string; - - private defaultAccount?: Account; - - private provider: RpcProvider; - - constructor( - lootSurvivorAddress: string, - provider: RpcProvider, - defaultAccount?: Account - ) { - this.lootSurvivorAddress = lootSurvivorAddress; - - this.defaultAccount = defaultAccount; - - this.provider = provider; - } - - private getAccount(account?: Account): Account { - if (account) return account; - if (this.defaultAccount) return this.defaultAccount; - throw new Error("No account provided"); - } - - private async processAndUpdateState( - receipt: InvokeTransactionReceiptResponse - ) { - const events = parseEvents(receipt as InvokeTransactionReceiptResponse); - - useSurvivorStore.getState().survivor?.updateFromEvents(events); - } - - async newGame( - clientRewardAddress: string, - weapon: number, - name: string, - goldenTokenId: bigint, - vrfFeeLimit: bigint, - account?: Account - ) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "new_game", - calldata: [ - clientRewardAddress, - weapon, - name, - goldenTokenId, - vrfFeeLimit, - ], - }); - - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + private lootSurvivorAddress!: string; + + private defaultAccount?: Account; + + private provider: RpcProvider; + + constructor( + lootSurvivorAddress: string, + provider: RpcProvider, + defaultAccount?: Account + ) { + this.lootSurvivorAddress = lootSurvivorAddress; + + this.defaultAccount = defaultAccount; + + this.provider = provider; + } + + private getAccount(account?: Account): Account { + if (account) return account; + if (this.defaultAccount) return this.defaultAccount; + throw new Error("No account provided"); + } + + private async processAndUpdateState( + receipt: InvokeTransactionReceiptResponse + ) { + const events = parseEvents(receipt as InvokeTransactionReceiptResponse); + + useSurvivorStore.getState().survivor?.updateFromEvents(events); } - } - - async explore(adventurerId: string, tillBeast: boolean, account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "explore", - calldata: [adventurerId, tillBeast ? 1 : 0], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async newGame( + clientRewardAddress: string, + weapon: number, + name: string, + goldenTokenId: bigint, + vrfFeeLimit: bigint, + account?: Account + ) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "new_game", + calldata: [ + clientRewardAddress, + weapon, + name, + goldenTokenId, + vrfFeeLimit, + ], + } + ); + + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async attack(adventurerId: string, toTheDeath: boolean, account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "attack", - calldata: [adventurerId, toTheDeath ? 1 : 0], - }); - - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async explore(adventurerId: string, tillBeast: boolean, account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "explore", + calldata: [adventurerId, tillBeast ? 1 : 0], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async flee(adventurerId: string, toTheDeath: boolean, account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "flee", - calldata: [adventurerId, toTheDeath ? 1 : 0], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async attack(adventurerId: string, toTheDeath: boolean, account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "attack", + calldata: [adventurerId, toTheDeath ? 1 : 0], + } + ); + + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } + } + + async flee(adventurerId: string, toTheDeath: boolean, account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "flee", + calldata: [adventurerId, toTheDeath ? 1 : 0], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async equip(adventurerId: string, items: number[], account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "equip", - calldata: [adventurerId, ...items], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async equip(adventurerId: string, items: number[], account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "equip", + calldata: [adventurerId, ...items], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async drop(adventurerId: string, items: number[], account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "drop", - calldata: [adventurerId, ...items], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async drop(adventurerId: string, items: number[], account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "drop", + calldata: [adventurerId, ...items], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async upgrade( - adventurerId: string, - potions: number, - statUpgrades: Stats, - items: ItemPurchase[], - account?: Account - ) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "upgrade", - calldata: [ - adventurerId, - potions, - ...Object.values(statUpgrades), - ...items.flatMap((item) => item), - ], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async upgrade( + adventurerId: string, + potions: number, + statUpgrades: Stats, + items: ItemPurchase[], + account?: Account + ) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "upgrade", + calldata: [ + adventurerId, + potions, + ...Object.values(statUpgrades), + ...items.flatMap((item) => item), + ], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async updateCostToPlay(account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute({ - contractAddress: this.lootSurvivorAddress, - entrypoint: "update_cost_to_play", - calldata: [], - }); - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error(e); + + async updateCostToPlay(account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + { + contractAddress: this.lootSurvivorAddress, + entrypoint: "update_cost_to_play", + calldata: [], + } + ); + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error(e); + } } - } - - async multiCall(calls: MulticallEntry[], account?: Account) { - try { - const { transaction_hash } = await this.getAccount(account).execute( - calls.map((call) => ({ - contractAddress: this.lootSurvivorAddress, - entrypoint: call.entrypoint, - calldata: call.calldata, - })) - ); - - this.processAndUpdateState( - (await this.provider.waitForTransaction( - transaction_hash - )) as InvokeTransactionReceiptResponse - ); - } catch (e) { - console.error("Multicall error:", e); - throw e; + + async multiCall(calls: MulticallEntry[], account?: Account) { + try { + const { transaction_hash } = await this.getAccount(account).execute( + calls.map((call) => ({ + contractAddress: this.lootSurvivorAddress, + entrypoint: call.entrypoint, + calldata: call.calldata, + })) + ); + + this.processAndUpdateState( + (await this.provider.waitForTransaction( + transaction_hash + )) as InvokeTransactionReceiptResponse + ); + } catch (e) { + console.error("Multicall error:", e); + throw e; + } } - } } diff --git a/packages/core/src/provider/index.ts b/packages/core/src/provider/index.ts index 610357d..333331a 100644 --- a/packages/core/src/provider/index.ts +++ b/packages/core/src/provider/index.ts @@ -3,59 +3,59 @@ import { RpcProvider, Account } from "starknet"; import { ExecuteProvider } from "./execute"; export class LootSurvivor { - // modules that can be read - beasts!: BeastManager; - loot!: LootManager; - prediction!: PredictionManager; - - // modules that can be executed - executeProvider!: ExecuteProvider; - - // addresses - private lootSurvivorAddress!: string; - private beastsAddress!: string; - private goldenTokenAddress!: string; - - // accounts and provider - private provider!: RpcProvider; - private account!: Account | undefined; - - constructor( - nodeUrl: string, - lootSurvivorAddress: string, - beastsAddress: string, - goldenTokenAddress: string, - account?: Account | undefined - ) { - this.lootSurvivorAddress = lootSurvivorAddress; - this.beastsAddress = beastsAddress; - this.goldenTokenAddress = goldenTokenAddress; - - this.provider = new RpcProvider({ nodeUrl }); - this.account = account; - - this.beasts = new BeastManager(); - this.prediction = new PredictionManager(); - this.executeProvider = new ExecuteProvider( - this.lootSurvivorAddress, - this.provider, - this.account - ); - } - - getBeastsAddress(): string { - return this.beastsAddress; - } - - getLootSurvivorAddress(): string { - return this.lootSurvivorAddress; - } - - getGoldenTokenAddress(): string { - return this.goldenTokenAddress; - } - - getProvider(): RpcProvider { - return this.provider; - } + // modules that can be read + beasts!: BeastManager; + loot!: LootManager; + prediction!: PredictionManager; + + // modules that can be executed + executeProvider!: ExecuteProvider; + + // addresses + private lootSurvivorAddress!: string; + private beastsAddress!: string; + private goldenTokenAddress!: string; + + // accounts and provider + private provider!: RpcProvider; + private account!: Account | undefined; + + constructor( + nodeUrl: string, + lootSurvivorAddress: string, + beastsAddress: string, + goldenTokenAddress: string, + account?: Account | undefined + ) { + this.lootSurvivorAddress = lootSurvivorAddress; + this.beastsAddress = beastsAddress; + this.goldenTokenAddress = goldenTokenAddress; + + this.provider = new RpcProvider({ nodeUrl }); + this.account = account; + + this.beasts = new BeastManager(); + this.prediction = new PredictionManager(); + this.executeProvider = new ExecuteProvider( + this.lootSurvivorAddress, + this.provider, + this.account + ); + } + + getBeastsAddress(): string { + return this.beastsAddress; + } + + getLootSurvivorAddress(): string { + return this.lootSurvivorAddress; + } + + getGoldenTokenAddress(): string { + return this.goldenTokenAddress; + } + + getProvider(): RpcProvider { + return this.provider; + } } diff --git a/packages/core/src/query/graphql.ts b/packages/core/src/query/graphql.ts index 8402bf7..64951cb 100644 --- a/packages/core/src/query/graphql.ts +++ b/packages/core/src/query/graphql.ts @@ -170,375 +170,375 @@ const GOLDEN_TOKEN_FRAGMENT = ` `; const getAdventurer = gql` - ${ADVENTURERS_FRAGMENT} - query getAdventurer($owner: HexValue) { - adventurers(where: { owner: { eq: $owner } }) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query getAdventurer($owner: HexValue) { + adventurers(where: { owner: { eq: $owner } }) { + ...AdventurerFields + } } - } `; const getDiscoveries = gql` - ${DISCOVERIES_FRAGMENT} - query getDiscoveries($id: FeltValue) { - discoveries( - where: { adventurerId: { eq: $id } } - limit: 1000000 - orderBy: { timestamp: { desc: true } } - ) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query getDiscoveries($id: FeltValue) { + discoveries( + where: { adventurerId: { eq: $id } } + limit: 1000000 + orderBy: { timestamp: { desc: true } } + ) { + ...DiscoveryFields + } } - } `; const getLatestDiscoveries = gql` - ${DISCOVERIES_FRAGMENT} - query getLatestDiscoveries($id: FeltValue) { - discoveries( - where: { adventurerId: { eq: $id } } - limit: 10 - orderBy: { timestamp: { desc: true } } - ) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query getLatestDiscoveries($id: FeltValue) { + discoveries( + where: { adventurerId: { eq: $id } } + limit: 10 + orderBy: { timestamp: { desc: true } } + ) { + ...DiscoveryFields + } } - } `; const getLastDiscovery = gql` - ${DISCOVERIES_FRAGMENT} - query get_last_discovery($adventurerId: FeltValue) { - discoveries( - where: { adventurerId: { eq: $adventurerId } } - limit: 1 - orderBy: { timestamp: { desc: true } } - ) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query get_last_discovery($adventurerId: FeltValue) { + discoveries( + where: { adventurerId: { eq: $adventurerId } } + limit: 1 + orderBy: { timestamp: { desc: true } } + ) { + ...DiscoveryFields + } } - } `; const getLastBeastDiscovery = gql` - ${DISCOVERIES_FRAGMENT} - query get_last_beast_query($id: FeltValue) { - discoveries( - where: { adventurerId: { eq: $id }, entityLevel: { gt: 0 } } - limit: 1 - orderBy: { timestamp: { desc: true } } - ) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query get_last_beast_query($id: FeltValue) { + discoveries( + where: { adventurerId: { eq: $id }, entityLevel: { gt: 0 } } + limit: 1 + orderBy: { timestamp: { desc: true } } + ) { + ...DiscoveryFields + } } - } `; const getDiscoveryByTxHash = gql` - ${DISCOVERIES_FRAGMENT} - query get_discovery($txHash: HexValue) { - discoveries(where: { txHash: { eq: $txHash } }) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query get_discovery($txHash: HexValue) { + discoveries(where: { txHash: { eq: $txHash } }) { + ...DiscoveryFields + } } - } `; const getItems = gql` - ${ITEMS_FRAGMENT} - query get_items { - items { - ...ItemFields + ${ITEMS_FRAGMENT} + query get_items { + items { + ...ItemFields + } } - } `; const getAdventurersByOwner = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurers_by_owner($owner: HexValue) { - adventurers(where: { owner: { eq: $owner } }, limit: 10000000) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurers_by_owner($owner: HexValue) { + adventurers(where: { owner: { eq: $owner } }, limit: 10000000) { + ...AdventurerFields + } } - } `; const getAdventurerById = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_id($id: FeltValue) { - adventurers(where: { id: { eq: $id } }) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_id($id: FeltValue) { + adventurers(where: { id: { eq: $id } }) { + ...AdventurerFields + } } - } `; const getAdventurersInList = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_id($ids: [FeltValue!]) { - adventurers(where: { id: { In: $ids } }, limit: 10000000) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_id($ids: [FeltValue!]) { + adventurers(where: { id: { In: $ids } }, limit: 10000000) { + ...AdventurerFields + } } - } `; const getAdventurersInListByXp = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_id_order_xp($ids: [FeltValue!]) { - adventurers( - where: { id: { In: $ids } } - limit: 10000000 - orderBy: { xp: { desc: true } } - ) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_id_order_xp($ids: [FeltValue!]) { + adventurers( + where: { id: { In: $ids } } + limit: 10000000 + orderBy: { xp: { desc: true } } + ) { + ...AdventurerFields + } } - } `; const getAdventurerByGold = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_gold { - adventurers(orderBy: { gold: { desc: true } }, limit: 10000000) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_gold { + adventurers(orderBy: { gold: { desc: true } }, limit: 10000000) { + ...AdventurerFields + } } - } `; const getAdventurerByXP = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_xp { - adventurers(orderBy: { xp: { desc: true } }, limit: 10000000) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_xp { + adventurers(orderBy: { xp: { desc: true } }, limit: 10000000) { + ...AdventurerFields + } } - } `; const getAdventurersByXPPaginated = gql` - ${ADVENTURERS_FRAGMENT} - query get_adventurer_by_xp_paginated($skip: Int) { - adventurers(limit: 10, skip: $skip, orderBy: { xp: { desc: true } }) { - ...AdventurerFields + ${ADVENTURERS_FRAGMENT} + query get_adventurer_by_xp_paginated($skip: Int) { + adventurers(limit: 10, skip: $skip, orderBy: { xp: { desc: true } }) { + ...AdventurerFields + } } - } `; const getBeast = gql` - ${BEASTS_FRAGMENT} - query get_beast_by_id( - $beast: BeastValue - $adventurerId: FeltValue - $seed: HexValue - ) { - beasts( - where: { - beast: { eq: $beast } - adventurerId: { eq: $adventurerId } - seed: { eq: $seed } - } + ${BEASTS_FRAGMENT} + query get_beast_by_id( + $beast: BeastValue + $adventurerId: FeltValue + $seed: HexValue ) { - ...BeastFields + beasts( + where: { + beast: { eq: $beast } + adventurerId: { eq: $adventurerId } + seed: { eq: $seed } + } + ) { + ...BeastFields + } } - } `; const getKilledBeasts = gql` - ${BEASTS_FRAGMENT} - query get_killed_beasts { - beasts(where: { health: { eq: 0 } }, limit: 10000000) { - ...BeastFields + ${BEASTS_FRAGMENT} + query get_killed_beasts { + beasts(where: { health: { eq: 0 } }, limit: 10000000) { + ...BeastFields + } } - } `; const getBeastsByAdventurer = gql` - ${DISCOVERIES_FRAGMENT} - query get_beast_by_id($id: FeltValue) { - discoveries(where: { adventurerId: { eq: $id } }) { - ...DiscoveryFields + ${DISCOVERIES_FRAGMENT} + query get_beast_by_id($id: FeltValue) { + discoveries(where: { adventurerId: { eq: $id } }) { + ...DiscoveryFields + } } - } `; const getLatestBattlesByAdventurer = gql` - ${BATTLES_FRAGMENT} - query get_latest_battles($adventurerId: FeltValue) { - battles( - limit: 10 - orderBy: { timestamp: { desc: true } } - where: { adventurerId: { eq: $adventurerId } } - ) { - ...BattleFields + ${BATTLES_FRAGMENT} + query get_latest_battles($adventurerId: FeltValue) { + battles( + limit: 10 + orderBy: { timestamp: { desc: true } } + where: { adventurerId: { eq: $adventurerId } } + ) { + ...BattleFields + } } - } `; const getBattlesByAdventurer = gql` - ${BATTLES_FRAGMENT} - query get_battles($adventurerId: FeltValue) { - battles( - limit: 1000000 - orderBy: { timestamp: { desc: true } } - where: { adventurerId: { eq: $adventurerId } } - ) { - ...BattleFields + ${BATTLES_FRAGMENT} + query get_battles($adventurerId: FeltValue) { + battles( + limit: 1000000 + orderBy: { timestamp: { desc: true } } + where: { adventurerId: { eq: $adventurerId } } + ) { + ...BattleFields + } } - } `; const getBattlesByBeast = gql` - ${BATTLES_FRAGMENT} - query get_battles_by_beast( - $adventurerId: FeltValue - $beast: BeastValue - $seed: HexValue - ) { - battles( - where: { - adventurerId: { eq: $adventurerId } - beast: { eq: $beast } - seed: { eq: $seed } - } - orderBy: { timestamp: { desc: true } } + ${BATTLES_FRAGMENT} + query get_battles_by_beast( + $adventurerId: FeltValue + $beast: BeastValue + $seed: HexValue ) { - ...BattleFields + battles( + where: { + adventurerId: { eq: $adventurerId } + beast: { eq: $beast } + seed: { eq: $seed } + } + orderBy: { timestamp: { desc: true } } + ) { + ...BattleFields + } } - } `; const getLastBattleByAdventurer = gql` - ${BATTLES_FRAGMENT} - query get_latest_battle_by_adventurer($adventurerId: FeltValue) { - battles( - limit: 1 - where: { adventurerId: { eq: $adventurerId } } - orderBy: { timestamp: { desc: true } } - ) { - ...BattleFields + ${BATTLES_FRAGMENT} + query get_latest_battle_by_adventurer($adventurerId: FeltValue) { + battles( + limit: 1 + where: { adventurerId: { eq: $adventurerId } } + orderBy: { timestamp: { desc: true } } + ) { + ...BattleFields + } } - } `; const getBattleByTxHash = gql` - ${BATTLES_FRAGMENT} - query get_latest_battle_by_tx($txHash: HexValue) { - battles( - where: { txHash: { eq: $txHash } } - orderBy: { timestamp: { asc: true } } - ) { - ...BattleFields + ${BATTLES_FRAGMENT} + query get_latest_battle_by_tx($txHash: HexValue) { + battles( + where: { txHash: { eq: $txHash } } + orderBy: { timestamp: { asc: true } } + ) { + ...BattleFields + } } - } `; const getItemsByTokenId = gql` - ${ITEMS_FRAGMENT} - query get_items($item: ItemValue) { - items(where: { item: { eq: $item } }) { - ...ItemFields + ${ITEMS_FRAGMENT} + query get_items($item: ItemValue) { + items(where: { item: { eq: $item } }) { + ...ItemFields + } } - } `; const getLatestMarketItems = gql` - ${ITEMS_FRAGMENT} - query get_latest_market_items($id: FeltValue) { - items( - where: { adventurerId: { eq: $id }, isAvailable: { eq: true } } - limit: 100000 - ) { - ...ItemFields + ${ITEMS_FRAGMENT} + query get_latest_market_items($id: FeltValue) { + items( + where: { adventurerId: { eq: $id }, isAvailable: { eq: true } } + limit: 100000 + ) { + ...ItemFields + } } - } `; const getItemsByAdventurer = gql` - ${ITEMS_FRAGMENT} - query get_items_by_adventurer($id: FeltValue) { - items( - where: { adventurerId: { eq: $id }, owner: { eq: true } } - limit: 10000000 - ) { - ...ItemFields + ${ITEMS_FRAGMENT} + query get_items_by_adventurer($id: FeltValue) { + items( + where: { adventurerId: { eq: $id }, owner: { eq: true } } + limit: 10000000 + ) { + ...ItemFields + } } - } `; const getItemsByOwner = gql` - ${ITEMS_FRAGMENT} - query get_items_by_owner($owner: HexValue) { - items(where: { owner: { eq: $owner } }, limit: 10000000) { - ...ItemFields + ${ITEMS_FRAGMENT} + query get_items_by_owner($owner: HexValue) { + items(where: { owner: { eq: $owner } }, limit: 10000000) { + ...ItemFields + } } - } `; const getTopScores = gql` - ${SCORES_FRAGMENT} - query get_top_scores { - scores(limit: 10000000) { - ...ScoreFields + ${SCORES_FRAGMENT} + query get_top_scores { + scores(limit: 10000000) { + ...ScoreFields + } } - } `; const getScoresAndAdventurers = gql` - ${SCORES_FRAGMENT} - ${ADVENTURERS_FRAGMENT} - query getScoresAndAdventurers { - scores(limit: 10000000, orderBy: { totalPayout: { desc: true } }) { - ...ScoreFields + ${SCORES_FRAGMENT} + ${ADVENTURERS_FRAGMENT} + query getScoresAndAdventurers { + scores(limit: 10000000, orderBy: { totalPayout: { desc: true } }) { + ...ScoreFields + } + adventurers(limit: 10000000, orderBy: { xp: { desc: true } }) { + ...AdventurerFields + } } - adventurers(limit: 10000000, orderBy: { xp: { desc: true } }) { - ...AdventurerFields - } - } `; const getScoresInList = gql` - ${SCORES_FRAGMENT} - query get_top_scores($ids: [FeltValue!]) { - scores(where: { adventurerId: { In: $ids } }, limit: 10000000) { - ...ScoreFields + ${SCORES_FRAGMENT} + query get_top_scores($ids: [FeltValue!]) { + scores(where: { adventurerId: { In: $ids } }, limit: 10000000) { + ...ScoreFields + } } - } `; const getGoldenTokensByOwner = gql` - ${GOLDEN_TOKEN_FRAGMENT} - query getGoldenTokensByOwner($contractAddress: String!, $owner: String!) { - getERC721Tokens( - contract_address: $contractAddress - cursor: 0 - limit: 10000 - owner: $owner - ) { - ...GoldenTokenFields + ${GOLDEN_TOKEN_FRAGMENT} + query getGoldenTokensByOwner($contractAddress: String!, $owner: String!) { + getERC721Tokens( + contract_address: $contractAddress + cursor: 0 + limit: 10000 + owner: $owner + ) { + ...GoldenTokenFields + } } - } `; export { - getAdventurer, - getDiscoveries, - getLatestDiscoveries, - getLastDiscovery, - getLastBeastDiscovery, - getDiscoveryByTxHash, - getAdventurersByOwner, - getAdventurerById, - getAdventurersInList, - getAdventurersInListByXp, - getAdventurerByGold, - getBeastsByAdventurer, - getBeast, - getKilledBeasts, - getLatestBattlesByAdventurer, - getBattlesByBeast, - getLastBattleByAdventurer, - getBattlesByAdventurer, - getBattleByTxHash, - getItems, - getItemsByTokenId, - getLatestMarketItems, - getItemsByOwner, - getItemsByAdventurer, - getAdventurerByXP, - getAdventurersByXPPaginated, - getTopScores, - getScoresInList, - getGoldenTokensByOwner, - getScoresAndAdventurers, + getAdventurer, + getDiscoveries, + getLatestDiscoveries, + getLastDiscovery, + getLastBeastDiscovery, + getDiscoveryByTxHash, + getAdventurersByOwner, + getAdventurerById, + getAdventurersInList, + getAdventurersInListByXp, + getAdventurerByGold, + getBeastsByAdventurer, + getBeast, + getKilledBeasts, + getLatestBattlesByAdventurer, + getBattlesByBeast, + getLastBattleByAdventurer, + getBattlesByAdventurer, + getBattleByTxHash, + getItems, + getItemsByTokenId, + getLatestMarketItems, + getItemsByOwner, + getItemsByAdventurer, + getAdventurerByXP, + getAdventurersByXPPaginated, + getTopScores, + getScoresInList, + getGoldenTokensByOwner, + getScoresAndAdventurers, }; diff --git a/packages/core/src/state/format.ts b/packages/core/src/state/format.ts index e10c28a..80bd1fe 100644 --- a/packages/core/src/state/format.ts +++ b/packages/core/src/state/format.ts @@ -3,842 +3,844 @@ import { Beast, HASHED_SELECTORS, SELECTORS } from "../type"; import * as EventTypes from "../type/events"; export const formatBeastData = ( - event: EventTypes.DiscoveredBeastEvent + event: EventTypes.DiscoveredBeastEvent ): Beast => { - const currentTime = new Date().toISOString(); - return { - adventurerId: event.adventurerState.adventurerId, - beast: `Beast_${event.id}`, // Placeholder name based on ID - createdTime: currentTime, - health: 100, // Placeholder value, should be calculated based on the seed - lastUpdatedTime: currentTime, - level: event.beastSpecs.level, - seed: event.seed.toString(), - slainOnTime: null, - special1: event.beastSpecs.specials.special1, - special2: event.beastSpecs.specials.special2, - special3: event.beastSpecs.specials.special3, - timestamp: currentTime, - }; + const currentTime = new Date().toISOString(); + return { + adventurerId: event.adventurerState.adventurerId, + beast: `Beast_${event.id}`, // Placeholder name based on ID + createdTime: currentTime, + health: 100, // Placeholder value, should be calculated based on the seed + lastUpdatedTime: currentTime, + level: event.beastSpecs.level, + seed: event.seed.toString(), + slainOnTime: null, + special1: event.beastSpecs.specials.special1, + special2: event.beastSpecs.specials.special2, + special3: event.beastSpecs.specials.special3, + timestamp: currentTime, + }; }; export function parseAdventurerState(data: string[]) { - return { - owner: data[0], - adventurerId: parseInt(data[1]), - adventurerEntropy: data[2], - adventurer: { - health: parseInt(data[3]), - xp: parseInt(data[4]), - gold: parseInt(data[5]), - beastHealth: parseInt(data[6]), - statUpgradesAvailable: parseInt(data[7]), - stats: { - strength: parseInt(data[8]), - dexterity: parseInt(data[9]), - vitality: parseInt(data[10]), - intelligence: parseInt(data[11]), - wisdom: parseInt(data[12]), - charisma: parseInt(data[13]), - luck: parseInt(data[14]), - }, - equipment: { - weapon: { - id: parseInt(data[15]), - xp: parseInt(data[16]), - }, - chest: { - id: parseInt(data[17]), - xp: parseInt(data[18]), - }, - head: { - id: parseInt(data[19]), - xp: parseInt(data[20]), - }, - waist: { - id: parseInt(data[21]), - xp: parseInt(data[22]), - }, - foot: { - id: parseInt(data[23]), - xp: parseInt(data[24]), - }, - hand: { - id: parseInt(data[25]), - xp: parseInt(data[26]), - }, - neck: { - id: parseInt(data[27]), - xp: parseInt(data[28]), - }, - ring: { - id: parseInt(data[29]), - xp: parseInt(data[30]), - }, - }, - mutated: convertToBoolean(parseInt(data[31])), - }, - }; + return { + owner: data[0], + adventurerId: parseInt(data[1]), + adventurerEntropy: data[2], + adventurer: { + health: parseInt(data[3]), + xp: parseInt(data[4]), + gold: parseInt(data[5]), + beastHealth: parseInt(data[6]), + statUpgradesAvailable: parseInt(data[7]), + stats: { + strength: parseInt(data[8]), + dexterity: parseInt(data[9]), + vitality: parseInt(data[10]), + intelligence: parseInt(data[11]), + wisdom: parseInt(data[12]), + charisma: parseInt(data[13]), + luck: parseInt(data[14]), + }, + equipment: { + weapon: { + id: parseInt(data[15]), + xp: parseInt(data[16]), + }, + chest: { + id: parseInt(data[17]), + xp: parseInt(data[18]), + }, + head: { + id: parseInt(data[19]), + xp: parseInt(data[20]), + }, + waist: { + id: parseInt(data[21]), + xp: parseInt(data[22]), + }, + foot: { + id: parseInt(data[23]), + xp: parseInt(data[24]), + }, + hand: { + id: parseInt(data[25]), + xp: parseInt(data[26]), + }, + neck: { + id: parseInt(data[27]), + xp: parseInt(data[28]), + }, + ring: { + id: parseInt(data[29]), + xp: parseInt(data[30]), + }, + }, + mutated: convertToBoolean(parseInt(data[31])), + }, + }; } export function convertToBoolean(value: number): boolean { - return value === 1; + return value === 1; } export const parseAdventurerMeta = (data: string[]) => { - return { - startEntropy: data[1], - startingStats: { - strength: parseInt(data[2]), - dexterity: parseInt(data[3]), - vitality: parseInt(data[4]), - intelligence: parseInt(data[5]), - wisdom: parseInt(data[6]), - charisma: parseInt(data[7]), - luck: parseInt(data[8]), - }, - interfaceCamel: convertToBoolean(parseInt(data[9])), - name: parseInt(data[10]), - }; + return { + startEntropy: data[1], + startingStats: { + strength: parseInt(data[2]), + dexterity: parseInt(data[3]), + vitality: parseInt(data[4]), + intelligence: parseInt(data[5]), + wisdom: parseInt(data[6]), + charisma: parseInt(data[7]), + luck: parseInt(data[8]), + }, + interfaceCamel: convertToBoolean(parseInt(data[9])), + name: parseInt(data[10]), + }; }; export function parseBag(data: string[]) { - return { - item1: { - id: parseInt(data[0]), - xp: parseInt(data[1]), - }, - item2: { - id: parseInt(data[2]), - xp: parseInt(data[3]), - }, - item3: { - id: parseInt(data[4]), - xp: parseInt(data[5]), - }, - item4: { - id: parseInt(data[6]), - xp: parseInt(data[7]), - }, - item5: { - id: parseInt(data[8]), - xp: parseInt(data[9]), - }, - item6: { - id: parseInt(data[10]), - xp: parseInt(data[11]), - }, - item7: { - id: parseInt(data[12]), - xp: parseInt(data[13]), - }, - item8: { - id: parseInt(data[14]), - xp: parseInt(data[15]), - }, - item9: { - id: parseInt(data[16]), - xp: parseInt(data[17]), - }, - item10: { - id: parseInt(data[18]), - xp: parseInt(data[19]), - }, - item11: { - id: parseInt(data[20]), - xp: parseInt(data[21]), - }, - item12: { - id: parseInt(data[22]), - xp: parseInt(data[23]), - }, - item13: { - id: parseInt(data[24]), - xp: parseInt(data[25]), - }, - item14: { - id: parseInt(data[26]), - xp: parseInt(data[27]), - }, - item15: { - id: parseInt(data[28]), - xp: parseInt(data[29]), - }, - mutated: convertToBoolean(parseInt(data[30])), - }; + return { + item1: { + id: parseInt(data[0]), + xp: parseInt(data[1]), + }, + item2: { + id: parseInt(data[2]), + xp: parseInt(data[3]), + }, + item3: { + id: parseInt(data[4]), + xp: parseInt(data[5]), + }, + item4: { + id: parseInt(data[6]), + xp: parseInt(data[7]), + }, + item5: { + id: parseInt(data[8]), + xp: parseInt(data[9]), + }, + item6: { + id: parseInt(data[10]), + xp: parseInt(data[11]), + }, + item7: { + id: parseInt(data[12]), + xp: parseInt(data[13]), + }, + item8: { + id: parseInt(data[14]), + xp: parseInt(data[15]), + }, + item9: { + id: parseInt(data[16]), + xp: parseInt(data[17]), + }, + item10: { + id: parseInt(data[18]), + xp: parseInt(data[19]), + }, + item11: { + id: parseInt(data[20]), + xp: parseInt(data[21]), + }, + item12: { + id: parseInt(data[22]), + xp: parseInt(data[23]), + }, + item13: { + id: parseInt(data[24]), + xp: parseInt(data[25]), + }, + item14: { + id: parseInt(data[26]), + xp: parseInt(data[27]), + }, + item15: { + id: parseInt(data[28]), + xp: parseInt(data[29]), + }, + mutated: convertToBoolean(parseInt(data[30])), + }; } export function parseItems(data: string[]) { - const purchases = []; - const chunkedArray = chunkArray(data, 5); - for (let i = 0; i < chunkedArray.length; i++) { - purchases.push({ - item: { - id: parseInt(chunkedArray[i][0]), - tier: parseInt(chunkedArray[i][1]), - itemType: parseInt(chunkedArray[i][2]), - slot: parseInt(chunkedArray[i][3]), - }, - price: parseInt(chunkedArray[i][4]), - }); - } - return purchases; + const purchases = []; + const chunkedArray = chunkArray(data, 5); + for (let i = 0; i < chunkedArray.length; i++) { + purchases.push({ + item: { + id: parseInt(chunkedArray[i][0]), + tier: parseInt(chunkedArray[i][1]), + itemType: parseInt(chunkedArray[i][2]), + slot: parseInt(chunkedArray[i][3]), + }, + price: parseInt(chunkedArray[i][4]), + }); + } + return purchases; } export function parseItemLevels(data: string[]) { - const itemLevels = []; - const chunkedArray = chunkArray(data, 8); - for (let i = 0; i < chunkedArray.length; i++) { - itemLevels.push({ - itemId: parseInt(chunkedArray[i][0]), - previousLevel: parseInt(chunkedArray[i][1]), - newLevel: parseInt(chunkedArray[i][2]), - suffixUnlocked: convertToBoolean(parseInt(chunkedArray[i][3])), - prefixesUnlocked: convertToBoolean(parseInt(chunkedArray[i][4])), - specials: { - special1: parseInt(chunkedArray[i][5]), - special2: parseInt(chunkedArray[i][6]), - special3: parseInt(chunkedArray[i][7]), - }, - }); - } - return itemLevels; + const itemLevels = []; + const chunkedArray = chunkArray(data, 8); + for (let i = 0; i < chunkedArray.length; i++) { + itemLevels.push({ + itemId: parseInt(chunkedArray[i][0]), + previousLevel: parseInt(chunkedArray[i][1]), + newLevel: parseInt(chunkedArray[i][2]), + suffixUnlocked: convertToBoolean(parseInt(chunkedArray[i][3])), + prefixesUnlocked: convertToBoolean(parseInt(chunkedArray[i][4])), + specials: { + special1: parseInt(chunkedArray[i][5]), + special2: parseInt(chunkedArray[i][6]), + special3: parseInt(chunkedArray[i][7]), + }, + }); + } + return itemLevels; } export function parseEquippedItems(data: string[]) { - const equippedLength = parseInt(data[0]); - const equippedItems = []; - const unequippedItems = []; - for (let i = 1; i <= equippedLength; i++) { - equippedItems.push(parseInt(data[i])); - } - const unequippedLength = parseInt(data[equippedLength + 1]); - for (let i = 2; i <= unequippedLength + 1; i++) { - unequippedItems.push(parseInt(data[i + equippedLength])); - } - return { equippedItems, unequippedItems }; + const equippedLength = parseInt(data[0]); + const equippedItems = []; + const unequippedItems = []; + for (let i = 1; i <= equippedLength; i++) { + equippedItems.push(parseInt(data[i])); + } + const unequippedLength = parseInt(data[equippedLength + 1]); + for (let i = 2; i <= unequippedLength + 1; i++) { + unequippedItems.push(parseInt(data[i + equippedLength])); + } + return { equippedItems, unequippedItems }; } export function parseEquipmentChanged(data: string[]) { - const equippedLength = parseInt(data[0]); - const equippedItems = []; - const baggedItems = []; - const droppedItems = []; - for (let i = 1; i <= equippedLength; i++) { - equippedItems.push(parseInt(data[i])); - } - const baggedLength = parseInt(data[equippedLength + 1]); - for (let i = 2; i <= baggedLength + 1; i++) { - baggedItems.push(parseInt(data[i + equippedLength])); - } - const droppedLength = parseInt(data[baggedLength + 1]); - for (let i = 2; i <= droppedLength + 1; i++) { - droppedItems.push(parseInt(data[i + baggedLength])); - } - return { equippedItems, baggedItems, droppedItems }; + const equippedLength = parseInt(data[0]); + const equippedItems = []; + const baggedItems = []; + const droppedItems = []; + for (let i = 1; i <= equippedLength; i++) { + equippedItems.push(parseInt(data[i])); + } + const baggedLength = parseInt(data[equippedLength + 1]); + for (let i = 2; i <= baggedLength + 1; i++) { + baggedItems.push(parseInt(data[i + equippedLength])); + } + const droppedLength = parseInt(data[baggedLength + 1]); + for (let i = 2; i <= droppedLength + 1; i++) { + droppedItems.push(parseInt(data[i + baggedLength])); + } + return { equippedItems, baggedItems, droppedItems }; } export function chunkArray(array: T[], chunkSize: number): T[][] { - const chunks: T[][] = []; - for (let i = 0; i < array?.length; i += chunkSize) { - const nextChunk = array?.slice(i, i + chunkSize); - chunks.push(nextChunk); - if (nextChunk.length < chunkSize) break; // Stop if we've hit the end of the array - } - return chunks; + const chunks: T[][] = []; + for (let i = 0; i < array?.length; i += chunkSize) { + const nextChunk = array?.slice(i, i + chunkSize); + chunks.push(nextChunk); + if (nextChunk.length < chunkSize) break; // Stop if we've hit the end of the array + } + return chunks; } export function parseStartGameEvent(data: string[]): { - name: string; - event: EventTypes.StartGameEvent; + name: string; + event: EventTypes.StartGameEvent; } { - return { - name: SELECTORS.StartGame, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - adventurerMeta: parseAdventurerMeta(data.slice(31, 42)), - revealBlock: parseInt(data[42]), - }, - }; + return { + name: SELECTORS.StartGame, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + adventurerMeta: parseAdventurerMeta(data.slice(31, 42)), + revealBlock: parseInt(data[42]), + }, + }; } export function parseAdventurerUpgradedEvent(data: string[]): { - name: string; - event: EventTypes.AdventurerUpgradedEvent; + name: string; + event: EventTypes.AdventurerUpgradedEvent; } { - return { - name: SELECTORS.AdventurerUpgraded, - event: { - adventurerStateWithBag: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - bag: parseBag(data.slice(32, 63)), - }, - strengthIncrease: parseInt(data[64]), - dexterityIncrease: parseInt(data[65]), - vitalityIncrease: parseInt(data[66]), - intelligenceIncrease: parseInt(data[67]), - wisdomIncrease: parseInt(data[68]), - charismaIncrease: parseInt(data[69]), - }, - }; + return { + name: SELECTORS.AdventurerUpgraded, + event: { + adventurerStateWithBag: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + bag: parseBag(data.slice(32, 63)), + }, + strengthIncrease: parseInt(data[64]), + dexterityIncrease: parseInt(data[65]), + vitalityIncrease: parseInt(data[66]), + intelligenceIncrease: parseInt(data[67]), + wisdomIncrease: parseInt(data[68]), + charismaIncrease: parseInt(data[69]), + }, + }; } export function parseDiscoveredHealthEvent(data: string[]): { - name: string; - event: EventTypes.DiscoveredHealthEvent; + name: string; + event: EventTypes.DiscoveredHealthEvent; } { - return { - name: SELECTORS.DiscoveredHealth, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - healthAmount: parseInt(data[32]), - }, - }; + return { + name: SELECTORS.DiscoveredHealth, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + healthAmount: parseInt(data[32]), + }, + }; } export function parseDiscoveredGoldEvent(data: string[]): { - name: string; - event: EventTypes.DiscoveredGoldEvent; + name: string; + event: EventTypes.DiscoveredGoldEvent; } { - return { - name: SELECTORS.DiscoveredGold, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - goldAmount: parseInt(data[32]), - }, - }; + return { + name: SELECTORS.DiscoveredGold, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + goldAmount: parseInt(data[32]), + }, + }; } export function parseDiscoveredXPEvent(data: string[]): { - name: string; - event: EventTypes.DiscoveredXPEvent; + name: string; + event: EventTypes.DiscoveredXPEvent; } { - return { - name: SELECTORS.DiscoveredXP, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - xpAmount: parseInt(data[32]), - }, - }; + return { + name: SELECTORS.DiscoveredXP, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + xpAmount: parseInt(data[32]), + }, + }; } export function parseDiscoveredLootEvent(data: string[]): { - name: string; - event: EventTypes.DiscoveredLootEvent; + name: string; + event: EventTypes.DiscoveredLootEvent; } { - return { - name: SELECTORS.DiscoveredLoot, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - itemId: parseInt(data[32]), - }, - }; + return { + name: SELECTORS.DiscoveredLoot, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + itemId: parseInt(data[32]), + }, + }; } export function parseEquipmentChangedEvent(data: string[]): { - name: string; - event: EventTypes.EquipmentChangedEvent; + name: string; + event: EventTypes.EquipmentChangedEvent; } { - const { equippedItems, baggedItems, droppedItems } = parseEquipmentChanged( - data.slice(63) - ); - return { - name: SELECTORS.EquipmentChanged, - event: { - adventurerStateWithBag: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - bag: parseBag(data.slice(32, 63)), - }, - equippedItems, - baggedItems, - droppedItems, - }, - }; + const { equippedItems, baggedItems, droppedItems } = parseEquipmentChanged( + data.slice(63) + ); + return { + name: SELECTORS.EquipmentChanged, + event: { + adventurerStateWithBag: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + bag: parseBag(data.slice(32, 63)), + }, + equippedItems, + baggedItems, + droppedItems, + }, + }; } export function parseDodgedObstacleEvent(data: string[]): { - name: string; - event: EventTypes.DodgedObstacleEvent; + name: string; + event: EventTypes.DodgedObstacleEvent; } { - return { - name: SELECTORS.DodgedObstacle, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - id: parseInt(data[32]), - level: parseInt(data[33]), - damageTaken: parseInt(data[34]), - damageLocation: parseInt(data[35]), - xpEarnedAdventurer: parseInt(data[36]), - xpEarnedItems: parseInt(data[37]), - }, - }; + return { + name: SELECTORS.DodgedObstacle, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + id: parseInt(data[32]), + level: parseInt(data[33]), + damageTaken: parseInt(data[34]), + damageLocation: parseInt(data[35]), + xpEarnedAdventurer: parseInt(data[36]), + xpEarnedItems: parseInt(data[37]), + }, + }; } export function parseHitByObstacleEvent(data: string[]): { - name: string; - event: EventTypes.HitByObstacleEvent; + name: string; + event: EventTypes.HitByObstacleEvent; } { - return { - name: SELECTORS.HitByObstacle, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - id: parseInt(data[32]), - level: parseInt(data[33]), - damageTaken: parseInt(data[34]), - damageLocation: parseInt(data[35]), - xpEarnedAdventurer: parseInt(data[36]), - xpEarnedItems: parseInt(data[37]), - }, - }; + return { + name: SELECTORS.HitByObstacle, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + id: parseInt(data[32]), + level: parseInt(data[33]), + damageTaken: parseInt(data[34]), + damageLocation: parseInt(data[35]), + xpEarnedAdventurer: parseInt(data[36]), + xpEarnedItems: parseInt(data[37]), + }, + }; } export function parseDiscoveredBeastEvent(data: string[]): { - name: string; - event: EventTypes.DiscoveredBeastEvent; + name: string; + event: EventTypes.DiscoveredBeastEvent; } { - return { - name: SELECTORS.DiscoveredBeast, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - }, - }; + return { + name: SELECTORS.DiscoveredBeast, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + }, + }; } export function parseAmbushedByBeastEvent(data: string[]): { - name: string; - event: EventTypes.AmbushedByBeastEvent; + name: string; + event: EventTypes.AmbushedByBeastEvent; } { - return { - name: SELECTORS.AmbushedByBeast, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - damage: parseInt(data[40]), - criticalHit: convertToBoolean(parseInt(data[41])), - location: parseInt(data[42]), - }, - }; + return { + name: SELECTORS.AmbushedByBeast, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + damage: parseInt(data[40]), + criticalHit: convertToBoolean(parseInt(data[41])), + location: parseInt(data[42]), + }, + }; } export function parseAttackedBeastEvent(data: string[]): { - name: string; - event: EventTypes.AttackedBeastEvent; + name: string; + event: EventTypes.AttackedBeastEvent; } { - return { - name: SELECTORS.AttackedBeast, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - damage: parseInt(data[40]), - criticalHit: convertToBoolean(parseInt(data[41])), - location: parseInt(data[42]), - }, - }; + return { + name: SELECTORS.AttackedBeast, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + damage: parseInt(data[40]), + criticalHit: convertToBoolean(parseInt(data[41])), + location: parseInt(data[42]), + }, + }; } export function parseAttackedByBeastEvent(data: string[]): { - name: string; - event: EventTypes.AttackedByBeastEvent; + name: string; + event: EventTypes.AttackedByBeastEvent; } { - return { - name: SELECTORS.AttackedByBeast, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - damage: parseInt(data[40]), - criticalHit: convertToBoolean(parseInt(data[41])), - location: parseInt(data[42]), - }, - }; + return { + name: SELECTORS.AttackedByBeast, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + damage: parseInt(data[40]), + criticalHit: convertToBoolean(parseInt(data[41])), + location: parseInt(data[42]), + }, + }; } export function parseSlayedBeastEvent(data: string[]): { - name: string; - event: EventTypes.SlayedBeastEvent; + name: string; + event: EventTypes.SlayedBeastEvent; } { - return { - name: SELECTORS.SlayedBeast, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - damageDealt: parseInt(data[40]), - criticalHit: convertToBoolean(parseInt(data[41])), - xpEarnedAdventurer: parseInt(data[42]), - xpEarnedItems: parseInt(data[43]), - goldEarned: parseInt(data[44]), - }, - }; + return { + name: SELECTORS.SlayedBeast, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + damageDealt: parseInt(data[40]), + criticalHit: convertToBoolean(parseInt(data[41])), + xpEarnedAdventurer: parseInt(data[42]), + xpEarnedItems: parseInt(data[43]), + goldEarned: parseInt(data[44]), + }, + }; } export function parseFleeFailedEvent(data: string[]): { - name: string; - event: EventTypes.FleeFailedEvent; + name: string; + event: EventTypes.FleeFailedEvent; } { - return { - name: SELECTORS.FleeFailed, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - }, - }; + return { + name: SELECTORS.FleeFailed, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + }, + }; } export function parseFleeSucceededEvent(data: string[]): { - name: string; - event: EventTypes.FleeSucceededEvent; + name: string; + event: EventTypes.FleeSucceededEvent; } { - return { - name: SELECTORS.FleeSucceeded, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - seed: parseInt(data[32]), - id: parseInt(data[33]), - beastSpecs: { - tier: parseInt(data[34]), - itemType: parseInt(data[35]), - level: parseInt(data[36]), - specials: { - special1: parseInt(data[37]), - special2: parseInt(data[38]), - special3: parseInt(data[39]), - }, - }, - }, - }; + return { + name: SELECTORS.FleeSucceeded, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + seed: parseInt(data[32]), + id: parseInt(data[33]), + beastSpecs: { + tier: parseInt(data[34]), + itemType: parseInt(data[35]), + level: parseInt(data[36]), + specials: { + special1: parseInt(data[37]), + special2: parseInt(data[38]), + special3: parseInt(data[39]), + }, + }, + }, + }; } export function parsePurchasedItemsEvent(data: string[]): { - name: string; - event: EventTypes.PurchasedItemsEvent; + name: string; + event: EventTypes.PurchasedItemsEvent; } { - return { - name: SELECTORS.PurchasedItems, - event: { - adventurerStateWithBag: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - bag: parseBag(data.slice(32, 63)), - }, - purchases: parseItems(data.slice(64)), - }, - }; + return { + name: SELECTORS.PurchasedItems, + event: { + adventurerStateWithBag: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + bag: parseBag(data.slice(32, 63)), + }, + purchases: parseItems(data.slice(64)), + }, + }; } export function parsePurchasedPotionsEvent(data: string[]): { - name: string; - event: EventTypes.PurchasedPotionsEvent; + name: string; + event: EventTypes.PurchasedPotionsEvent; } { - return { - name: SELECTORS.PurchasedPotions, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - quantity: parseInt(data[32]), - cost: parseInt(data[33]), - health: parseInt(data[34]), - }, - }; + return { + name: SELECTORS.PurchasedPotions, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + quantity: parseInt(data[32]), + cost: parseInt(data[33]), + health: parseInt(data[34]), + }, + }; } export function parseEquippedItemsEvent(data: string[]): { - name: string; - event: EventTypes.EquippedItemsEvent; + name: string; + event: EventTypes.EquippedItemsEvent; } { - const { equippedItems, unequippedItems } = parseEquippedItems(data.slice(63)); - return { - name: SELECTORS.EquippedItems, - event: { - adventurerStateWithBag: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - bag: parseBag(data.slice(32, 63)), - }, - equippedItems, - unequippedItems, - }, - }; + const { equippedItems, unequippedItems } = parseEquippedItems( + data.slice(63) + ); + return { + name: SELECTORS.EquippedItems, + event: { + adventurerStateWithBag: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + bag: parseBag(data.slice(32, 63)), + }, + equippedItems, + unequippedItems, + }, + }; } export function parseDroppedItemsEvent(data: string[]): { - name: string; - event: EventTypes.DroppedItemsEvent; + name: string; + event: EventTypes.DroppedItemsEvent; } { - const itemIds = data.slice(64).map((id) => parseInt(id)); - return { - name: SELECTORS.DroppedItems, - event: { - adventurerStateWithBag: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - bag: parseBag(data.slice(32, 63)), - }, - itemIds, - }, - }; + const itemIds = data.slice(64).map((id) => parseInt(id)); + return { + name: SELECTORS.DroppedItems, + event: { + adventurerStateWithBag: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + bag: parseBag(data.slice(32, 63)), + }, + itemIds, + }, + }; } export function parseGreatnessIncreasedEvent(data: string[]): { - name: string; - event: EventTypes.GreatnessIncreasedEvent; + name: string; + event: EventTypes.GreatnessIncreasedEvent; } { - return { - name: SELECTORS.GreatnessIncreased, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - itemId: parseInt(data[32]), - previousLevel: parseInt(data[33]), - newLevel: parseInt(data[34]), - }, - }; + return { + name: SELECTORS.GreatnessIncreased, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + itemId: parseInt(data[32]), + previousLevel: parseInt(data[33]), + newLevel: parseInt(data[34]), + }, + }; } export function parseItemsLeveledUpEvent(data: string[]): { - name: string; - event: EventTypes.ItemsLeveledUpEvent; + name: string; + event: EventTypes.ItemsLeveledUpEvent; } { - return { - name: SELECTORS.ItemsLeveledUp, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - items: parseItemLevels(data.slice(33)), - }, - }; + return { + name: SELECTORS.ItemsLeveledUp, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + items: parseItemLevels(data.slice(33)), + }, + }; } export function parseNewHighScoreEvent(data: string[]): { - name: string; - event: EventTypes.NewHighScoreEvent; + name: string; + event: EventTypes.NewHighScoreEvent; } { - return { - name: SELECTORS.NewHighScore, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - rank: parseInt(data[32]), - }, - }; + return { + name: SELECTORS.NewHighScore, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + rank: parseInt(data[32]), + }, + }; } export function parseAdventurerDiedEvent(data: string[]): { - name: string; - event: EventTypes.AdventurerDiedEvent; + name: string; + event: EventTypes.AdventurerDiedEvent; } { - return { - name: SELECTORS.AdventurerDied, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - killedByBeast: parseInt(data[32]), - killedByObstacle: parseInt(data[33]), - callerAddress: data[34], - }, - }; + return { + name: SELECTORS.AdventurerDied, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + killedByBeast: parseInt(data[32]), + killedByObstacle: parseInt(data[33]), + callerAddress: data[34], + }, + }; } export function parseAdventurerLeveledUpEvent(data: string[]): { - name: string; - event: EventTypes.AdventurerLeveledUpEvent; + name: string; + event: EventTypes.AdventurerLeveledUpEvent; } { - return { - name: SELECTORS.AdventurerLeveledUp, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - previousLevel: parseInt(data[32]), - newLevel: parseInt(data[33]), - }, - }; + return { + name: SELECTORS.AdventurerLeveledUp, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + previousLevel: parseInt(data[32]), + newLevel: parseInt(data[33]), + }, + }; } export function parseUpgradesAvailableEvent(data: string[]): { - name: string; - event: EventTypes.UpgradesAvailableEvent; + name: string; + event: EventTypes.UpgradesAvailableEvent; } { - const newItemsIds = data.slice(33).map((id) => parseInt(id)); - return { - name: SELECTORS.UpgradesAvailable, - event: { - adventurerState: parseAdventurerState(data.slice(0, 31)), - items: newItemsIds, - }, - }; + const newItemsIds = data.slice(33).map((id) => parseInt(id)); + return { + name: SELECTORS.UpgradesAvailable, + event: { + adventurerState: parseAdventurerState(data.slice(0, 31)), + items: newItemsIds, + }, + }; } export function getKeyFromValue( - data: Record, - value: string + data: Record, + value: string ): string | null { - for (const key in data) { - if (data[key] === value) { - return key; + for (const key in data) { + if (data[key] === value) { + return key; + } } - } - return null; + return null; } export function parseEvents( - receipt: InvokeTransactionReceiptResponse + receipt: InvokeTransactionReceiptResponse ): Array { - let events: Array = []; - if (!receipt.events) { - throw new Error(`No events found`); - } - - for (let raw of receipt.events) { - let eventName: string | null = getKeyFromValue( - HASHED_SELECTORS, - raw.keys[0] - ); - - if (!eventName) { - throw new Error(`Event name not found`); + let events: Array = []; + if (!receipt.events) { + throw new Error(`No events found`); } - switch (eventName) { - case HASHED_SELECTORS.StartGame: - events.push(parseStartGameEvent(raw.keys)); - break; - case HASHED_SELECTORS.AdventurerUpgraded: - events.push(parseAdventurerUpgradedEvent(raw.keys)); - break; - case HASHED_SELECTORS.DiscoveredHealth: - events.push(parseDiscoveredHealthEvent(raw.keys)); - break; - case HASHED_SELECTORS.DiscoveredGold: - events.push(parseDiscoveredGoldEvent(raw.keys)); - break; - case HASHED_SELECTORS.DiscoveredLoot: - events.push(parseDiscoveredLootEvent(raw.keys)); - break; - case HASHED_SELECTORS.DiscoveredXP: - events.push(parseDiscoveredXPEvent(raw.keys)); - break; - case HASHED_SELECTORS.EquipmentChanged: - events.push(parseEquipmentChangedEvent(raw.keys)); - break; - case HASHED_SELECTORS.DodgedObstacle: - events.push(parseDodgedObstacleEvent(raw.keys)); - break; - case HASHED_SELECTORS.HitByObstacle: - events.push(parseHitByObstacleEvent(raw.keys)); - break; - case HASHED_SELECTORS.DiscoveredBeast: - events.push(parseDiscoveredBeastEvent(raw.keys)); - break; - case HASHED_SELECTORS.AmbushedByBeast: - events.push(parseAmbushedByBeastEvent(raw.keys)); - break; - case HASHED_SELECTORS.AttackedBeast: - events.push(parseAttackedBeastEvent(raw.keys)); - break; - case HASHED_SELECTORS.AttackedByBeast: - events.push(parseAttackedByBeastEvent(raw.keys)); - break; - case HASHED_SELECTORS.SlayedBeast: - events.push(parseSlayedBeastEvent(raw.keys)); - break; - case HASHED_SELECTORS.FleeFailed: - events.push(parseFleeFailedEvent(raw.keys)); - break; - case HASHED_SELECTORS.FleeSucceeded: - events.push(parseFleeSucceededEvent(raw.keys)); - break; - case HASHED_SELECTORS.PurchasedItems: - events.push(parsePurchasedItemsEvent(raw.keys)); - break; - case HASHED_SELECTORS.PurchasedPotions: - events.push(parsePurchasedPotionsEvent(raw.keys)); - break; - case HASHED_SELECTORS.EquippedItems: - events.push(parseEquippedItemsEvent(raw.keys)); - break; - case HASHED_SELECTORS.DroppedItems: - events.push(parseDroppedItemsEvent(raw.keys)); - break; - case HASHED_SELECTORS.GreatnessIncreased: - events.push(parseGreatnessIncreasedEvent(raw.keys)); - break; - case HASHED_SELECTORS.ItemsLeveledUp: - events.push(parseItemsLeveledUpEvent(raw.keys)); - break; - case HASHED_SELECTORS.NewHighScore: - events.push(parseNewHighScoreEvent(raw.keys)); - break; - case HASHED_SELECTORS.AdventurerDied: - events.push(parseAdventurerDiedEvent(raw.keys)); - break; - case HASHED_SELECTORS.AdventurerLeveledUp: - events.push(parseAdventurerLeveledUpEvent(raw.keys)); - break; - case HASHED_SELECTORS.UpgradesAvailable: - events.push(parseUpgradesAvailableEvent(raw.keys)); - break; - - // TODO: Add transfer event - default: - throw new Error(`Unknown event name: ${eventName}`); + for (let raw of receipt.events) { + let eventName: string | null = getKeyFromValue( + HASHED_SELECTORS, + raw.keys[0] + ); + + if (!eventName) { + throw new Error(`Event name not found`); + } + + switch (eventName) { + case HASHED_SELECTORS.StartGame: + events.push(parseStartGameEvent(raw.keys)); + break; + case HASHED_SELECTORS.AdventurerUpgraded: + events.push(parseAdventurerUpgradedEvent(raw.keys)); + break; + case HASHED_SELECTORS.DiscoveredHealth: + events.push(parseDiscoveredHealthEvent(raw.keys)); + break; + case HASHED_SELECTORS.DiscoveredGold: + events.push(parseDiscoveredGoldEvent(raw.keys)); + break; + case HASHED_SELECTORS.DiscoveredLoot: + events.push(parseDiscoveredLootEvent(raw.keys)); + break; + case HASHED_SELECTORS.DiscoveredXP: + events.push(parseDiscoveredXPEvent(raw.keys)); + break; + case HASHED_SELECTORS.EquipmentChanged: + events.push(parseEquipmentChangedEvent(raw.keys)); + break; + case HASHED_SELECTORS.DodgedObstacle: + events.push(parseDodgedObstacleEvent(raw.keys)); + break; + case HASHED_SELECTORS.HitByObstacle: + events.push(parseHitByObstacleEvent(raw.keys)); + break; + case HASHED_SELECTORS.DiscoveredBeast: + events.push(parseDiscoveredBeastEvent(raw.keys)); + break; + case HASHED_SELECTORS.AmbushedByBeast: + events.push(parseAmbushedByBeastEvent(raw.keys)); + break; + case HASHED_SELECTORS.AttackedBeast: + events.push(parseAttackedBeastEvent(raw.keys)); + break; + case HASHED_SELECTORS.AttackedByBeast: + events.push(parseAttackedByBeastEvent(raw.keys)); + break; + case HASHED_SELECTORS.SlayedBeast: + events.push(parseSlayedBeastEvent(raw.keys)); + break; + case HASHED_SELECTORS.FleeFailed: + events.push(parseFleeFailedEvent(raw.keys)); + break; + case HASHED_SELECTORS.FleeSucceeded: + events.push(parseFleeSucceededEvent(raw.keys)); + break; + case HASHED_SELECTORS.PurchasedItems: + events.push(parsePurchasedItemsEvent(raw.keys)); + break; + case HASHED_SELECTORS.PurchasedPotions: + events.push(parsePurchasedPotionsEvent(raw.keys)); + break; + case HASHED_SELECTORS.EquippedItems: + events.push(parseEquippedItemsEvent(raw.keys)); + break; + case HASHED_SELECTORS.DroppedItems: + events.push(parseDroppedItemsEvent(raw.keys)); + break; + case HASHED_SELECTORS.GreatnessIncreased: + events.push(parseGreatnessIncreasedEvent(raw.keys)); + break; + case HASHED_SELECTORS.ItemsLeveledUp: + events.push(parseItemsLeveledUpEvent(raw.keys)); + break; + case HASHED_SELECTORS.NewHighScore: + events.push(parseNewHighScoreEvent(raw.keys)); + break; + case HASHED_SELECTORS.AdventurerDied: + events.push(parseAdventurerDiedEvent(raw.keys)); + break; + case HASHED_SELECTORS.AdventurerLeveledUp: + events.push(parseAdventurerLeveledUpEvent(raw.keys)); + break; + case HASHED_SELECTORS.UpgradesAvailable: + events.push(parseUpgradesAvailableEvent(raw.keys)); + break; + + // TODO: Add transfer event + default: + throw new Error(`Unknown event name: ${eventName}`); + } } - } - return events; + return events; } diff --git a/packages/core/src/state/index.ts b/packages/core/src/state/index.ts index 0a1090b..a289250 100644 --- a/packages/core/src/state/index.ts +++ b/packages/core/src/state/index.ts @@ -10,27 +10,27 @@ import { devtools } from "zustand/middleware"; import { Survivor } from "../objects/survivor"; export interface SurvivorStore { - survivor: Survivor | null; - updateSurvivor: (updates: Survivor) => void; - clearSurvivor: () => void; - newSurvivor: () => void; + survivor: Survivor | null; + updateSurvivor: (updates: Survivor) => void; + clearSurvivor: () => void; + newSurvivor: () => void; } export const useSurvivorStore = createStore()( - devtools( - (set) => ({ - survivor: null, - newSurvivor: () => { - set(() => { - return { survivor: new Survivor() }; - }); - }, - clearSurvivor: () => set({ survivor: null }), - updateSurvivor: (survivor: Survivor) => - set(() => { - return { survivor }; + devtools( + (set) => ({ + survivor: null, + newSurvivor: () => { + set(() => { + return { survivor: new Survivor() }; + }); + }, + clearSurvivor: () => set({ survivor: null }), + updateSurvivor: (survivor: Survivor) => + set(() => { + return { survivor }; + }), }), - }), - { name: "Survivor Store" } - ) + { name: "Survivor Store" } + ) ); diff --git a/packages/core/src/state/mock.ts b/packages/core/src/state/mock.ts index 145a100..ca1355e 100644 --- a/packages/core/src/state/mock.ts +++ b/packages/core/src/state/mock.ts @@ -2,485 +2,485 @@ import { shortString } from "starknet"; import * as EventTypes from "../type/events"; const encodeEventData = (event: any): string[] => { - return Object.values(event).flatMap((value) => { - if (typeof value === "object" && value !== null) { - return encodeEventData(value); - } - if (typeof value === "number") { - return ["0x" + value.toString(16)]; - } - if (typeof value === "boolean") { - return [value ? "0x1" : "0x0"]; - } - if (typeof value === "string" && value.startsWith("0x")) { - return [value]; - } - return [shortString.encodeShortString((value as any).toString())]; - }); + return Object.values(event).flatMap((value) => { + if (typeof value === "object" && value !== null) { + return encodeEventData(value); + } + if (typeof value === "number") { + return ["0x" + value.toString(16)]; + } + if (typeof value === "boolean") { + return [value ? "0x1" : "0x0"]; + } + if (typeof value === "string" && value.startsWith("0x")) { + return [value]; + } + return [shortString.encodeShortString((value as any).toString())]; + }); }; const createBagState = (itemIds: number[]): EventTypes.Bag => { - const bag: EventTypes.Bag = { - item1: { id: 0, xp: 0 }, - item2: { id: 0, xp: 0 }, - item3: { id: 0, xp: 0 }, - item4: { id: 0, xp: 0 }, - item5: { id: 0, xp: 0 }, - item6: { id: 0, xp: 0 }, - item7: { id: 0, xp: 0 }, - item8: { id: 0, xp: 0 }, - item9: { id: 0, xp: 0 }, - item10: { id: 0, xp: 0 }, - item11: { id: 0, xp: 0 }, - item12: { id: 0, xp: 0 }, - item13: { id: 0, xp: 0 }, - item14: { id: 0, xp: 0 }, - item15: { id: 0, xp: 0 }, - mutated: false, - }; - - itemIds.forEach((id, index) => { - if (index < 15) { - const key = `item${index + 1}` as keyof EventTypes.Bag; - (bag[key] as any) = { id, xp: 0 }; - } - }); - return bag; + const bag: EventTypes.Bag = { + item1: { id: 0, xp: 0 }, + item2: { id: 0, xp: 0 }, + item3: { id: 0, xp: 0 }, + item4: { id: 0, xp: 0 }, + item5: { id: 0, xp: 0 }, + item6: { id: 0, xp: 0 }, + item7: { id: 0, xp: 0 }, + item8: { id: 0, xp: 0 }, + item9: { id: 0, xp: 0 }, + item10: { id: 0, xp: 0 }, + item11: { id: 0, xp: 0 }, + item12: { id: 0, xp: 0 }, + item13: { id: 0, xp: 0 }, + item14: { id: 0, xp: 0 }, + item15: { id: 0, xp: 0 }, + mutated: false, + }; + + itemIds.forEach((id, index) => { + if (index < 15) { + const key = `item${index + 1}` as keyof EventTypes.Bag; + (bag[key] as any) = { id, xp: 0 }; + } + }); + return bag; }; // Helper function to create a basic AdventurerState const createBasicAdventurerState = ( - id: number + id: number ): EventTypes.AdventurerState => ({ - owner: "0x1234567890123456789012345678901234567890", - adventurerId: id, - adventurerEntropy: "someEntropyString", - adventurer: { - health: 100, - xp: 0, - gold: 0, - beastHealth: 0, - statUpgradesAvailable: 0, - stats: { - strength: 10, - dexterity: 10, - vitality: 10, - intelligence: 10, - wisdom: 10, - charisma: 10, - luck: 10, - }, - equipment: { - weapon: { id: 1, xp: 0 }, - chest: { id: 2, xp: 0 }, - head: { id: 3, xp: 0 }, - waist: { id: 4, xp: 0 }, - foot: { id: 5, xp: 0 }, - hand: { id: 6, xp: 0 }, - neck: { id: 7, xp: 0 }, - ring: { id: 8, xp: 0 }, + owner: "0x1234567890123456789012345678901234567890", + adventurerId: id, + adventurerEntropy: "someEntropyString", + adventurer: { + health: 100, + xp: 0, + gold: 0, + beastHealth: 0, + statUpgradesAvailable: 0, + stats: { + strength: 10, + dexterity: 10, + vitality: 10, + intelligence: 10, + wisdom: 10, + charisma: 10, + luck: 10, + }, + equipment: { + weapon: { id: 1, xp: 0 }, + chest: { id: 2, xp: 0 }, + head: { id: 3, xp: 0 }, + waist: { id: 4, xp: 0 }, + foot: { id: 5, xp: 0 }, + hand: { id: 6, xp: 0 }, + neck: { id: 7, xp: 0 }, + ring: { id: 8, xp: 0 }, + }, + mutated: false, }, - mutated: false, - }, }); // Create mock events for all event types export const mockStartGameEvent: EventTypes.StartGameEvent = { - adventurerState: createBasicAdventurerState(1), - adventurerMeta: { - startEntropy: "startEntropyString", - startingStats: { - strength: 10, - dexterity: 10, - vitality: 10, - intelligence: 10, - wisdom: 10, - charisma: 10, - luck: 10, + adventurerState: createBasicAdventurerState(1), + adventurerMeta: { + startEntropy: "startEntropyString", + startingStats: { + strength: 10, + dexterity: 10, + vitality: 10, + intelligence: 10, + wisdom: 10, + charisma: 10, + luck: 10, + }, + interfaceCamel: true, + name: 123456789, }, - interfaceCamel: true, - name: 123456789, - }, - revealBlock: 1000000, + revealBlock: 1000000, }; export const mockDiscoveredHealthEvent: EventTypes.DiscoveredHealthEvent = { - adventurerState: { - ...createBasicAdventurerState(1), - adventurer: { - ...createBasicAdventurerState(1).adventurer, - health: createBasicAdventurerState(1).adventurer.health + 20, + adventurerState: { + ...createBasicAdventurerState(1), + adventurer: { + ...createBasicAdventurerState(1).adventurer, + health: createBasicAdventurerState(1).adventurer.health + 20, + }, }, - }, - healthAmount: 20, + healthAmount: 20, }; export const mockDiscoveredGoldEvent: EventTypes.DiscoveredGoldEvent = { - adventurerState: { - ...createBasicAdventurerState(1), - adventurer: { - ...createBasicAdventurerState(1).adventurer, - gold: createBasicAdventurerState(1).adventurer.gold + 50, + adventurerState: { + ...createBasicAdventurerState(1), + adventurer: { + ...createBasicAdventurerState(1).adventurer, + gold: createBasicAdventurerState(1).adventurer.gold + 50, + }, }, - }, - goldAmount: 50, + goldAmount: 50, }; export const mockDiscoveredXPEvent: EventTypes.DiscoveredXPEvent = { - adventurerState: { - ...createBasicAdventurerState(1), - adventurer: { - ...createBasicAdventurerState(1).adventurer, - xp: createBasicAdventurerState(1).adventurer.xp + 100, + adventurerState: { + ...createBasicAdventurerState(1), + adventurer: { + ...createBasicAdventurerState(1).adventurer, + xp: createBasicAdventurerState(1).adventurer.xp + 100, + }, }, - }, - xpAmount: 100, + xpAmount: 100, }; export const mockDiscoveredLootEvent: EventTypes.DiscoveredLootEvent = { - adventurerState: createBasicAdventurerState(1), - itemId: 5, + adventurerState: createBasicAdventurerState(1), + itemId: 5, }; export const mockEquipmentChangedEvent: EventTypes.EquipmentChangedEvent = { - adventurerStateWithBag: { - adventurerState: { - ...createBasicAdventurerState(1), - adventurer: { - ...createBasicAdventurerState(1).adventurer, - equipment: { - ...createBasicAdventurerState(1).adventurer.equipment, - weapon: { id: 1, xp: 0 }, - chest: { id: 2, xp: 0 }, - head: { id: 3, xp: 0 }, + adventurerStateWithBag: { + adventurerState: { + ...createBasicAdventurerState(1), + adventurer: { + ...createBasicAdventurerState(1).adventurer, + equipment: { + ...createBasicAdventurerState(1).adventurer.equipment, + weapon: { id: 1, xp: 0 }, + chest: { id: 2, xp: 0 }, + head: { id: 3, xp: 0 }, + }, + }, + }, + bag: { + ...createBagState([1, 2, 3, 4]), + item1: { id: 4, xp: 0 }, + item2: { id: 5, xp: 0 }, }, - }, - }, - bag: { - ...createBagState([1, 2, 3, 4]), - item1: { id: 4, xp: 0 }, - item2: { id: 5, xp: 0 }, }, - }, - equippedItems: [1, 2, 3], - baggedItems: [4, 5], - droppedItems: [6, 7], + equippedItems: [1, 2, 3], + baggedItems: [4, 5], + droppedItems: [6, 7], }; export const mockDodgedObstacleEvent: EventTypes.DodgedObstacleEvent = { - adventurerState: createBasicAdventurerState(1), - id: 3, - level: 2, - damageTaken: 5, - damageLocation: 1, - xpEarnedAdventurer: 10, - xpEarnedItems: 5, + adventurerState: createBasicAdventurerState(1), + id: 3, + level: 2, + damageTaken: 5, + damageLocation: 1, + xpEarnedAdventurer: 10, + xpEarnedItems: 5, }; export const mockHitByObstacleEvent: EventTypes.HitByObstacleEvent = { - adventurerState: createBasicAdventurerState(1), - id: 4, - level: 3, - damageTaken: 15, - damageLocation: 2, - xpEarnedAdventurer: 20, - xpEarnedItems: 10, + adventurerState: createBasicAdventurerState(1), + id: 4, + level: 3, + damageTaken: 15, + damageLocation: 2, + xpEarnedAdventurer: 20, + xpEarnedItems: 10, }; export const mockAmbushedByBeastEvent: EventTypes.AmbushedByBeastEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 987654321, - id: 5, - beastSpecs: { - tier: EventTypes.Tier.T2, - itemType: EventTypes.Type.Blade_or_Hide, - level: 3, - specials: { special1: 1, special2: 2, special3: 3 }, - }, - damage: 15, - criticalHit: false, - location: 2, + adventurerState: createBasicAdventurerState(1), + seed: 987654321, + id: 5, + beastSpecs: { + tier: EventTypes.Tier.T2, + itemType: EventTypes.Type.Blade_or_Hide, + level: 3, + specials: { special1: 1, special2: 2, special3: 3 }, + }, + damage: 15, + criticalHit: false, + location: 2, }; export const mockDiscoveredBeastEvent: EventTypes.DiscoveredBeastEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 123456789, - id: 6, - beastSpecs: { - tier: EventTypes.Tier.T3, - itemType: EventTypes.Type.Magic_or_Cloth, - level: 4, - specials: { special1: 2, special2: 3, special3: 4 }, - }, + adventurerState: createBasicAdventurerState(1), + seed: 123456789, + id: 6, + beastSpecs: { + tier: EventTypes.Tier.T3, + itemType: EventTypes.Type.Magic_or_Cloth, + level: 4, + specials: { special1: 2, special2: 3, special3: 4 }, + }, }; export const mockAttackedBeastEvent: EventTypes.AttackedBeastEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 246813579, - id: 7, - beastSpecs: { - tier: EventTypes.Tier.T4, - itemType: EventTypes.Type.Bludgeon_or_Metal, - level: 5, - specials: { special1: 3, special2: 4, special3: 5 }, - }, - damage: 25, - criticalHit: true, - location: 3, + adventurerState: createBasicAdventurerState(1), + seed: 246813579, + id: 7, + beastSpecs: { + tier: EventTypes.Tier.T4, + itemType: EventTypes.Type.Bludgeon_or_Metal, + level: 5, + specials: { special1: 3, special2: 4, special3: 5 }, + }, + damage: 25, + criticalHit: true, + location: 3, }; export const mockAttackedByBeastEvent: EventTypes.AttackedByBeastEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 135792468, - id: 8, - beastSpecs: { - tier: EventTypes.Tier.T5, - itemType: EventTypes.Type.Necklace, - level: 6, - specials: { special1: 4, special2: 5, special3: 6 }, - }, - damage: 30, - criticalHit: false, - location: 4, + adventurerState: createBasicAdventurerState(1), + seed: 135792468, + id: 8, + beastSpecs: { + tier: EventTypes.Tier.T5, + itemType: EventTypes.Type.Necklace, + level: 6, + specials: { special1: 4, special2: 5, special3: 6 }, + }, + damage: 30, + criticalHit: false, + location: 4, }; export const mockSlayedBeastEvent: EventTypes.SlayedBeastEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 369258147, - id: 9, - beastSpecs: { - tier: EventTypes.Tier.T5, - itemType: EventTypes.Type.Ring, - level: 7, - specials: { special1: 5, special2: 6, special3: 7 }, - }, - damageDealt: 50, - criticalHit: true, - xpEarnedAdventurer: 200, - xpEarnedItems: 100, - goldEarned: 75, + adventurerState: createBasicAdventurerState(1), + seed: 369258147, + id: 9, + beastSpecs: { + tier: EventTypes.Tier.T5, + itemType: EventTypes.Type.Ring, + level: 7, + specials: { special1: 5, special2: 6, special3: 7 }, + }, + damageDealt: 50, + criticalHit: true, + xpEarnedAdventurer: 200, + xpEarnedItems: 100, + goldEarned: 75, }; export const mockFleeFailedEvent: EventTypes.FleeFailedEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 951753852, - id: 10, - beastSpecs: { - tier: EventTypes.Tier.T3, - itemType: EventTypes.Type.Blade_or_Hide, - level: 4, - specials: { special1: 2, special2: 3, special3: 4 }, - }, + adventurerState: createBasicAdventurerState(1), + seed: 951753852, + id: 10, + beastSpecs: { + tier: EventTypes.Tier.T3, + itemType: EventTypes.Type.Blade_or_Hide, + level: 4, + specials: { special1: 2, special2: 3, special3: 4 }, + }, }; export const mockFleeSucceededEvent: EventTypes.FleeSucceededEvent = { - adventurerState: createBasicAdventurerState(1), - seed: 753951852, - id: 11, - beastSpecs: { - tier: EventTypes.Tier.T4, - itemType: EventTypes.Type.Magic_or_Cloth, - level: 5, - specials: { special1: 3, special2: 4, special3: 5 }, - }, + adventurerState: createBasicAdventurerState(1), + seed: 753951852, + id: 11, + beastSpecs: { + tier: EventTypes.Tier.T4, + itemType: EventTypes.Type.Magic_or_Cloth, + level: 5, + specials: { special1: 3, special2: 4, special3: 5 }, + }, }; export const mockPurchasedItemsEvent: EventTypes.PurchasedItemsEvent = { - adventurerStateWithBag: { - adventurerState: createBasicAdventurerState(1), - bag: createBagState([1, 2]), // Add a proper bag structure if needed - }, - purchases: [ - { - item: { - id: 1, - tier: EventTypes.Tier.T1, - itemType: EventTypes.Type.Blade_or_Hide, - slot: EventTypes.Slot.Weapon, - }, - price: 100, - }, - { - item: { - id: 2, - tier: EventTypes.Tier.T2, - itemType: EventTypes.Type.Magic_or_Cloth, - slot: EventTypes.Slot.Chest, - }, - price: 150, + adventurerStateWithBag: { + adventurerState: createBasicAdventurerState(1), + bag: createBagState([1, 2]), // Add a proper bag structure if needed }, - ], + purchases: [ + { + item: { + id: 1, + tier: EventTypes.Tier.T1, + itemType: EventTypes.Type.Blade_or_Hide, + slot: EventTypes.Slot.Weapon, + }, + price: 100, + }, + { + item: { + id: 2, + tier: EventTypes.Tier.T2, + itemType: EventTypes.Type.Magic_or_Cloth, + slot: EventTypes.Slot.Chest, + }, + price: 150, + }, + ], }; export const mockPurchasedPotionsEvent: EventTypes.PurchasedPotionsEvent = { - adventurerState: createBasicAdventurerState(1), - quantity: 3, - cost: 75, - health: 50, + adventurerState: createBasicAdventurerState(1), + quantity: 3, + cost: 75, + health: 50, }; export const mockEquippedItemsEvent: EventTypes.EquippedItemsEvent = { - adventurerStateWithBag: { - adventurerState: createBasicAdventurerState(1), - bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed - }, - equippedItems: [1, 2, 3], - unequippedItems: [4, 5], + adventurerStateWithBag: { + adventurerState: createBasicAdventurerState(1), + bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed + }, + equippedItems: [1, 2, 3], + unequippedItems: [4, 5], }; export const mockDroppedItemsEvent: EventTypes.DroppedItemsEvent = { - adventurerStateWithBag: { - adventurerState: createBasicAdventurerState(1), - bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed - }, - itemIds: [6, 7, 8], + adventurerStateWithBag: { + adventurerState: createBasicAdventurerState(1), + bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed + }, + itemIds: [6, 7, 8], }; export const mockGreatnessIncreasedEvent: EventTypes.GreatnessIncreasedEvent = { - adventurerState: createBasicAdventurerState(1), - itemId: 3, - previousLevel: 2, - newLevel: 3, + adventurerState: createBasicAdventurerState(1), + itemId: 3, + previousLevel: 2, + newLevel: 3, }; export const mockItemsLeveledUpEvent: EventTypes.ItemsLeveledUpEvent = { - adventurerState: createBasicAdventurerState(1), - items: [ - { - itemId: 1, - previousLevel: 1, - newLevel: 2, - suffixUnlocked: true, - prefixesUnlocked: false, - specials: { special1: 1, special2: 2, special3: 3 }, - }, - { - itemId: 2, - previousLevel: 2, - newLevel: 3, - suffixUnlocked: false, - prefixesUnlocked: true, - specials: { special1: 2, special2: 3, special3: 4 }, - }, - ], + adventurerState: createBasicAdventurerState(1), + items: [ + { + itemId: 1, + previousLevel: 1, + newLevel: 2, + suffixUnlocked: true, + prefixesUnlocked: false, + specials: { special1: 1, special2: 2, special3: 3 }, + }, + { + itemId: 2, + previousLevel: 2, + newLevel: 3, + suffixUnlocked: false, + prefixesUnlocked: true, + specials: { special1: 2, special2: 3, special3: 4 }, + }, + ], }; export const mockNewHighScoreEvent: EventTypes.NewHighScoreEvent = { - adventurerState: createBasicAdventurerState(1), - rank: 5, + adventurerState: createBasicAdventurerState(1), + rank: 5, }; export const mockAdventurerDiedEvent: EventTypes.AdventurerDiedEvent = { - adventurerState: createBasicAdventurerState(1), - killedByBeast: 7, - killedByObstacle: 0, - callerAddress: "0x9876543210987654321098765432109876543210", + adventurerState: createBasicAdventurerState(1), + killedByBeast: 7, + killedByObstacle: 0, + callerAddress: "0x9876543210987654321098765432109876543210", }; export const mockAdventurerLeveledUpEvent: EventTypes.AdventurerLeveledUpEvent = - { - adventurerState: createBasicAdventurerState(1), - previousLevel: 1, - newLevel: 2, - }; + { + adventurerState: createBasicAdventurerState(1), + previousLevel: 1, + newLevel: 2, + }; export const mockUpgradesAvailableEvent: EventTypes.UpgradesAvailableEvent = { - adventurerState: createBasicAdventurerState(1), - items: [1, 2, 3], + adventurerState: createBasicAdventurerState(1), + items: [1, 2, 3], }; export const mockAdventurerUpgradedEvent: EventTypes.AdventurerUpgradedEvent = { - adventurerStateWithBag: { - adventurerState: createBasicAdventurerState(1), - bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed - }, - strengthIncrease: 1, - dexterityIncrease: 1, - vitalityIncrease: 1, - intelligenceIncrease: 1, - wisdomIncrease: 1, - charismaIncrease: 1, + adventurerStateWithBag: { + adventurerState: createBasicAdventurerState(1), + bag: createBagState([1, 2, 3]), // Add a proper bag structure if needed + }, + strengthIncrease: 1, + dexterityIncrease: 1, + vitalityIncrease: 1, + intelligenceIncrease: 1, + wisdomIncrease: 1, + charismaIncrease: 1, }; export const mockERC721TransferEvent: EventTypes.ERC721TransferEvent = { - from: "0x1111111111111111111111111111111111111111", - to: "0x2222222222222222222222222222222222222222", - tokenId: { low: 123, high: 0 }, + from: "0x1111111111111111111111111111111111111111", + to: "0x2222222222222222222222222222222222222222", + tokenId: { low: 123, high: 0 }, }; export const encodedMockStartGameEvent = encodeEventData(mockStartGameEvent); export const encodedMockDiscoveredHealthEvent = encodeEventData( - mockDiscoveredHealthEvent + mockDiscoveredHealthEvent ); export const encodedMockDiscoveredGoldEvent = encodeEventData( - mockDiscoveredGoldEvent + mockDiscoveredGoldEvent ); export const encodedMockDiscoveredXPEvent = encodeEventData( - mockDiscoveredXPEvent + mockDiscoveredXPEvent ); export const encodedMockDiscoveredLootEvent = encodeEventData( - mockDiscoveredLootEvent + mockDiscoveredLootEvent ); export const encodedMockEquipmentChangedEvent = encodeEventData( - mockEquipmentChangedEvent + mockEquipmentChangedEvent ); export const encodedMockDodgedObstacleEvent = encodeEventData( - mockDodgedObstacleEvent + mockDodgedObstacleEvent ); export const encodedMockHitByObstacleEvent = encodeEventData( - mockHitByObstacleEvent + mockHitByObstacleEvent ); export const encodedMockAmbushedByBeastEvent = encodeEventData( - mockAmbushedByBeastEvent + mockAmbushedByBeastEvent ); export const encodedMockDiscoveredBeastEvent = encodeEventData( - mockDiscoveredBeastEvent + mockDiscoveredBeastEvent ); export const encodedMockAttackedBeastEvent = encodeEventData( - mockAttackedBeastEvent + mockAttackedBeastEvent ); export const encodedMockAttackedByBeastEvent = encodeEventData( - mockAttackedByBeastEvent + mockAttackedByBeastEvent ); export const encodedMockSlayedBeastEvent = - encodeEventData(mockSlayedBeastEvent); + encodeEventData(mockSlayedBeastEvent); export const encodedMockFleeFailedEvent = encodeEventData(mockFleeFailedEvent); export const encodedMockFleeSucceededEvent = encodeEventData( - mockFleeSucceededEvent + mockFleeSucceededEvent ); export const encodedMockPurchasedItemsEvent = encodeEventData( - mockPurchasedItemsEvent + mockPurchasedItemsEvent ); export const encodedMockPurchasedPotionsEvent = encodeEventData( - mockPurchasedPotionsEvent + mockPurchasedPotionsEvent ); export const encodedMockEquippedItemsEvent = encodeEventData( - mockEquippedItemsEvent + mockEquippedItemsEvent ); export const encodedMockDroppedItemsEvent = encodeEventData( - mockDroppedItemsEvent + mockDroppedItemsEvent ); export const encodedMockGreatnessIncreasedEvent = encodeEventData( - mockGreatnessIncreasedEvent + mockGreatnessIncreasedEvent ); export const encodedMockItemsLeveledUpEvent = encodeEventData( - mockItemsLeveledUpEvent + mockItemsLeveledUpEvent ); export const encodedMockNewHighScoreEvent = encodeEventData( - mockNewHighScoreEvent + mockNewHighScoreEvent ); export const encodedMockAdventurerDiedEvent = encodeEventData( - mockAdventurerDiedEvent + mockAdventurerDiedEvent ); export const encodedMockAdventurerLeveledUpEvent = encodeEventData( - mockAdventurerLeveledUpEvent + mockAdventurerLeveledUpEvent ); export const encodedMockUpgradesAvailableEvent = encodeEventData( - mockUpgradesAvailableEvent + mockUpgradesAvailableEvent ); export const encodedMockAdventurerUpgradedEvent = encodeEventData( - mockAdventurerUpgradedEvent + mockAdventurerUpgradedEvent ); export const encodedMockERC721TransferEvent = encodeEventData( - mockERC721TransferEvent + mockERC721TransferEvent ); diff --git a/packages/core/src/state/state.test.ts b/packages/core/src/state/state.test.ts index 05def26..fa12f9b 100644 --- a/packages/core/src/state/state.test.ts +++ b/packages/core/src/state/state.test.ts @@ -1,11 +1,11 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; import { - formatBeastData, - parseAdventurerMeta, - parseAdventurerState, - parseBag, - parseStartGameEvent, + formatBeastData, + parseAdventurerMeta, + parseAdventurerState, + parseBag, + parseStartGameEvent, } from "./format"; import * as mockEvents from "./mock"; @@ -13,554 +13,554 @@ import { useSurvivorStore } from "."; import { Survivor } from "../objects/survivor"; describe("updateState with events", () => { - beforeEach(() => { - useSurvivorStore.setState({ survivor: new Survivor() }); - }); + beforeEach(() => { + useSurvivorStore.setState({ survivor: new Survivor() }); + }); - it("should update state with StartGameEvent", () => { - const { survivor } = useSurvivorStore.getState(); + it("should update state with StartGameEvent", () => { + const { survivor } = useSurvivorStore.getState(); - survivor?.updateFromEvent( - parseStartGameEvent(mockEvents.encodedMockStartGameEvent) - ); + survivor?.updateFromEvent( + parseStartGameEvent(mockEvents.encodedMockStartGameEvent) + ); - const updatedState = useSurvivorStore.getState().survivor; + const updatedState = useSurvivorStore.getState().survivor; - expect(updatedState?.name).toEqual( - parseStartGameEvent(mockEvents.encodedMockStartGameEvent).event - .adventurerMeta.name - ); + expect(updatedState?.name).toEqual( + parseStartGameEvent(mockEvents.encodedMockStartGameEvent).event + .adventurerMeta.name + ); - expect(updatedState?.gold).toEqual( - parseStartGameEvent(mockEvents.encodedMockStartGameEvent).event - .adventurerState.adventurer.gold - ); - }); - // it("should update health with DiscoveredHealthEvent", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredHealthEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update gold with DiscoveredGoldEvent", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredGoldEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer?.gold).toEqual( - // adventurerState.adventurer.gold - // ); - // }); - // it("should update XP with DiscoveredXPEvent", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredXPEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer?.xp).toEqual(adventurerState.adventurer.xp); - // }); - // it("should update adventurer state after discovering loot", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredLootEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after equipment change", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockEquipmentChangedEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after dodging obstacle", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDodgedObstacleEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after being hit by obstacle", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockHitByObstacleEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after being ambushed by beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAmbushedByBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after discovering a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after attacking a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAttackedBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after being attacked by a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAttackedByBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after slaying a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockSlayedBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after failing to flee", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockFleeFailedEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after successfully fleeing", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockFleeSucceededEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after purchasing items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockPurchasedItemsEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after purchasing potions", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockPurchasedPotionsEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after equipping items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockEquippedItemsEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after dropping items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDroppedItemsEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after greatness increase", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockGreatnessIncreasedEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after items level up", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockItemsLeveledUpEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after achieving new high score", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockNewHighScoreEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after adventurer dies", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAdventurerDiedEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after leveling up", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAdventurerLeveledUpEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state when upgrades are available", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockUpgradesAvailableEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state after upgrading", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAdventurerUpgradedEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // }); - // it("should update adventurer state and bag after equipment change", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockEquipmentChangedEvent.slice(0, 31) - // ); - // const bag = parseBag( - // mockEvents.encodedMockEquipmentChangedEvent.slice(31, 62) - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // bag, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.bag).toEqual(bag); - // }); - // it("should update adventurer state and bag after purchasing items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockPurchasedItemsEvent.slice(0, 31) - // ); - // const bag = parseBag( - // mockEvents.encodedMockPurchasedItemsEvent.slice(31, 62) - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // bag, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.bag).toEqual(bag); - // }); - // it("should update adventurer state and bag after equipping items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockEquippedItemsEvent.slice(0, 31) - // ); - // const bag = parseBag( - // mockEvents.encodedMockEquippedItemsEvent.slice(31, 62) - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // bag, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.bag).toEqual(bag); - // }); - // it("should update adventurer state and bag after dropping items", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDroppedItemsEvent.slice(0, 31) - // ); - // const bag = parseBag(mockEvents.encodedMockDroppedItemsEvent.slice(31, 62)); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // bag, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.bag).toEqual(bag); - // }); - // it("should update adventurer state and bag after upgrading", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAdventurerUpgradedEvent.slice(0, 31) - // ); - // const bag = parseBag( - // mockEvents.encodedMockAdventurerUpgradedEvent.slice(31, 62) - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // bag, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.bag).toEqual(bag); - // }); - // it("should update beast state when discovering a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockDiscoveredBeastEvent - // ); - // const formattedBeast = formatBeastData(mockEvents.mockDiscoveredBeastEvent); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // beast: formattedBeast, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.beast).toEqual(formattedBeast); - // }); - // it("should update beast state when ambushed by a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAmbushedByBeastEvent - // ); - // const formattedBeast = formatBeastData(mockEvents.mockAmbushedByBeastEvent); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // beast: formattedBeast, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.beast).toEqual(formattedBeast); - // }); - // it("should update beast state when attacking a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockAttackedBeastEvent - // ); - // const formattedBeast = formatBeastData(mockEvents.mockAttackedBeastEvent); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // beast: formattedBeast, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.beast).toEqual(formattedBeast); - // }); - // it("should clear beast state when slaying a beast", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockSlayedBeastEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // beast: undefined, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.beast).toBeUndefined(); - // }); - // it("should clear beast state when successfully fleeing", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const adventurerState = parseAdventurerState( - // mockEvents.encodedMockFleeSucceededEvent - // ); - // updateGameState({ - // adventurer: adventurerState.adventurer, - // beast: undefined, - // }); - // const updatedState = useGameStateStore.getState().gameState; - // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); - // expect(updatedState.beast).toBeUndefined(); - // }); - // }); - // describe("updateState with multiple sequential events", () => { - // beforeEach(() => { - // useGameStateStore.setState({ gameState: {} }); - // }); - // it("should correctly update state after a sequence of events", () => { - // const { updateGameState } = useGameStateStore.getState(); - // const getState = () => useGameStateStore.getState().gameState; - // // Start game - // const initialAdventurer = - // mockEvents.mockStartGameEvent.adventurerState.adventurer; - // updateGameState({ adventurer: initialAdventurer }); - // expect(getState().adventurer).toEqual(initialAdventurer); - // // Discover gold - // const goldEvent = mockEvents.mockDiscoveredGoldEvent; - // updateGameState({ - // adventurer: { - // ...getState().adventurer!, - // gold: (getState().adventurer?.gold || 0) + goldEvent.goldAmount, - // }, - // }); - // expect(getState().adventurer?.gold).toEqual( - // initialAdventurer.gold + goldEvent.goldAmount - // ); - // // Discover XP - // const xpEvent = mockEvents.mockDiscoveredXPEvent; - // updateGameState({ - // adventurer: { - // ...getState().adventurer!, - // xp: (getState().adventurer?.xp || 0) + xpEvent.xpAmount, - // }, - // }); - // expect(getState().adventurer?.xp).toEqual( - // initialAdventurer.xp + xpEvent.xpAmount - // ); - // // Encounter a beast - // const beastEvent = mockEvents.mockDiscoveredBeastEvent; - // const beast = formatBeastData(beastEvent); - // updateGameState({ beast }); - // expect(getState().beast).toEqual(beast); - // // Attack the beast - // const attackEvent = mockEvents.mockAttackedBeastEvent; - // updateGameState({ - // adventurer: { - // ...getState().adventurer!, - // beastHealth: beast.health - attackEvent.damage, - // }, - // beast: { - // ...getState().beast!, - // health: beast.health - attackEvent.damage, - // }, - // }); - // expect(getState().adventurer?.beastHealth).toEqual( - // beast.health - attackEvent.damage - // ); - // expect(getState().beast?.health).toEqual(beast.health - attackEvent.damage); - // // Slay the beast - // const slayEvent = mockEvents.mockSlayedBeastEvent; - // updateGameState({ - // adventurer: { - // ...getState().adventurer!, - // gold: (getState().adventurer?.gold || 0) + slayEvent.goldEarned, - // xp: (getState().adventurer?.xp || 0) + slayEvent.xpEarnedAdventurer, - // beastHealth: 0, - // }, - // beast: undefined, - // }); - // expect(getState().adventurer?.gold).toEqual( - // initialAdventurer.gold + goldEvent.goldAmount + slayEvent.goldEarned - // ); - // expect(getState().adventurer?.xp).toEqual( - // initialAdventurer.xp + xpEvent.xpAmount + slayEvent.xpEarnedAdventurer - // ); - // expect(getState().adventurer?.beastHealth).toEqual(0); - // expect(getState().beast).toBeUndefined(); - // // Level up - // const levelUpEvent = mockEvents.mockAdventurerUpgradedEvent; - // updateGameState({ - // adventurer: - // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer, - // }); - // const finalState = getState().adventurer; - // expect(finalState?.stats).toEqual( - // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer.stats - // ); - // expect(finalState?.statUpgradesAvailable).toEqual( - // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer - // .statUpgradesAvailable - // ); - // // TODO: e2e test. We need to increment the mock data to include the next event - // // // Final state check - // // expect(finalState).toMatchObject({ - // // gold: - // // initialAdventurer.gold + goldEvent.goldAmount + slayEvent.goldEarned, - // // xp: - // // initialAdventurer.xp + xpEvent.xpAmount + slayEvent.xpEarnedAdventurer, - // // beastHealth: 0, - // // stats: - // // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer.stats, - // // statUpgradesAvailable: - // // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer - // // .statUpgradesAvailable, - // // }); - // }); + expect(updatedState?.gold).toEqual( + parseStartGameEvent(mockEvents.encodedMockStartGameEvent).event + .adventurerState.adventurer.gold + ); + }); + // it("should update health with DiscoveredHealthEvent", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredHealthEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update gold with DiscoveredGoldEvent", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredGoldEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer?.gold).toEqual( + // adventurerState.adventurer.gold + // ); + // }); + // it("should update XP with DiscoveredXPEvent", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredXPEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer?.xp).toEqual(adventurerState.adventurer.xp); + // }); + // it("should update adventurer state after discovering loot", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredLootEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after equipment change", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockEquipmentChangedEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after dodging obstacle", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDodgedObstacleEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after being hit by obstacle", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockHitByObstacleEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after being ambushed by beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAmbushedByBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after discovering a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after attacking a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAttackedBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after being attacked by a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAttackedByBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after slaying a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockSlayedBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after failing to flee", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockFleeFailedEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after successfully fleeing", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockFleeSucceededEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after purchasing items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockPurchasedItemsEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after purchasing potions", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockPurchasedPotionsEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after equipping items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockEquippedItemsEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after dropping items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDroppedItemsEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after greatness increase", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockGreatnessIncreasedEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after items level up", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockItemsLeveledUpEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after achieving new high score", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockNewHighScoreEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after adventurer dies", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAdventurerDiedEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after leveling up", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAdventurerLeveledUpEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state when upgrades are available", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockUpgradesAvailableEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state after upgrading", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAdventurerUpgradedEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // }); + // it("should update adventurer state and bag after equipment change", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockEquipmentChangedEvent.slice(0, 31) + // ); + // const bag = parseBag( + // mockEvents.encodedMockEquipmentChangedEvent.slice(31, 62) + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // bag, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.bag).toEqual(bag); + // }); + // it("should update adventurer state and bag after purchasing items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockPurchasedItemsEvent.slice(0, 31) + // ); + // const bag = parseBag( + // mockEvents.encodedMockPurchasedItemsEvent.slice(31, 62) + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // bag, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.bag).toEqual(bag); + // }); + // it("should update adventurer state and bag after equipping items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockEquippedItemsEvent.slice(0, 31) + // ); + // const bag = parseBag( + // mockEvents.encodedMockEquippedItemsEvent.slice(31, 62) + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // bag, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.bag).toEqual(bag); + // }); + // it("should update adventurer state and bag after dropping items", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDroppedItemsEvent.slice(0, 31) + // ); + // const bag = parseBag(mockEvents.encodedMockDroppedItemsEvent.slice(31, 62)); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // bag, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.bag).toEqual(bag); + // }); + // it("should update adventurer state and bag after upgrading", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAdventurerUpgradedEvent.slice(0, 31) + // ); + // const bag = parseBag( + // mockEvents.encodedMockAdventurerUpgradedEvent.slice(31, 62) + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // bag, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.bag).toEqual(bag); + // }); + // it("should update beast state when discovering a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockDiscoveredBeastEvent + // ); + // const formattedBeast = formatBeastData(mockEvents.mockDiscoveredBeastEvent); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // beast: formattedBeast, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.beast).toEqual(formattedBeast); + // }); + // it("should update beast state when ambushed by a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAmbushedByBeastEvent + // ); + // const formattedBeast = formatBeastData(mockEvents.mockAmbushedByBeastEvent); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // beast: formattedBeast, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.beast).toEqual(formattedBeast); + // }); + // it("should update beast state when attacking a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockAttackedBeastEvent + // ); + // const formattedBeast = formatBeastData(mockEvents.mockAttackedBeastEvent); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // beast: formattedBeast, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.beast).toEqual(formattedBeast); + // }); + // it("should clear beast state when slaying a beast", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockSlayedBeastEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // beast: undefined, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.beast).toBeUndefined(); + // }); + // it("should clear beast state when successfully fleeing", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const adventurerState = parseAdventurerState( + // mockEvents.encodedMockFleeSucceededEvent + // ); + // updateGameState({ + // adventurer: adventurerState.adventurer, + // beast: undefined, + // }); + // const updatedState = useGameStateStore.getState().gameState; + // expect(updatedState.adventurer).toEqual(adventurerState.adventurer); + // expect(updatedState.beast).toBeUndefined(); + // }); + // }); + // describe("updateState with multiple sequential events", () => { + // beforeEach(() => { + // useGameStateStore.setState({ gameState: {} }); + // }); + // it("should correctly update state after a sequence of events", () => { + // const { updateGameState } = useGameStateStore.getState(); + // const getState = () => useGameStateStore.getState().gameState; + // // Start game + // const initialAdventurer = + // mockEvents.mockStartGameEvent.adventurerState.adventurer; + // updateGameState({ adventurer: initialAdventurer }); + // expect(getState().adventurer).toEqual(initialAdventurer); + // // Discover gold + // const goldEvent = mockEvents.mockDiscoveredGoldEvent; + // updateGameState({ + // adventurer: { + // ...getState().adventurer!, + // gold: (getState().adventurer?.gold || 0) + goldEvent.goldAmount, + // }, + // }); + // expect(getState().adventurer?.gold).toEqual( + // initialAdventurer.gold + goldEvent.goldAmount + // ); + // // Discover XP + // const xpEvent = mockEvents.mockDiscoveredXPEvent; + // updateGameState({ + // adventurer: { + // ...getState().adventurer!, + // xp: (getState().adventurer?.xp || 0) + xpEvent.xpAmount, + // }, + // }); + // expect(getState().adventurer?.xp).toEqual( + // initialAdventurer.xp + xpEvent.xpAmount + // ); + // // Encounter a beast + // const beastEvent = mockEvents.mockDiscoveredBeastEvent; + // const beast = formatBeastData(beastEvent); + // updateGameState({ beast }); + // expect(getState().beast).toEqual(beast); + // // Attack the beast + // const attackEvent = mockEvents.mockAttackedBeastEvent; + // updateGameState({ + // adventurer: { + // ...getState().adventurer!, + // beastHealth: beast.health - attackEvent.damage, + // }, + // beast: { + // ...getState().beast!, + // health: beast.health - attackEvent.damage, + // }, + // }); + // expect(getState().adventurer?.beastHealth).toEqual( + // beast.health - attackEvent.damage + // ); + // expect(getState().beast?.health).toEqual(beast.health - attackEvent.damage); + // // Slay the beast + // const slayEvent = mockEvents.mockSlayedBeastEvent; + // updateGameState({ + // adventurer: { + // ...getState().adventurer!, + // gold: (getState().adventurer?.gold || 0) + slayEvent.goldEarned, + // xp: (getState().adventurer?.xp || 0) + slayEvent.xpEarnedAdventurer, + // beastHealth: 0, + // }, + // beast: undefined, + // }); + // expect(getState().adventurer?.gold).toEqual( + // initialAdventurer.gold + goldEvent.goldAmount + slayEvent.goldEarned + // ); + // expect(getState().adventurer?.xp).toEqual( + // initialAdventurer.xp + xpEvent.xpAmount + slayEvent.xpEarnedAdventurer + // ); + // expect(getState().adventurer?.beastHealth).toEqual(0); + // expect(getState().beast).toBeUndefined(); + // // Level up + // const levelUpEvent = mockEvents.mockAdventurerUpgradedEvent; + // updateGameState({ + // adventurer: + // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer, + // }); + // const finalState = getState().adventurer; + // expect(finalState?.stats).toEqual( + // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer.stats + // ); + // expect(finalState?.statUpgradesAvailable).toEqual( + // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer + // .statUpgradesAvailable + // ); + // // TODO: e2e test. We need to increment the mock data to include the next event + // // // Final state check + // // expect(finalState).toMatchObject({ + // // gold: + // // initialAdventurer.gold + goldEvent.goldAmount + slayEvent.goldEarned, + // // xp: + // // initialAdventurer.xp + xpEvent.xpAmount + slayEvent.xpEarnedAdventurer, + // // beastHealth: 0, + // // stats: + // // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer.stats, + // // statUpgradesAvailable: + // // levelUpEvent.adventurerStateWithBag.adventurerState.adventurer + // // .statUpgradesAvailable, + // // }); + // }); }); diff --git a/packages/core/src/type/events.ts b/packages/core/src/type/events.ts index 09f616f..ec1d51f 100644 --- a/packages/core/src/type/events.ts +++ b/packages/core/src/type/events.ts @@ -1,6 +1,6 @@ export type u256 = { - low: u128; - high: u128; + low: u128; + high: u128; }; export type u128 = number; @@ -9,333 +9,333 @@ export type u16 = number; export type u8 = number; export type AdventurerMetadata = { - startEntropy: string; - startingStats: Stats; - interfaceCamel: boolean; - name: u128; + startEntropy: string; + startingStats: Stats; + interfaceCamel: boolean; + name: u128; }; export type Stats = { - strength: u8; - dexterity: u8; - vitality: u8; - intelligence: u8; - wisdom: u8; - charisma: u8; - luck: u8; + strength: u8; + dexterity: u8; + vitality: u8; + intelligence: u8; + wisdom: u8; + charisma: u8; + luck: u8; }; export type Equipment = { - weapon: LootStatistics; - chest: LootStatistics; - head: LootStatistics; - waist: LootStatistics; - foot: LootStatistics; - hand: LootStatistics; - neck: LootStatistics; - ring: LootStatistics; + weapon: LootStatistics; + chest: LootStatistics; + head: LootStatistics; + waist: LootStatistics; + foot: LootStatistics; + hand: LootStatistics; + neck: LootStatistics; + ring: LootStatistics; }; export type LootStatistics = { - id: u8; - xp: u16; + id: u8; + xp: u16; }; export type Adventurer = { - health: u16; - xp: u16; - gold: u16; - beastHealth: u16; - statUpgradesAvailable: u8; - stats: Stats; - equipment: Equipment; - mutated: boolean; + health: u16; + xp: u16; + gold: u16; + beastHealth: u16; + statUpgradesAvailable: u8; + stats: Stats; + equipment: Equipment; + mutated: boolean; }; export type Bag = { - item1: LootStatistics; - item2: LootStatistics; - item3: LootStatistics; - item4: LootStatistics; - item5: LootStatistics; - item6: LootStatistics; - item7: LootStatistics; - item8: LootStatistics; - item9: LootStatistics; - item10: LootStatistics; - item11: LootStatistics; - item12: LootStatistics; - item13: LootStatistics; - item14: LootStatistics; - item15: LootStatistics; - mutated: boolean; + item1: LootStatistics; + item2: LootStatistics; + item3: LootStatistics; + item4: LootStatistics; + item5: LootStatistics; + item6: LootStatistics; + item7: LootStatistics; + item8: LootStatistics; + item9: LootStatistics; + item10: LootStatistics; + item11: LootStatistics; + item12: LootStatistics; + item13: LootStatistics; + item14: LootStatistics; + item15: LootStatistics; + mutated: boolean; }; export type LootWithPrice = { - item: Loot; - price: u16; + item: Loot; + price: u16; }; export enum Tier { - None, - T1, - T2, - T3, - T4, - T5, + None, + T1, + T2, + T3, + T4, + T5, } export enum Slot { - None, - Weapon, - Chest, - Head, - Waist, - Foot, - Hand, - Neck, - Ring, + None, + Weapon, + Chest, + Head, + Waist, + Foot, + Hand, + Neck, + Ring, } export enum Type { - None, - Magic_or_Cloth, - Blade_or_Hide, - Bludgeon_or_Metal, - Necklace, - Ring, + None, + Magic_or_Cloth, + Blade_or_Hide, + Bludgeon_or_Metal, + Necklace, + Ring, } export type Loot = { - id: u8; - tier: Tier; - itemType: Type; - slot: Slot; + id: u8; + tier: Tier; + itemType: Type; + slot: Slot; }; export type ContractAddress = string; export type AdventurerState = { - owner: ContractAddress; - adventurerId: u128; - adventurerEntropy: string; - adventurer: Adventurer; + owner: ContractAddress; + adventurerId: u128; + adventurerEntropy: string; + adventurer: Adventurer; }; export type SpecialPowers = { - special1: u8; - special2: u8; - special3: u8; + special1: u8; + special2: u8; + special3: u8; }; export type CombatSpec = { - tier: Tier; - itemType: Type; - level: u16; - specials: SpecialPowers; + tier: Tier; + itemType: Type; + level: u16; + specials: SpecialPowers; }; export type AdventurerStateWithBag = { - adventurerState: AdventurerState; - bag: Bag; + adventurerState: AdventurerState; + bag: Bag; }; // Events export type StartGameEvent = { - adventurerState: AdventurerState; - adventurerMeta: AdventurerMetadata; - revealBlock: u64; + adventurerState: AdventurerState; + adventurerMeta: AdventurerMetadata; + revealBlock: u64; }; export type DiscoveredHealthEvent = { - adventurerState: AdventurerState; - healthAmount: u16; + adventurerState: AdventurerState; + healthAmount: u16; }; export type DiscoveredGoldEvent = { - adventurerState: AdventurerState; - goldAmount: u16; + adventurerState: AdventurerState; + goldAmount: u16; }; export type DiscoveredXPEvent = { - adventurerState: AdventurerState; - xpAmount: u16; + adventurerState: AdventurerState; + xpAmount: u16; }; export type DiscoveredLootEvent = { - adventurerState: AdventurerState; - itemId: u16; + adventurerState: AdventurerState; + itemId: u16; }; export type EquipmentChangedEvent = { - adventurerStateWithBag: AdventurerStateWithBag; - equippedItems: u8[]; - baggedItems: u8[]; - droppedItems: u8[]; + adventurerStateWithBag: AdventurerStateWithBag; + equippedItems: u8[]; + baggedItems: u8[]; + droppedItems: u8[]; }; export type DodgedObstacleEvent = { - adventurerState: AdventurerState; - id: u8; - level: u16; - damageTaken: u16; - damageLocation: u8; - xpEarnedAdventurer: u16; - xpEarnedItems: u16; + adventurerState: AdventurerState; + id: u8; + level: u16; + damageTaken: u16; + damageLocation: u8; + xpEarnedAdventurer: u16; + xpEarnedItems: u16; }; export type HitByObstacleEvent = { - adventurerState: AdventurerState; - id: u8; - level: u16; - damageTaken: u16; - damageLocation: u8; - xpEarnedAdventurer: u16; - xpEarnedItems: u16; + adventurerState: AdventurerState; + id: u8; + level: u16; + damageTaken: u16; + damageLocation: u8; + xpEarnedAdventurer: u16; + xpEarnedItems: u16; }; export type AmbushedByBeastEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; - damage: u16; - criticalHit: boolean; - location: u8; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; + damage: u16; + criticalHit: boolean; + location: u8; }; export type DiscoveredBeastEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; }; export type AttackedBeastEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; - damage: u16; - criticalHit: boolean; - location: u8; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; + damage: u16; + criticalHit: boolean; + location: u8; }; export type AttackedByBeastEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; - damage: u16; - criticalHit: boolean; - location: u8; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; + damage: u16; + criticalHit: boolean; + location: u8; }; export type SlayedBeastEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; - damageDealt: u16; - criticalHit: boolean; - xpEarnedAdventurer: u16; - xpEarnedItems: u16; - goldEarned: u16; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; + damageDealt: u16; + criticalHit: boolean; + xpEarnedAdventurer: u16; + xpEarnedItems: u16; + goldEarned: u16; }; export type FleeFailedEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; }; export type FleeSucceededEvent = { - adventurerState: AdventurerState; - seed: u128; - id: u8; - beastSpecs: CombatSpec; + adventurerState: AdventurerState; + seed: u128; + id: u8; + beastSpecs: CombatSpec; }; export type PurchasedItemsEvent = { - adventurerStateWithBag: AdventurerStateWithBag; - purchases: LootWithPrice[]; + adventurerStateWithBag: AdventurerStateWithBag; + purchases: LootWithPrice[]; }; export type PurchasedPotionsEvent = { - adventurerState: AdventurerState; - quantity: u8; - cost: u16; - health: u16; + adventurerState: AdventurerState; + quantity: u8; + cost: u16; + health: u16; }; export type EquippedItemsEvent = { - adventurerStateWithBag: AdventurerStateWithBag; - equippedItems: u8[]; - unequippedItems: u8[]; + adventurerStateWithBag: AdventurerStateWithBag; + equippedItems: u8[]; + unequippedItems: u8[]; }; export type DroppedItemsEvent = { - adventurerStateWithBag: AdventurerStateWithBag; - itemIds: u8[]; + adventurerStateWithBag: AdventurerStateWithBag; + itemIds: u8[]; }; export type GreatnessIncreasedEvent = { - adventurerState: AdventurerState; - itemId: u8; - previousLevel: u8; - newLevel: u8; + adventurerState: AdventurerState; + itemId: u8; + previousLevel: u8; + newLevel: u8; }; export type ItemLeveledUp = { - itemId: u8; - previousLevel: u8; - newLevel: u8; - suffixUnlocked: boolean; - prefixesUnlocked: boolean; - specials: SpecialPowers; + itemId: u8; + previousLevel: u8; + newLevel: u8; + suffixUnlocked: boolean; + prefixesUnlocked: boolean; + specials: SpecialPowers; }; export type ItemsLeveledUpEvent = { - adventurerState: AdventurerState; - items: ItemLeveledUp[]; + adventurerState: AdventurerState; + items: ItemLeveledUp[]; }; export type NewHighScoreEvent = { - adventurerState: AdventurerState; - rank: u8; + adventurerState: AdventurerState; + rank: u8; }; export type AdventurerDiedEvent = { - adventurerState: AdventurerState; - killedByBeast: u8; - killedByObstacle: u8; - callerAddress: ContractAddress; + adventurerState: AdventurerState; + killedByBeast: u8; + killedByObstacle: u8; + callerAddress: ContractAddress; }; export type AdventurerLeveledUpEvent = { - adventurerState: AdventurerState; - previousLevel: u8; - newLevel: u8; + adventurerState: AdventurerState; + previousLevel: u8; + newLevel: u8; }; export type UpgradesAvailableEvent = { - adventurerState: AdventurerState; - items: number[]; + adventurerState: AdventurerState; + items: number[]; }; export type AdventurerUpgradedEvent = { - adventurerStateWithBag: AdventurerStateWithBag; - strengthIncrease: u8; - dexterityIncrease: u8; - vitalityIncrease: u8; - intelligenceIncrease: u8; - wisdomIncrease: u8; - charismaIncrease: u8; + adventurerStateWithBag: AdventurerStateWithBag; + strengthIncrease: u8; + dexterityIncrease: u8; + vitalityIncrease: u8; + intelligenceIncrease: u8; + wisdomIncrease: u8; + charismaIncrease: u8; }; export type ERC721TransferEvent = { - from: ContractAddress; - to: ContractAddress; - tokenId: u256; + from: ContractAddress; + to: ContractAddress; + tokenId: u256; }; diff --git a/packages/core/src/type/index.ts b/packages/core/src/type/index.ts index b83079d..59727b0 100644 --- a/packages/core/src/type/index.ts +++ b/packages/core/src/type/index.ts @@ -4,785 +4,790 @@ import { Adventurer, AdventurerMetadata, Bag } from "./events"; export * from "./events"; export interface Stats { - strength: number; - dexterity: number; - vitality: number; - intelligence: number; - wisdom: number; - charisma: number; - luck: number; + strength: number; + dexterity: number; + vitality: number; + intelligence: number; + wisdom: number; + charisma: number; + luck: number; } export interface ItemPurchase { - item_id: number; - equip: boolean; + item_id: number; + equip: boolean; } export type MulticallEntry = - | { - entrypoint: "new_game"; - calldata: [string, number, string, bigint, bigint]; - } - | { entrypoint: "explore"; calldata: [string, number] } - | { entrypoint: "attack"; calldata: [string, number] } - | { entrypoint: "flee"; calldata: [string, number] } - | { entrypoint: "equip"; calldata: [string, ...number[]] } - | { entrypoint: "drop"; calldata: [string, ...number[]] } - | { - entrypoint: "upgrade"; - calldata: [string, number, ...number[]]; - } - | { entrypoint: "update_cost_to_play"; calldata: [] }; + | { + entrypoint: "new_game"; + calldata: [string, number, string, bigint, bigint]; + } + | { entrypoint: "explore"; calldata: [string, number] } + | { entrypoint: "attack"; calldata: [string, number] } + | { entrypoint: "flee"; calldata: [string, number] } + | { entrypoint: "equip"; calldata: [string, ...number[]] } + | { entrypoint: "drop"; calldata: [string, ...number[]] } + | { + entrypoint: "upgrade"; + calldata: [string, number, ...number[]]; + } + | { entrypoint: "update_cost_to_play"; calldata: [] }; export interface Beast { - adventurerId: number; - beast: string; - createdTime: string; - health: number; - lastUpdatedTime: string; - level: number; - seed: string; - slainOnTime: string | null; - special1: number; - special2: number; - special3: number; - timestamp: string; + adventurerId: number; + beast: string; + createdTime: string; + health: number; + lastUpdatedTime: string; + level: number; + seed: string; + slainOnTime: string | null; + special1: number; + special2: number; + special3: number; + timestamp: string; } export interface BeastEncounter { - encounter: string; - id: bigint; - type: string; - tier: number; - level: number; - health: number; - location: string; - dodgeRoll: number; - nextXp: number; - specialName: string; - criticalMultiplier: number; - damage: number; + encounter: string; + id: bigint; + type: string; + tier: number; + level: number; + health: number; + location: string; + dodgeRoll: number; + nextXp: number; + specialName: string; + criticalMultiplier: number; + damage: number; } export interface Item { - slot: string; - item?: string; - type?: string; - xp?: number; - level?: number; - tier?: number; - cost?: number; - purchaseTime?: string; - equipped?: string; - special1?: string; - special2?: string; - special3?: string; + slot: string; + item?: string; + type?: string; + xp?: number; + level?: number; + tier?: number; + cost?: number; + purchaseTime?: string; + equipped?: string; + special1?: string; + special2?: string; + special3?: string; } export interface Encounter { - encounter: string; - id?: bigint; - type: string; - tier: string | number; - level?: number; - health?: number; - location?: string; - dodgeRoll?: number; - nextXp: number; - specialName?: string; - criticalMultiplier?: number; - damage?: number; + encounter: string; + id?: bigint; + type: string; + tier: string | number; + level?: number; + health?: number; + location?: string; + dodgeRoll?: number; + nextXp: number; + specialName?: string; + criticalMultiplier?: number; + damage?: number; } export interface CombatResult { - totalDamage: number; - isCriticalHit: boolean; + totalDamage: number; + isCriticalHit: boolean; } export interface BattleEvent { - type: string; - totalDamage: number; - isCriticalHit: boolean; - beastDamageType?: string; - location?: string; + type: string; + totalDamage: number; + isCriticalHit: boolean; + beastDamageType?: string; + location?: string; } export interface AdventurerComplete { - id: number; - beastHealth: number; - charisma: number; - chest: string; - createdTime: string; - dexterity: number; - entropy: string; - foot: string; - gold: number; - hand: string; - head: string; - health: number; - intelligence: number; - lastUpdatedTime: string; - luck: number; - name: string; - neck: string; - owner: string; - revealBlock: number; - ring: string; - startEntropy: string; - statUpgrades: number; - strength: number; - timestamp: string; - vitality: number; - waist: string; - weapon: string; - wisdom: number; - xp: number; + id: number; + beastHealth: number; + charisma: number; + chest: string; + createdTime: string; + dexterity: number; + entropy: string; + foot: string; + gold: number; + hand: string; + head: string; + health: number; + intelligence: number; + lastUpdatedTime: string; + luck: number; + name: string; + neck: string; + owner: string; + revealBlock: number; + ring: string; + startEntropy: string; + statUpgrades: number; + strength: number; + timestamp: string; + vitality: number; + waist: string; + weapon: string; + wisdom: number; + xp: number; } export interface Battle { - attacker: string; - adventurerId: number; - beast: string; - beastHealth: number; - beastLevel: number; - blockTime: string; - criticalHit: boolean; - damageDealt: number; - damageLocation: string; - damageTaken: number; - discoveryTime: string; - fled: boolean; - goldEarned: number; - seed: string; - special1: number; - special2: number; - special3: number; - timestamp: string; - txHash: string; - xpEarnedAdventurer: number; - xpEarnedItems: number; + attacker: string; + adventurerId: number; + beast: string; + beastHealth: number; + beastLevel: number; + blockTime: string; + criticalHit: boolean; + damageDealt: number; + damageLocation: string; + damageTaken: number; + discoveryTime: string; + fled: boolean; + goldEarned: number; + seed: string; + special1: number; + special2: number; + special3: number; + timestamp: string; + txHash: string; + xpEarnedAdventurer: number; + xpEarnedItems: number; } export interface Discovery { - adventurerHealth: number; - adventurerId: number; - ambushed: boolean; - damageLocation: string; - damageTaken: number; - discoveryTime: string; - discoveryType: string; - dodgedObstacle: boolean; - entity: string; - entityHealth: number; - entityLevel: number; - obstacle: string; - obstacleLevel: number; - outputAmount: number; - seed: string; - special1: number; - special2: number; - special3: number; - subDiscoveryType: string; - timestamp: string; - txHash: string; - xpEarnedAdventurer: number; - xpEarnedItems: number; + adventurerHealth: number; + adventurerId: number; + ambushed: boolean; + damageLocation: string; + damageTaken: number; + discoveryTime: string; + discoveryType: string; + dodgedObstacle: boolean; + entity: string; + entityHealth: number; + entityLevel: number; + obstacle: string; + obstacleLevel: number; + outputAmount: number; + seed: string; + special1: number; + special2: number; + special3: number; + subDiscoveryType: string; + timestamp: string; + txHash: string; + xpEarnedAdventurer: number; + xpEarnedItems: number; } export interface Score { - adventurerId: number; - timestamp: string; - totalPayout: number; + adventurerId: number; + timestamp: string; + totalPayout: number; } export interface GameState { - beast: Beast; - adventurer: Adventurer; - adventurerMetadata: AdventurerMetadata; - currentBattle: Battle; - lastDiscovery: Discovery; - bag: Bag; - revealBlock: number; + beast: Beast; + adventurer: Adventurer; + adventurerMetadata: AdventurerMetadata; + currentBattle: Battle; + lastDiscovery: Discovery; + bag: Bag; + revealBlock: number; } export enum Beasts { - Warlock = 1, - Typhon = 2, - Jiangshi = 3, - Anansi = 4, - Basilisk = 5, - Gorgon = 6, - Kitsune = 7, - Lich = 8, - Chimera = 9, - Wendigo = 10, - Rakshasa = 11, - Werewolf = 12, - Banshee = 13, - Draugr = 14, - Vampire = 15, - Goblin = 16, - Ghoul = 17, - Wraith = 18, - Sprite = 19, - Kappa = 20, - Fairy = 21, - Leprechaun = 22, - Kelpie = 23, - Pixie = 24, - Gnome = 25, - Griffin = 26, - Manticore = 27, - Phoenix = 28, - Dragon = 29, - Minotaur = 30, - Qilin = 31, - Ammit = 32, - Nue = 33, - Skinwalker = 34, - Chupacabra = 35, - Weretiger = 36, - Wyvern = 37, - Roc = 38, - Harpy = 39, - Pegasus = 40, - Hippogriff = 41, - Fenrir = 42, - Jaguar = 43, - Satori = 44, - DireWolf = 45, - Bear = 46, - Wolf = 47, - Mantis = 48, - Spider = 49, - Rat = 50, - Kraken = 51, - Colossus = 52, - Balrog = 53, - Leviathan = 54, - Tarrasque = 55, - Titan = 56, - Nephilim = 57, - Behemoth = 58, - Hydra = 59, - Juggernaut = 60, - Oni = 61, - Jotunn = 62, - Ettin = 63, - Cyclops = 64, - Giant = 65, - NemeanLion = 66, - Berserker = 67, - Yeti = 68, - Golem = 69, - Ent = 70, - Troll = 71, - Bigfoot = 72, - Ogre = 73, - Orc = 74, - Skeleton = 75, + Warlock = 1, + Typhon = 2, + Jiangshi = 3, + Anansi = 4, + Basilisk = 5, + Gorgon = 6, + Kitsune = 7, + Lich = 8, + Chimera = 9, + Wendigo = 10, + Rakshasa = 11, + Werewolf = 12, + Banshee = 13, + Draugr = 14, + Vampire = 15, + Goblin = 16, + Ghoul = 17, + Wraith = 18, + Sprite = 19, + Kappa = 20, + Fairy = 21, + Leprechaun = 22, + Kelpie = 23, + Pixie = 24, + Gnome = 25, + Griffin = 26, + Manticore = 27, + Phoenix = 28, + Dragon = 29, + Minotaur = 30, + Qilin = 31, + Ammit = 32, + Nue = 33, + Skinwalker = 34, + Chupacabra = 35, + Weretiger = 36, + Wyvern = 37, + Roc = 38, + Harpy = 39, + Pegasus = 40, + Hippogriff = 41, + Fenrir = 42, + Jaguar = 43, + Satori = 44, + DireWolf = 45, + Bear = 46, + Wolf = 47, + Mantis = 48, + Spider = 49, + Rat = 50, + Kraken = 51, + Colossus = 52, + Balrog = 53, + Leviathan = 54, + Tarrasque = 55, + Titan = 56, + Nephilim = 57, + Behemoth = 58, + Hydra = 59, + Juggernaut = 60, + Oni = 61, + Jotunn = 62, + Ettin = 63, + Cyclops = 64, + Giant = 65, + NemeanLion = 66, + Berserker = 67, + Yeti = 68, + Golem = 69, + Ent = 70, + Troll = 71, + Bigfoot = 72, + Ogre = 73, + Orc = 74, + Skeleton = 75, } export enum BeastType { - Magical = "Magical", - Hunter = "Hunter", - Brute = "Brute", + Magical = "Magical", + Hunter = "Hunter", + Brute = "Brute", } export enum AttackType { - Magic = "Magic", - Blade = "Blade", - Bludgeon = "Bludgeon", + Magic = "Magic", + Blade = "Blade", + Bludgeon = "Bludgeon", } export enum ArmorType { - Cloth = "Cloth", - Hide = "Hide", - Metal = "Metal", + Cloth = "Cloth", + Hide = "Hide", + Metal = "Metal", } export enum Loot { - Pendant = 1, - Necklace = 2, - Amulet = 3, - SilverRing = 4, - BronzeRing = 5, - PlatinumRing = 6, - TitaniumRing = 7, - GoldRing = 8, - GhostWand = 9, - GraveWand = 10, - BoneWand = 11, - Wand = 12, - Grimoire = 13, - Chronicle = 14, - Tome = 15, - Book = 16, - DivineRobe = 17, - SilkRobe = 18, - LinenRobe = 19, - Robe = 20, - Shirt = 21, - Crown = 22, - DivineHood = 23, - SilkHood = 24, - LinenHood = 25, - Hood = 26, - BrightsilkSash = 27, - SilkSash = 28, - WoolSash = 29, - LinenSash = 30, - Sash = 31, - DivineSlippers = 32, - SilkSlippers = 33, - WoolShoes = 34, - LinenShoes = 35, - Shoes = 36, - DivineGloves = 37, - SilkGloves = 38, - WoolGloves = 39, - LinenGloves = 40, - Gloves = 41, - Katana = 42, - Falchion = 43, - Scimitar = 44, - LongSword = 45, - ShortSword = 46, - DemonHusk = 47, - DragonskinArmor = 48, - StuddedLeatherArmor = 49, - HardLeatherArmor = 50, - LeatherArmor = 51, - DemonCrown = 52, - DragonsCrown = 53, - WarCap = 54, - LeatherCap = 55, - Cap = 56, - DemonhideBelt = 57, - DragonskinBelt = 58, - StuddedLeatherBelt = 59, - HardLeatherBelt = 60, - LeatherBelt = 61, - DemonhideBoots = 62, - DragonskinBoots = 63, - StuddedLeatherBoots = 64, - HardLeatherBoots = 65, - LeatherBoots = 66, - DemonsHands = 67, - DragonskinGloves = 68, - StuddedLeatherGloves = 69, - HardLeatherGloves = 70, - LeatherGloves = 71, - Warhammer = 72, - Quarterstaff = 73, - Maul = 74, - Mace = 75, - Club = 76, - HolyChestplate = 77, - OrnateChestplate = 78, - PlateMail = 79, - ChainMail = 80, - RingMail = 81, - AncientHelm = 82, - OrnateHelm = 83, - GreatHelm = 84, - FullHelm = 85, - Helm = 86, - OrnateBelt = 87, - WarBelt = 88, - PlatedBelt = 89, - MeshBelt = 90, - HeavyBelt = 91, - HolyGreaves = 92, - OrnateGreaves = 93, - Greaves = 94, - ChainBoots = 95, - HeavyBoots = 96, - HolyGauntlets = 97, - OrnateGauntlets = 98, - Gauntlets = 99, - ChainGloves = 100, - HeavyGloves = 101, + Pendant = 1, + Necklace = 2, + Amulet = 3, + SilverRing = 4, + BronzeRing = 5, + PlatinumRing = 6, + TitaniumRing = 7, + GoldRing = 8, + GhostWand = 9, + GraveWand = 10, + BoneWand = 11, + Wand = 12, + Grimoire = 13, + Chronicle = 14, + Tome = 15, + Book = 16, + DivineRobe = 17, + SilkRobe = 18, + LinenRobe = 19, + Robe = 20, + Shirt = 21, + Crown = 22, + DivineHood = 23, + SilkHood = 24, + LinenHood = 25, + Hood = 26, + BrightsilkSash = 27, + SilkSash = 28, + WoolSash = 29, + LinenSash = 30, + Sash = 31, + DivineSlippers = 32, + SilkSlippers = 33, + WoolShoes = 34, + LinenShoes = 35, + Shoes = 36, + DivineGloves = 37, + SilkGloves = 38, + WoolGloves = 39, + LinenGloves = 40, + Gloves = 41, + Katana = 42, + Falchion = 43, + Scimitar = 44, + LongSword = 45, + ShortSword = 46, + DemonHusk = 47, + DragonskinArmor = 48, + StuddedLeatherArmor = 49, + HardLeatherArmor = 50, + LeatherArmor = 51, + DemonCrown = 52, + DragonsCrown = 53, + WarCap = 54, + LeatherCap = 55, + Cap = 56, + DemonhideBelt = 57, + DragonskinBelt = 58, + StuddedLeatherBelt = 59, + HardLeatherBelt = 60, + LeatherBelt = 61, + DemonhideBoots = 62, + DragonskinBoots = 63, + StuddedLeatherBoots = 64, + HardLeatherBoots = 65, + LeatherBoots = 66, + DemonsHands = 67, + DragonskinGloves = 68, + StuddedLeatherGloves = 69, + HardLeatherGloves = 70, + LeatherGloves = 71, + Warhammer = 72, + Quarterstaff = 73, + Maul = 74, + Mace = 75, + Club = 76, + HolyChestplate = 77, + OrnateChestplate = 78, + PlateMail = 79, + ChainMail = 80, + RingMail = 81, + AncientHelm = 82, + OrnateHelm = 83, + GreatHelm = 84, + FullHelm = 85, + Helm = 86, + OrnateBelt = 87, + WarBelt = 88, + PlatedBelt = 89, + MeshBelt = 90, + HeavyBelt = 91, + HolyGreaves = 92, + OrnateGreaves = 93, + Greaves = 94, + ChainBoots = 95, + HeavyBoots = 96, + HolyGauntlets = 97, + OrnateGauntlets = 98, + Gauntlets = 99, + ChainGloves = 100, + HeavyGloves = 101, } export enum ItemType { - Necklace = "Necklace", - Ring = "Ring", - Magic = "Magic", - Cloth = "Cloth", - Blade = "Blade", - Hide = "Hide", - Bludgeon = "Bludgeon", - Metal = "Metal", + Necklace = "Necklace", + Ring = "Ring", + Magic = "Magic", + Cloth = "Cloth", + Blade = "Blade", + Hide = "Hide", + Bludgeon = "Bludgeon", + Metal = "Metal", } export enum ItemSlot { - Neck = "Neck", - Ring = "Ring", - Weapon = "Weapon", - Chest = "Chest", - Head = "Head", - Waist = "Waist", - Foot = "Foot", - Hand = "Hand", + Neck = "Neck", + Ring = "Ring", + Weapon = "Weapon", + Chest = "Chest", + Head = "Head", + Waist = "Waist", + Foot = "Foot", + Hand = "Hand", } export const ITEM_SLOT_TO_NUMBER: Record = { - [ItemSlot.Weapon]: 1, - [ItemSlot.Chest]: 2, - [ItemSlot.Head]: 3, - [ItemSlot.Waist]: 4, - [ItemSlot.Foot]: 5, - [ItemSlot.Hand]: 6, - [ItemSlot.Neck]: 7, - [ItemSlot.Ring]: 8, + [ItemSlot.Weapon]: 1, + [ItemSlot.Chest]: 2, + [ItemSlot.Head]: 3, + [ItemSlot.Waist]: 4, + [ItemSlot.Foot]: 5, + [ItemSlot.Hand]: 6, + [ItemSlot.Neck]: 7, + [ItemSlot.Ring]: 8, }; export const NUMBER_TO_ITEM_SLOT: Record = { - 1: ItemSlot.Weapon, - 2: ItemSlot.Chest, - 3: ItemSlot.Head, - 4: ItemSlot.Waist, - 5: ItemSlot.Foot, - 6: ItemSlot.Hand, - 7: ItemSlot.Neck, - 8: ItemSlot.Ring, + 1: ItemSlot.Weapon, + 2: ItemSlot.Chest, + 3: ItemSlot.Head, + 4: ItemSlot.Waist, + 5: ItemSlot.Foot, + 6: ItemSlot.Hand, + 7: ItemSlot.Neck, + 8: ItemSlot.Ring, }; export enum StatType { - Strength = 0, - Dexterity = 1, - Vitality = 2, - Intelligence = 3, - Wisdom = 4, - Charisma = 5, - Luck = 6, + Strength = 0, + Dexterity = 1, + Vitality = 2, + Intelligence = 3, + Wisdom = 4, + Charisma = 5, + Luck = 6, } export const STATS_ABBREVIATIONS: Record = { - [StatType.Strength]: "STR", - [StatType.Dexterity]: "DEX", - [StatType.Vitality]: "VIT", - [StatType.Intelligence]: "INT", - [StatType.Wisdom]: "WIS", - [StatType.Charisma]: "CHA", - [StatType.Luck]: "LUCK", + [StatType.Strength]: "STR", + [StatType.Dexterity]: "DEX", + [StatType.Vitality]: "VIT", + [StatType.Intelligence]: "INT", + [StatType.Wisdom]: "WIS", + [StatType.Charisma]: "CHA", + [StatType.Luck]: "LUCK", }; export enum Obstacles { - // Magical Obstacles - DemonicAlter = 1, - VortexOfDespair = 2, - EldritchBarrier = 3, - SoulTrap = 4, - PhantomVortex = 5, - EctoplasmicWeb = 6, - SpectralChains = 7, - InfernalPact = 8, - ArcaneExplosion = 9, - HypnoticEssence = 10, - MischievousSprites = 11, - SoulDrainingStatue = 12, - PetrifyingGaze = 13, - SummoningCircle = 14, - EtherealVoid = 15, - MagicLock = 16, - BewitchingFog = 17, - IllusionaryMaze = 18, - SpellboundMirror = 19, - EnsnaringShadow = 20, - DarkMist = 21, - Curse = 22, - HauntingEcho = 23, - Hex = 24, - GhostlyWhispers = 25, - - // Sharp Obstacles - PendulumBlades = 26, - IcyRazorWinds = 27, - AcidicThorns = 28, - DragonsBreath = 29, - PendulumScythe = 30, - FlameJet = 31, - PiercingIceDarts = 32, - GlassSandStorm = 33, - PoisonedDartWall = 34, - SpinningBladeWheel = 35, - PoisonDart = 36, - SpikedTumbleweed = 37, - Thunderbolt = 38, - GiantBearTrap = 39, - SteelNeedleRain = 40, - SpikedPit = 41, - DiamondDustStorm = 42, - TrapdoorScorpionPit = 43, - BladedFan = 44, - BearTrap = 45, - PorcupineQuill = 46, - HiddenArrow = 47, - GlassShard = 48, - ThornBush = 49, - JaggedRocks = 50, - - // Crushing Obstacles - SubterraneanTremor = 51, - Rockslide = 52, - FlashFlood = 53, - ClingingRoots = 54, - CollapsingCavern = 55, - CrushingWalls = 56, - SmashingPillars = 57, - RumblingCatacomb = 58, - WhirlingCyclone = 59, - EruptingEarth = 60, - SubterraneanTremor2 = 61, - FallingChandelier = 62, - CollapsingBridge = 63, - RagingSandstorm = 64, - AvalanchingRocks = 65, - TumblingBoulders = 66, - SlammingIronGate = 67, - ShiftingSandtrap = 68, - EruptingMudGeyser = 69, - CrumblingStaircase = 70, - SwingingLogs = 71, - UnstableCliff = 72, - TopplingStatue = 73, - TumblingBarrels = 74, - RollingBoulder = 75, + // Magical Obstacles + DemonicAlter = 1, + VortexOfDespair = 2, + EldritchBarrier = 3, + SoulTrap = 4, + PhantomVortex = 5, + EctoplasmicWeb = 6, + SpectralChains = 7, + InfernalPact = 8, + ArcaneExplosion = 9, + HypnoticEssence = 10, + MischievousSprites = 11, + SoulDrainingStatue = 12, + PetrifyingGaze = 13, + SummoningCircle = 14, + EtherealVoid = 15, + MagicLock = 16, + BewitchingFog = 17, + IllusionaryMaze = 18, + SpellboundMirror = 19, + EnsnaringShadow = 20, + DarkMist = 21, + Curse = 22, + HauntingEcho = 23, + Hex = 24, + GhostlyWhispers = 25, + + // Sharp Obstacles + PendulumBlades = 26, + IcyRazorWinds = 27, + AcidicThorns = 28, + DragonsBreath = 29, + PendulumScythe = 30, + FlameJet = 31, + PiercingIceDarts = 32, + GlassSandStorm = 33, + PoisonedDartWall = 34, + SpinningBladeWheel = 35, + PoisonDart = 36, + SpikedTumbleweed = 37, + Thunderbolt = 38, + GiantBearTrap = 39, + SteelNeedleRain = 40, + SpikedPit = 41, + DiamondDustStorm = 42, + TrapdoorScorpionPit = 43, + BladedFan = 44, + BearTrap = 45, + PorcupineQuill = 46, + HiddenArrow = 47, + GlassShard = 48, + ThornBush = 49, + JaggedRocks = 50, + + // Crushing Obstacles + SubterraneanTremor = 51, + Rockslide = 52, + FlashFlood = 53, + ClingingRoots = 54, + CollapsingCavern = 55, + CrushingWalls = 56, + SmashingPillars = 57, + RumblingCatacomb = 58, + WhirlingCyclone = 59, + EruptingEarth = 60, + SubterraneanTremor2 = 61, + FallingChandelier = 62, + CollapsingBridge = 63, + RagingSandstorm = 64, + AvalanchingRocks = 65, + TumblingBoulders = 66, + SlammingIronGate = 67, + ShiftingSandtrap = 68, + EruptingMudGeyser = 69, + CrumblingStaircase = 70, + SwingingLogs = 71, + UnstableCliff = 72, + TopplingStatue = 73, + TumblingBarrels = 74, + RollingBoulder = 75, } export enum DiscoveryType { - Beast = 1, - Obstacle = 2, - Item = 3, + Beast = 1, + Obstacle = 2, + Item = 3, } export enum ItemDiscoveryType { - Health = 1, - Gold = 2, - XP = 3, + Health = 1, + Gold = 2, + XP = 3, } export enum ItemNamePrefix { - Agony = 1, - Apocalypse = 2, - Armageddon = 3, - Beast = 4, - Behemoth = 5, - Blight = 6, - Blood = 7, - Bramble = 8, - Brimstone = 9, - Brood = 10, - Carrion = 11, - Cataclysm = 12, - Chimeric = 13, - Corpse = 14, - Corruption = 15, - Damnation = 16, - Death = 17, - Demon = 18, - Dire = 19, - Dragon = 20, - Dread = 21, - Doom = 22, - Dusk = 23, - Eagle = 24, - Empyrean = 25, - Fate = 26, - Foe = 27, - Gale = 28, - Ghoul = 29, - Gloom = 30, - Glyph = 31, - Golem = 32, - Grim = 33, - Hate = 34, - Havoc = 35, - Honour = 36, - Horror = 37, - Hypnotic = 38, - Kraken = 39, - Loath = 40, - Maelstrom = 41, - Mind = 42, - Miracle = 43, - Morbid = 44, - Oblivion = 45, - Onslaught = 46, - Pain = 47, - Pandemonium = 48, - Phoenix = 49, - Plague = 50, - Rage = 51, - Rapture = 52, - Rune = 53, - Skull = 54, - Sol = 55, - Soul = 56, - Sorrow = 57, - Spirit = 58, - Storm = 59, - Tempest = 60, - Torment = 61, - Vengeance = 62, - Victory = 63, - Viper = 64, - Vortex = 65, - Woe = 66, - Wrath = 67, - Lights = 68, - Shimmering = 69, + Agony = 1, + Apocalypse = 2, + Armageddon = 3, + Beast = 4, + Behemoth = 5, + Blight = 6, + Blood = 7, + Bramble = 8, + Brimstone = 9, + Brood = 10, + Carrion = 11, + Cataclysm = 12, + Chimeric = 13, + Corpse = 14, + Corruption = 15, + Damnation = 16, + Death = 17, + Demon = 18, + Dire = 19, + Dragon = 20, + Dread = 21, + Doom = 22, + Dusk = 23, + Eagle = 24, + Empyrean = 25, + Fate = 26, + Foe = 27, + Gale = 28, + Ghoul = 29, + Gloom = 30, + Glyph = 31, + Golem = 32, + Grim = 33, + Hate = 34, + Havoc = 35, + Honour = 36, + Horror = 37, + Hypnotic = 38, + Kraken = 39, + Loath = 40, + Maelstrom = 41, + Mind = 42, + Miracle = 43, + Morbid = 44, + Oblivion = 45, + Onslaught = 46, + Pain = 47, + Pandemonium = 48, + Phoenix = 49, + Plague = 50, + Rage = 51, + Rapture = 52, + Rune = 53, + Skull = 54, + Sol = 55, + Soul = 56, + Sorrow = 57, + Spirit = 58, + Storm = 59, + Tempest = 60, + Torment = 61, + Vengeance = 62, + Victory = 63, + Viper = 64, + Vortex = 65, + Woe = 66, + Wrath = 67, + Lights = 68, + Shimmering = 69, } export enum ItemNameSuffix { - Bane = 1, - Root = 2, - Bite = 3, - Song = 4, - Roar = 5, - Grasp = 6, - Instrument = 7, - Glow = 8, - Bender = 9, - Shadow = 10, - Whisper = 11, - Shout = 12, - Growl = 13, - Tear = 14, - Peak = 15, - Form = 16, - Sun = 17, - Moon = 18, + Bane = 1, + Root = 2, + Bite = 3, + Song = 4, + Roar = 5, + Grasp = 6, + Instrument = 7, + Glow = 8, + Bender = 9, + Shadow = 10, + Whisper = 11, + Shout = 12, + Growl = 13, + Tear = 14, + Peak = 15, + Form = 16, + Sun = 17, + Moon = 18, } export enum ItemSuffix { - OfPower = 1, - OfGiant = 2, - OfTitans = 3, - OfSkill = 4, - OfPerfection = 5, - OfBrilliance = 6, - OfEnlightenment = 7, - OfProtection = 8, - OfAnger = 9, - OfRage = 10, - OfFury = 11, - OfVitriol = 12, - OfTheFox = 13, - OfDetection = 14, - OfReflection = 15, - OfTheTwins = 16, + OfPower = 1, + OfGiant = 2, + OfTitans = 3, + OfSkill = 4, + OfPerfection = 5, + OfBrilliance = 6, + OfEnlightenment = 7, + OfProtection = 8, + OfAnger = 9, + OfRage = 10, + OfFury = 11, + OfVitriol = 12, + OfTheFox = 13, + OfDetection = 14, + OfReflection = 15, + OfTheTwins = 16, } export interface StatBoost { - [StatType.Strength]?: number; - [StatType.Dexterity]?: number; - [StatType.Vitality]?: number; - [StatType.Intelligence]?: number; - [StatType.Wisdom]?: number; - [StatType.Charisma]?: number; + [StatType.Strength]?: number; + [StatType.Dexterity]?: number; + [StatType.Vitality]?: number; + [StatType.Intelligence]?: number; + [StatType.Wisdom]?: number; + [StatType.Charisma]?: number; } export const ITEM_SUFFIX_BOOST: Record = { - [ItemSuffix.OfPower]: { [StatType.Strength]: 3 }, - [ItemSuffix.OfGiant]: { [StatType.Vitality]: 3 }, - [ItemSuffix.OfTitans]: { [StatType.Strength]: 2, [StatType.Charisma]: 1 }, - [ItemSuffix.OfSkill]: { [StatType.Dexterity]: 3 }, - [ItemSuffix.OfPerfection]: { - [StatType.Strength]: 1, - [StatType.Dexterity]: 1, - [StatType.Vitality]: 1, - }, - [ItemSuffix.OfBrilliance]: { [StatType.Intelligence]: 3 }, - [ItemSuffix.OfEnlightenment]: { [StatType.Wisdom]: 3 }, - [ItemSuffix.OfProtection]: { - [StatType.Vitality]: 2, - [StatType.Dexterity]: 1, - }, - [ItemSuffix.OfAnger]: { [StatType.Strength]: 2, [StatType.Dexterity]: 1 }, - [ItemSuffix.OfRage]: { - [StatType.Wisdom]: 1, - [StatType.Strength]: 1, - [StatType.Charisma]: 1, - }, - [ItemSuffix.OfFury]: { - [StatType.Vitality]: 1, - [StatType.Charisma]: 1, - [StatType.Intelligence]: 1, - }, - [ItemSuffix.OfVitriol]: { [StatType.Intelligence]: 2, [StatType.Wisdom]: 1 }, - [ItemSuffix.OfTheFox]: { [StatType.Dexterity]: 2, [StatType.Charisma]: 1 }, - [ItemSuffix.OfDetection]: { [StatType.Wisdom]: 2, [StatType.Dexterity]: 1 }, - [ItemSuffix.OfReflection]: { - [StatType.Wisdom]: 2, - [StatType.Intelligence]: 1, - }, - [ItemSuffix.OfTheTwins]: { [StatType.Charisma]: 3 }, + [ItemSuffix.OfPower]: { [StatType.Strength]: 3 }, + [ItemSuffix.OfGiant]: { [StatType.Vitality]: 3 }, + [ItemSuffix.OfTitans]: { [StatType.Strength]: 2, [StatType.Charisma]: 1 }, + [ItemSuffix.OfSkill]: { [StatType.Dexterity]: 3 }, + [ItemSuffix.OfPerfection]: { + [StatType.Strength]: 1, + [StatType.Dexterity]: 1, + [StatType.Vitality]: 1, + }, + [ItemSuffix.OfBrilliance]: { [StatType.Intelligence]: 3 }, + [ItemSuffix.OfEnlightenment]: { [StatType.Wisdom]: 3 }, + [ItemSuffix.OfProtection]: { + [StatType.Vitality]: 2, + [StatType.Dexterity]: 1, + }, + [ItemSuffix.OfAnger]: { [StatType.Strength]: 2, [StatType.Dexterity]: 1 }, + [ItemSuffix.OfRage]: { + [StatType.Wisdom]: 1, + [StatType.Strength]: 1, + [StatType.Charisma]: 1, + }, + [ItemSuffix.OfFury]: { + [StatType.Vitality]: 1, + [StatType.Charisma]: 1, + [StatType.Intelligence]: 1, + }, + [ItemSuffix.OfVitriol]: { + [StatType.Intelligence]: 2, + [StatType.Wisdom]: 1, + }, + [ItemSuffix.OfTheFox]: { [StatType.Dexterity]: 2, [StatType.Charisma]: 1 }, + [ItemSuffix.OfDetection]: { [StatType.Wisdom]: 2, [StatType.Dexterity]: 1 }, + [ItemSuffix.OfReflection]: { + [StatType.Wisdom]: 2, + [StatType.Intelligence]: 1, + }, + [ItemSuffix.OfTheTwins]: { [StatType.Charisma]: 3 }, }; export enum Status { - Closed = 0, - Open = 1, + Closed = 0, + Open = 1, } export enum SELECTORS { - StartGame = "StartGame", - AdventurerUpgraded = "AdventurerUpgraded", - DiscoveredHealth = "DiscoveredHealth", - DiscoveredGold = "DiscoveredGold", - DiscoveredLoot = "DiscoveredLoot", - DiscoveredXP = "DiscoveredXP", - EquipmentChanged = "EquipmentChanged", - DodgedObstacle = "DodgedObstacle", - HitByObstacle = "HitByObstacle", - DiscoveredBeast = "DiscoveredBeast", - AmbushedByBeast = "AmbushedByBeast", - AttackedBeast = "AttackedBeast", - AttackedByBeast = "AttackedByBeast", - SlayedBeast = "SlayedBeast", - FleeFailed = "FleeFailed", - FleeSucceeded = "FleeSucceeded", - PurchasedItems = "PurchasedItems", - PurchasedPotions = "PurchasedPotions", - EquippedItems = "EquippedItems", - DroppedItems = "DroppedItems", - GreatnessIncreased = "GreatnessIncreased", - ItemsLeveledUp = "ItemsLeveledUp", - NewHighScore = "NewHighScore", - AdventurerDied = "AdventurerDied", - AdventurerLeveledUp = "AdventurerLeveledUp", - UpgradesAvailable = "UpgradesAvailable", - Transfer = "Transfer", + StartGame = "StartGame", + AdventurerUpgraded = "AdventurerUpgraded", + DiscoveredHealth = "DiscoveredHealth", + DiscoveredGold = "DiscoveredGold", + DiscoveredLoot = "DiscoveredLoot", + DiscoveredXP = "DiscoveredXP", + EquipmentChanged = "EquipmentChanged", + DodgedObstacle = "DodgedObstacle", + HitByObstacle = "HitByObstacle", + DiscoveredBeast = "DiscoveredBeast", + AmbushedByBeast = "AmbushedByBeast", + AttackedBeast = "AttackedBeast", + AttackedByBeast = "AttackedByBeast", + SlayedBeast = "SlayedBeast", + FleeFailed = "FleeFailed", + FleeSucceeded = "FleeSucceeded", + PurchasedItems = "PurchasedItems", + PurchasedPotions = "PurchasedPotions", + EquippedItems = "EquippedItems", + DroppedItems = "DroppedItems", + GreatnessIncreased = "GreatnessIncreased", + ItemsLeveledUp = "ItemsLeveledUp", + NewHighScore = "NewHighScore", + AdventurerDied = "AdventurerDied", + AdventurerLeveledUp = "AdventurerLeveledUp", + UpgradesAvailable = "UpgradesAvailable", + Transfer = "Transfer", } export const HASHED_SELECTORS = { - StartGame: hash.getSelectorFromName(SELECTORS.StartGame), - AdventurerUpgraded: hash.getSelectorFromName(SELECTORS.AdventurerUpgraded), - DiscoveredHealth: hash.getSelectorFromName(SELECTORS.DiscoveredHealth), - DiscoveredGold: hash.getSelectorFromName(SELECTORS.DiscoveredGold), - DiscoveredLoot: hash.getSelectorFromName(SELECTORS.DiscoveredLoot), - DiscoveredXP: hash.getSelectorFromName(SELECTORS.DiscoveredXP), - EquipmentChanged: hash.getSelectorFromName(SELECTORS.EquipmentChanged), - DodgedObstacle: hash.getSelectorFromName(SELECTORS.DodgedObstacle), - HitByObstacle: hash.getSelectorFromName(SELECTORS.HitByObstacle), - DiscoveredBeast: hash.getSelectorFromName(SELECTORS.DiscoveredBeast), - AmbushedByBeast: hash.getSelectorFromName(SELECTORS.AmbushedByBeast), - AttackedBeast: hash.getSelectorFromName(SELECTORS.AttackedBeast), - AttackedByBeast: hash.getSelectorFromName(SELECTORS.AttackedByBeast), - SlayedBeast: hash.getSelectorFromName(SELECTORS.SlayedBeast), - FleeFailed: hash.getSelectorFromName(SELECTORS.FleeFailed), - FleeSucceeded: hash.getSelectorFromName(SELECTORS.FleeSucceeded), - PurchasedItems: hash.getSelectorFromName(SELECTORS.PurchasedItems), - PurchasedPotions: hash.getSelectorFromName(SELECTORS.PurchasedPotions), - EquippedItems: hash.getSelectorFromName(SELECTORS.EquippedItems), - DroppedItems: hash.getSelectorFromName(SELECTORS.DroppedItems), - GreatnessIncreased: hash.getSelectorFromName(SELECTORS.GreatnessIncreased), - ItemsLeveledUp: hash.getSelectorFromName(SELECTORS.ItemsLeveledUp), - NewHighScore: hash.getSelectorFromName(SELECTORS.NewHighScore), - AdventurerDied: hash.getSelectorFromName(SELECTORS.AdventurerDied), - AdventurerLeveledUp: hash.getSelectorFromName(SELECTORS.AdventurerLeveledUp), - UpgradesAvailable: hash.getSelectorFromName(SELECTORS.UpgradesAvailable), - Transfer: hash.getSelectorFromName(SELECTORS.Transfer), + StartGame: hash.getSelectorFromName(SELECTORS.StartGame), + AdventurerUpgraded: hash.getSelectorFromName(SELECTORS.AdventurerUpgraded), + DiscoveredHealth: hash.getSelectorFromName(SELECTORS.DiscoveredHealth), + DiscoveredGold: hash.getSelectorFromName(SELECTORS.DiscoveredGold), + DiscoveredLoot: hash.getSelectorFromName(SELECTORS.DiscoveredLoot), + DiscoveredXP: hash.getSelectorFromName(SELECTORS.DiscoveredXP), + EquipmentChanged: hash.getSelectorFromName(SELECTORS.EquipmentChanged), + DodgedObstacle: hash.getSelectorFromName(SELECTORS.DodgedObstacle), + HitByObstacle: hash.getSelectorFromName(SELECTORS.HitByObstacle), + DiscoveredBeast: hash.getSelectorFromName(SELECTORS.DiscoveredBeast), + AmbushedByBeast: hash.getSelectorFromName(SELECTORS.AmbushedByBeast), + AttackedBeast: hash.getSelectorFromName(SELECTORS.AttackedBeast), + AttackedByBeast: hash.getSelectorFromName(SELECTORS.AttackedByBeast), + SlayedBeast: hash.getSelectorFromName(SELECTORS.SlayedBeast), + FleeFailed: hash.getSelectorFromName(SELECTORS.FleeFailed), + FleeSucceeded: hash.getSelectorFromName(SELECTORS.FleeSucceeded), + PurchasedItems: hash.getSelectorFromName(SELECTORS.PurchasedItems), + PurchasedPotions: hash.getSelectorFromName(SELECTORS.PurchasedPotions), + EquippedItems: hash.getSelectorFromName(SELECTORS.EquippedItems), + DroppedItems: hash.getSelectorFromName(SELECTORS.DroppedItems), + GreatnessIncreased: hash.getSelectorFromName(SELECTORS.GreatnessIncreased), + ItemsLeveledUp: hash.getSelectorFromName(SELECTORS.ItemsLeveledUp), + NewHighScore: hash.getSelectorFromName(SELECTORS.NewHighScore), + AdventurerDied: hash.getSelectorFromName(SELECTORS.AdventurerDied), + AdventurerLeveledUp: hash.getSelectorFromName( + SELECTORS.AdventurerLeveledUp + ), + UpgradesAvailable: hash.getSelectorFromName(SELECTORS.UpgradesAvailable), + Transfer: hash.getSelectorFromName(SELECTORS.Transfer), }; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index b16dce2..6bd540e 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,21 +1,21 @@ { - "compilerOptions": { - "target": "esnext", - "module": "ESNext", - "declaration": true, - "outDir": "./dist", - "sourceMap": true, - "noImplicitAny": true, - "noUnusedLocals": true, - "moduleResolution": "bundler", - "noUnusedParameters": true, - "resolveJsonModule": true, + "compilerOptions": { + "target": "esnext", + "module": "ESNext", + "declaration": true, + "outDir": "./dist", + "sourceMap": true, + "noImplicitAny": true, + "noUnusedLocals": true, + "moduleResolution": "bundler", + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "esModuleInterop": true + }, + "include": ["src/**/*.ts", "src/provider/QueryProvider.tsx"], "skipLibCheck": true, - "strict": true, - "strictNullChecks": true, - "esModuleInterop": true - }, - "include": ["src/**/*.ts", "src/provider/QueryProvider.tsx"], - "skipLibCheck": true, - "exclude": ["node_modules", "dist", "**/*.test.ts"] + "exclude": ["node_modules", "dist", "**/*.test.ts"] } diff --git a/packages/core/tsup.config.ts b/packages/core/tsup.config.ts index 52bdfce..30da7a9 100644 --- a/packages/core/tsup.config.ts +++ b/packages/core/tsup.config.ts @@ -1,11 +1,11 @@ import { defineConfig } from "tsup"; export default defineConfig({ - entry: ["src/index.ts"], - target: "esnext", - format: ["esm"], - dts: true, - sourcemap: true, - clean: true, - minify: true, + entry: ["src/index.ts"], + target: "esnext", + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + minify: true, }); diff --git a/packages/react/package.json b/packages/react/package.json index 723bac6..f9047d1 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,40 +1,40 @@ { - "name": "@lootsurvivor/react", - "version": "0.0.1", - "description": "Useful React hooks for Survivor", - "source": "src/index.ts", - "main": "dist/index.js", - "type": "module", - "scripts": { - "build": "tsup --dts-resolve", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "license": "MIT", - "peerDependencies": { - "react": "^18.2.0", - "starknet": "6.11.0" - }, - "exports": { - ".": { - "import": "./dist/index.js", - "types": "./dist/index.d.ts" + "name": "@lootsurvivor/react", + "version": "0.0.1", + "description": "Useful React hooks for Survivor", + "source": "src/index.ts", + "main": "dist/index.js", + "type": "module", + "scripts": { + "build": "tsup --dts-resolve", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "license": "MIT", + "peerDependencies": { + "react": "^18.2.0", + "starknet": "6.11.0" + }, + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "devDependencies": { + "@babel/core": "^7.21.4", + "@babel/preset-env": "^7.21.4", + "@types/js-cookie": "^3.0.3", + "@types/node": "^18.15.11", + "@types/react": "^18.2.33", + "@types/react-dom": "^18.0.11", + "@types/web": "^0.0.114", + "tsup": "^8.0.1", + "typescript": "^5.0.3" + }, + "dependencies": { + "get-starknet-core": "^3.2.0", + "graphql-request": "^7.1.0", + "@lootsurvivor/core": "workspace:^", + "@tanstack/react-query": "^5.51.15" } - }, - "devDependencies": { - "@babel/core": "^7.21.4", - "@babel/preset-env": "^7.21.4", - "@types/js-cookie": "^3.0.3", - "@types/node": "^18.15.11", - "@types/react": "^18.2.33", - "@types/react-dom": "^18.0.11", - "@types/web": "^0.0.114", - "tsup": "^8.0.1", - "typescript": "^5.0.3" - }, - "dependencies": { - "get-starknet-core": "^3.2.0", - "graphql-request": "^7.1.0", - "@lootsurvivor/core": "workspace:^", - "@tanstack/react-query": "^5.51.15" - } } diff --git a/packages/react/src/providers/index.tsx b/packages/react/src/providers/index.tsx index 5abf36f..1da875b 100644 --- a/packages/react/src/providers/index.tsx +++ b/packages/react/src/providers/index.tsx @@ -4,7 +4,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export function QueryProvider({ children }: { children: React.ReactNode }) { - return ( - {children} - ); + return ( + + {children} + + ); } diff --git a/packages/react/src/queries/index.ts b/packages/react/src/queries/index.ts index e5a493a..1146a1a 100644 --- a/packages/react/src/queries/index.ts +++ b/packages/react/src/queries/index.ts @@ -1,205 +1,205 @@ import { useQuery, UseQueryResult } from "@tanstack/react-query"; import { request } from "graphql-request"; import { - getAdventurer, - getDiscoveries, - getLatestDiscoveries, - getLastDiscovery, - getLastBeastDiscovery, - getDiscoveryByTxHash, - getAdventurersByOwner, - getAdventurerById, - getAdventurersInList, - getAdventurersInListByXp, - getAdventurerByGold, - getBeastsByAdventurer, - getBeast, - getKilledBeasts, - getLatestBattlesByAdventurer, - getBattlesByBeast, - getLastBattleByAdventurer, - getBattlesByAdventurer, - getBattleByTxHash, - getItems, - getItemsByTokenId, - getLatestMarketItems, - getItemsByOwner, - getItemsByAdventurer, - getAdventurerByXP, - getAdventurersByXPPaginated, - getTopScores, - getScoresInList, - getGoldenTokensByOwner, - getScoresAndAdventurers, + getAdventurer, + getDiscoveries, + getLatestDiscoveries, + getLastDiscovery, + getLastBeastDiscovery, + getDiscoveryByTxHash, + getAdventurersByOwner, + getAdventurerById, + getAdventurersInList, + getAdventurersInListByXp, + getAdventurerByGold, + getBeastsByAdventurer, + getBeast, + getKilledBeasts, + getLatestBattlesByAdventurer, + getBattlesByBeast, + getLastBattleByAdventurer, + getBattlesByAdventurer, + getBattleByTxHash, + getItems, + getItemsByTokenId, + getLatestMarketItems, + getItemsByOwner, + getItemsByAdventurer, + getAdventurerByXP, + getAdventurersByXPPaginated, + getTopScores, + getScoresInList, + getGoldenTokensByOwner, + getScoresAndAdventurers, } from "@lootsurvivor/core"; import { AdventurerComplete } from "@lootsurvivor/core"; const DEFAULT_ENDPOINT = "https://ls-indexer-sepolia.provable.games/graphql"; function createQueryHook( - queryKey: string[], - query: string + queryKey: string[], + query: string ) { - return (variables?: TVariables, endpoint?: string): UseQueryResult => - useQuery({ - queryKey: [...queryKey, variables], - queryFn: async () => { - const data = await request( - endpoint || DEFAULT_ENDPOINT, - query, - variables || {} - ); - return data; - }, - }); + return (variables?: TVariables, endpoint?: string): UseQueryResult => + useQuery({ + queryKey: [...queryKey, variables], + queryFn: async () => { + const data = await request( + endpoint || DEFAULT_ENDPOINT, + query, + variables || {} + ); + return data; + }, + }); } export const useAdventurer = createQueryHook< - { adventurers: Array }, - { owner: string } + { adventurers: Array }, + { owner: string } >(["adventurer"], getAdventurer); export const useDiscoveries = createQueryHook< - { discoveries: Array }, - { id: string } + { discoveries: Array }, + { id: string } >(["discoveries"], getDiscoveries); export const useLatestDiscoveries = createQueryHook< - { discoveries: Array }, - { id: string } + { discoveries: Array }, + { id: string } >(["latestDiscoveries"], getLatestDiscoveries); export const useLastDiscovery = createQueryHook< - { discoveries: Array }, - { adventurerId: string } + { discoveries: Array }, + { adventurerId: string } >(["lastDiscovery"], getLastDiscovery); export const useLastBeastDiscovery = createQueryHook< - { discoveries: Array }, - { id: string } + { discoveries: Array }, + { id: string } >(["lastBeastDiscovery"], getLastBeastDiscovery); export const useDiscoveryByTxHash = createQueryHook< - { discoveries: Array }, - { txHash: string } + { discoveries: Array }, + { txHash: string } >(["discoveryByTxHash"], getDiscoveryByTxHash); export const useItems = createQueryHook<{ items: Array }, {}>( - ["items"], - getItems + ["items"], + getItems ); export const useAdventurersByOwner = createQueryHook< - { adventurers: Array }, - { owner: string } + { adventurers: Array }, + { owner: string } >(["adventurersByOwner"], getAdventurersByOwner); export const useAdventurerById = createQueryHook< - { adventurers: Array }, - { id: string } + { adventurers: Array }, + { id: string } >(["adventurerById"], getAdventurerById); export const useAdventurersInList = createQueryHook< - { adventurers: Array }, - { ids: string[] } + { adventurers: Array }, + { ids: string[] } >(["adventurersInList"], getAdventurersInList); export const useAdventurersInListByXp = createQueryHook< - { adventurers: Array }, - { ids: string[] } + { adventurers: Array }, + { ids: string[] } >(["adventurersInListByXp"], getAdventurersInListByXp); export const useAdventurerByGold = createQueryHook< - { adventurers: Array }, - {} + { adventurers: Array }, + {} >(["adventurerByGold"], getAdventurerByGold); export const useAdventurerByXP = createQueryHook< - { adventurers: Array }, - {} + { adventurers: Array }, + {} >(["adventurerByXP"], getAdventurerByXP); export const useAdventurersByXPPaginated = createQueryHook< - { adventurers: Array }, - { skip: number } + { adventurers: Array }, + { skip: number } >(["adventurersByXPPaginated"], getAdventurersByXPPaginated); export const useBeast = createQueryHook< - { beasts: Array }, - { beast: string; adventurerId: string; seed: string } + { beasts: Array }, + { beast: string; adventurerId: string; seed: string } >(["beast"], getBeast); export const useKilledBeasts = createQueryHook<{ beasts: Array }, {}>( - ["killedBeasts"], - getKilledBeasts + ["killedBeasts"], + getKilledBeasts ); export const useBeastsByAdventurer = createQueryHook< - { discoveries: Array }, - { id: string } + { discoveries: Array }, + { id: string } >(["beastsByAdventurer"], getBeastsByAdventurer); export const useLatestBattlesByAdventurer = createQueryHook< - { battles: Array }, - { adventurerId: string } + { battles: Array }, + { adventurerId: string } >(["latestBattlesByAdventurer"], getLatestBattlesByAdventurer); export const useBattlesByAdventurer = createQueryHook< - { battles: Array }, - { adventurerId: string } + { battles: Array }, + { adventurerId: string } >(["battlesByAdventurer"], getBattlesByAdventurer); export const useBattlesByBeast = createQueryHook< - { battles: Array }, - { adventurerId: string; beast: string; seed: string } + { battles: Array }, + { adventurerId: string; beast: string; seed: string } >(["battlesByBeast"], getBattlesByBeast); export const useLastBattleByAdventurer = createQueryHook< - { battles: Array }, - { adventurerId: string } + { battles: Array }, + { adventurerId: string } >(["lastBattleByAdventurer"], getLastBattleByAdventurer); export const useBattleByTxHash = createQueryHook< - { battles: Array }, - { txHash: string } + { battles: Array }, + { txHash: string } >(["battleByTxHash"], getBattleByTxHash); export const useItemsByTokenId = createQueryHook< - { items: Array }, - { item: string } + { items: Array }, + { item: string } >(["itemsByTokenId"], getItemsByTokenId); export const useLatestMarketItems = createQueryHook< - { items: Array }, - { id: string } + { items: Array }, + { id: string } >(["latestMarketItems"], getLatestMarketItems); export const useItemsByAdventurer = createQueryHook< - { items: Array }, - { id: string } + { items: Array }, + { id: string } >(["itemsByAdventurer"], getItemsByAdventurer); export const useItemsByOwner = createQueryHook< - { items: Array }, - { owner: string } + { items: Array }, + { owner: string } >(["itemsByOwner"], getItemsByOwner); export const useTopScores = createQueryHook<{ scores: Array }, {}>( - ["topScores"], - getTopScores + ["topScores"], + getTopScores ); export const useScoresInList = createQueryHook< - { scores: Array }, - { ids: number[] } + { scores: Array }, + { ids: number[] } >(["scoresInList"], getScoresInList); export const useGoldenTokensByOwner = createQueryHook< - { getERC721Tokens: Array }, - { contractAddress: string; owner: string } + { getERC721Tokens: Array }, + { contractAddress: string; owner: string } >(["goldenTokensByOwner"], getGoldenTokensByOwner); export const useScoresAndAdventurers = createQueryHook< - { scores: Array; adventurers: Array }, - {} + { scores: Array; adventurers: Array }, + {} >(["scoresAndAdventurers"], getScoresAndAdventurers); diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json index ef400fb..c33a6fb 100644 --- a/packages/react/tsconfig.json +++ b/packages/react/tsconfig.json @@ -1,30 +1,30 @@ { - "compilerOptions": { - "outDir": "./dist", - "module": "ESNext", - "moduleResolution": "bundler", - "esModuleInterop": true, - "isolatedModules": true, - "forceConsistentCasingInFileNames": true, - "jsx": "react-jsx", - "lib": ["esnext", "DOM"], - "sourceMap": true, - "declaration": true, - "noImplicitAny": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "strict": true, - "strictNullChecks": true, - "target": "esnext", - "types": ["node", "web"], - "baseUrl": ".", - "rootDir": "src", - "paths": { - "~/*": ["src/*"] - } - }, - "include": ["src/**/*.ts", "src/providers/index.tsx"], - "exclude": ["node_modules", "dist", "**/*.test.ts"] + "compilerOptions": { + "outDir": "./dist", + "module": "ESNext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["esnext", "DOM"], + "sourceMap": true, + "declaration": true, + "noImplicitAny": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "strict": true, + "strictNullChecks": true, + "target": "esnext", + "types": ["node", "web"], + "baseUrl": ".", + "rootDir": "src", + "paths": { + "~/*": ["src/*"] + } + }, + "include": ["src/**/*.ts", "src/providers/index.tsx"], + "exclude": ["node_modules", "dist", "**/*.test.ts"] } diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts index 52bdfce..30da7a9 100644 --- a/packages/react/tsup.config.ts +++ b/packages/react/tsup.config.ts @@ -1,11 +1,11 @@ import { defineConfig } from "tsup"; export default defineConfig({ - entry: ["src/index.ts"], - target: "esnext", - format: ["esm"], - dts: true, - sourcemap: true, - clean: true, - minify: true, + entry: ["src/index.ts"], + target: "esnext", + format: ["esm"], + dts: true, + sourcemap: true, + clean: true, + minify: true, }); diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index cdce547..b493be1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,3 @@ packages: - - "packages/*" - - "clients/*" + - "packages/*" + - "clients/*" diff --git a/readme.md b/readme.md index 834bb15..208bd4b 100644 --- a/readme.md +++ b/readme.md @@ -10,24 +10,24 @@ Currently the only package is the `core` which is vanilla.js of the following: ## Features -- [x] Execution client -- [x] Game Constants -- [x] Hosted Images -- [x] Zustand State -- [] Abstracted Graphql queries for deep information -- [] gPRC provider -- [] React Package +- [x] Execution client +- [x] Game Constants +- [x] Hosted Images +- [x] Zustand State +- [] Abstracted Graphql queries for deep information +- [] gPRC provider +- [] React Package ## Usage ```js // Full Provider which exposes all the Managers along with an execution client const survivor = new LootSurvivor( - nodeUrl, - lootSurvivorAddress, - beastsAddress, - goldenTokenAddress, - account + nodeUrl, + lootSurvivorAddress, + beastsAddress, + goldenTokenAddress, + account ); // usage