diff --git a/apps/client/src/components/interface.tsx b/apps/client/src/components/interface.tsx index 094e5ae6..022cf641 100644 --- a/apps/client/src/components/interface.tsx +++ b/apps/client/src/components/interface.tsx @@ -4,7 +4,6 @@ import { useScene } from "../hooks/useScene" import { ChunkBlock } from "./chunkBlock" import { EventsBlock } from "./eventsBlock" import { GroupBlock } from "./groupBlock" -import { Loader } from "./loader" import { RouteBlock } from "./routeBlock" import { TopPlayersBlock } from "./topPlayers" import { WagonStatsBlock } from "./wagonStatsBlock" @@ -15,7 +14,7 @@ export const InterfaceLayer = () => { return ( <> - + {/**/}
Promise - - constructor({ command, commandDescription }: IActionOptions) { - this.command = command - this.commandDescription = commandDescription - } -} diff --git a/apps/client/src/game/actions/donateWoodToVillageAction.ts b/apps/client/src/game/actions/donateWoodToVillageAction.ts deleted file mode 100644 index 11ffaade..00000000 --- a/apps/client/src/game/actions/donateWoodToVillageAction.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ANSWER } from "../../../../../packages/api-sdk/src/lib/actionAnswer" -import { Village } from "../chunks" -import type { Warehouse } from "../objects/buildings/warehouse" -import type { Player } from "../objects/units" -import type { GameScene } from "../scenes/gameScene" -import { Action } from "./action" - -interface IDonateWoodToVillageActionOptions { - scene: GameScene -} - -export class DonateWoodToVillageAction extends Action { - private scene: GameScene - - constructor({ scene }: IDonateWoodToVillageActionOptions) { - super({ command: "donate", commandDescription: "!donate [quantity]" }) - - this.scene = scene - this.live = this.initLive - } - - async initLive(player: Player, params: string[]) { - const amount = this.scene.actionService.getAmountFromChatCommand(params[0]) - if (!amount) { - return ANSWER.WRONG_AMOUNT_ERROR - } - - let warehouse: Warehouse | undefined - if (this.scene.chunkNow instanceof Village) { - warehouse = this.scene.chunkNow.getWarehouse() - } - - const isSuccess = await player.inventory.reduceOrDestroyItem("WOOD", amount) - if (!isSuccess) { - return ANSWER.NOT_ENOUGH_WOOD_ERROR - } - - await warehouse?.inventory.addOrCreateItem("WOOD", amount) - await player.addReputation(amount) - - return ANSWER.DONATE_WOOD_OK - } -} diff --git a/apps/client/src/game/actions/plantTreeAction.ts b/apps/client/src/game/actions/plantTreeAction.ts deleted file mode 100644 index a4900b4f..00000000 --- a/apps/client/src/game/actions/plantTreeAction.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ANSWER } from "../../../../../packages/api-sdk/src/lib/actionAnswer" -import { Village } from "../chunks" -import type { Player } from "../objects/units" -import type { GameScene } from "../scenes" -import { PlantNewTreeScript } from "../scripts/plantNewTreeScript" -import { Action } from "./action" - -interface IPlantTreeActionOptions { - scene: GameScene -} - -export class PlantTreeAction extends Action { - private scene: GameScene - - constructor({ scene }: IPlantTreeActionOptions) { - super({ command: "plant", commandDescription: "!plant" }) - - this.scene = scene - this.live = this.initLive - } - - async initLive(player: Player) { - if (player.script && !player.script.isInterruptible) { - return ANSWER.BUSY_ERROR - } - - if (this.scene.chunkNow instanceof Village) { - const target = this.scene.chunkNow.checkIfNeedToPlantTree() - if (!target) { - return ANSWER.NO_SPACE_AVAILABLE_ERROR - } - - const plantNewTreeFunc = () => { - if (this.scene.chunkNow instanceof Village) { - this.scene.chunkNow.plantNewTree(target) - } - } - - player.script = new PlantNewTreeScript({ - object: player, - target, - plantNewTreeFunc, - }) - - return ANSWER.OK - } - - return ANSWER.ERROR - } -} diff --git a/apps/client/src/game/actions/voteAction.ts b/apps/client/src/game/actions/voteAction.ts deleted file mode 100644 index c65e3757..00000000 --- a/apps/client/src/game/actions/voteAction.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ANSWER } from "../../../../../packages/api-sdk/src/lib/actionAnswer" -import type { Poll } from "../common" -import type { Player } from "../objects/units" -import { Action } from "./action" - -interface IVoteActionOptions { - poll: Poll -} - -export class VoteAction extends Action { - private poll: Poll - private readonly id: string - - constructor({ poll }: IVoteActionOptions) { - super({ command: "go", commandDescription: "!go" }) - - this.id = poll.generatePollId() - - this.command = `go ${this.id}` - this.commandDescription = `!go ${this.id}` - - this.poll = poll - this.live = this.initLive - } - - async initLive(player: Player) { - const isSuccess = this.poll.vote(player) - if (!isSuccess) { - return ANSWER.ALREADY_VOTED_ERROR - } - - return ANSWER.VOTED_OK - } -} diff --git a/apps/client/src/game/assets/audio/chop-1.wav b/apps/client/src/game/assets/audio/chop-1.wav deleted file mode 100644 index d76c89bf..00000000 Binary files a/apps/client/src/game/assets/audio/chop-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/fire-1.wav b/apps/client/src/game/assets/audio/fire-1.wav deleted file mode 100644 index 839ec9d4..00000000 Binary files a/apps/client/src/game/assets/audio/fire-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/forest-1.mp3 b/apps/client/src/game/assets/audio/forest-1.mp3 deleted file mode 100644 index 385dfe97..00000000 Binary files a/apps/client/src/game/assets/audio/forest-1.mp3 and /dev/null differ diff --git a/apps/client/src/game/assets/audio/hand-punch-1.wav b/apps/client/src/game/assets/audio/hand-punch-1.wav deleted file mode 100644 index 9afaa4b7..00000000 Binary files a/apps/client/src/game/assets/audio/hand-punch-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/marching-with-horns-1.wav b/apps/client/src/game/assets/audio/marching-with-horns-1.wav deleted file mode 100644 index 25879073..00000000 Binary files a/apps/client/src/game/assets/audio/marching-with-horns-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/mine-1.wav b/apps/client/src/game/assets/audio/mine-1.wav deleted file mode 100644 index cf0102b0..00000000 Binary files a/apps/client/src/game/assets/audio/mine-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/wagon-1.wav b/apps/client/src/game/assets/audio/wagon-1.wav deleted file mode 100644 index f0025026..00000000 Binary files a/apps/client/src/game/assets/audio/wagon-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/audio/yeah-1.wav b/apps/client/src/game/assets/audio/yeah-1.wav deleted file mode 100644 index bd1aa563..00000000 Binary files a/apps/client/src/game/assets/audio/yeah-1.wav and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/1.png b/apps/client/src/game/assets/images/animation/campfire/1.png deleted file mode 100644 index 4f9adad5..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/2.png b/apps/client/src/game/assets/images/animation/campfire/2.png deleted file mode 100644 index 63c1b1ac..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/3.png b/apps/client/src/game/assets/images/animation/campfire/3.png deleted file mode 100644 index 62e9d9e3..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/4.png b/apps/client/src/game/assets/images/animation/campfire/4.png deleted file mode 100644 index 5e663302..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/4.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/5.png b/apps/client/src/game/assets/images/animation/campfire/5.png deleted file mode 100644 index 7a25cbe3..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/5.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/particle-1.png b/apps/client/src/game/assets/images/animation/campfire/particle-1.png deleted file mode 100644 index 9b4c0659..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/particle-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/particle-2.png b/apps/client/src/game/assets/images/animation/campfire/particle-2.png deleted file mode 100644 index 7c26c095..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/particle-2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/campfire/particle-3.png b/apps/client/src/game/assets/images/animation/campfire/particle-3.png deleted file mode 100644 index 945ff039..00000000 Binary files a/apps/client/src/game/assets/images/animation/campfire/particle-3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/1.png b/apps/client/src/game/assets/images/animation/hero-moving-right/1.png deleted file mode 100644 index 17ecc617..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/2.png b/apps/client/src/game/assets/images/animation/hero-moving-right/2.png deleted file mode 100644 index 584152d6..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/3.png b/apps/client/src/game/assets/images/animation/hero-moving-right/3.png deleted file mode 100644 index e60369f0..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/4.png b/apps/client/src/game/assets/images/animation/hero-moving-right/4.png deleted file mode 100644 index 85ac447e..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/4.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/5.png b/apps/client/src/game/assets/images/animation/hero-moving-right/5.png deleted file mode 100644 index df47794d..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/5.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/animation/hero-moving-right/6.png b/apps/client/src/game/assets/images/animation/hero-moving-right/6.png deleted file mode 100644 index f81f8a21..00000000 Binary files a/apps/client/src/game/assets/images/animation/hero-moving-right/6.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/1.png b/apps/client/src/game/assets/images/background/1.png deleted file mode 100644 index 5bc7fcab..00000000 Binary files a/apps/client/src/game/assets/images/background/1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/2.png b/apps/client/src/game/assets/images/background/2.png deleted file mode 100644 index f267bea9..00000000 Binary files a/apps/client/src/game/assets/images/background/2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/3.png b/apps/client/src/game/assets/images/background/3.png deleted file mode 100644 index 68de7b9e..00000000 Binary files a/apps/client/src/game/assets/images/background/3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/4.png b/apps/client/src/game/assets/images/background/4.png deleted file mode 100644 index b76292fb..00000000 Binary files a/apps/client/src/game/assets/images/background/4.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/5.png b/apps/client/src/game/assets/images/background/5.png deleted file mode 100644 index 263edc45..00000000 Binary files a/apps/client/src/game/assets/images/background/5.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/generated-1.png b/apps/client/src/game/assets/images/background/generated-1.png deleted file mode 100644 index 48d02b63..00000000 Binary files a/apps/client/src/game/assets/images/background/generated-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/background/paper-background-1.jpg b/apps/client/src/game/assets/images/background/paper-background-1.jpg deleted file mode 100644 index b8a8b9f9..00000000 Binary files a/apps/client/src/game/assets/images/background/paper-background-1.jpg and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/camp-fire-1.png b/apps/client/src/game/assets/images/buildings/camp-fire-1.png deleted file mode 100644 index f9eaf5d2..00000000 Binary files a/apps/client/src/game/assets/images/buildings/camp-fire-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/camp-fire-2.png b/apps/client/src/game/assets/images/buildings/camp-fire-2.png deleted file mode 100644 index dcb01b1d..00000000 Binary files a/apps/client/src/game/assets/images/buildings/camp-fire-2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/construction-1.png b/apps/client/src/game/assets/images/buildings/construction-1.png deleted file mode 100644 index 518f7b33..00000000 Binary files a/apps/client/src/game/assets/images/buildings/construction-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/store.png b/apps/client/src/game/assets/images/buildings/store.png deleted file mode 100644 index adb7d533..00000000 Binary files a/apps/client/src/game/assets/images/buildings/store.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/wagon-stop-1.png b/apps/client/src/game/assets/images/buildings/wagon-stop-1.png deleted file mode 100644 index 5c1cd1ef..00000000 Binary files a/apps/client/src/game/assets/images/buildings/wagon-stop-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/buildings/warehouse-1.png b/apps/client/src/game/assets/images/buildings/warehouse-1.png deleted file mode 100644 index b5b49dc6..00000000 Binary files a/apps/client/src/game/assets/images/buildings/warehouse-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/coin-1.png b/apps/client/src/game/assets/images/icons/coin-1.png deleted file mode 100644 index a4307355..00000000 Binary files a/apps/client/src/game/assets/images/icons/coin-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/fuel-1.png b/apps/client/src/game/assets/images/icons/fuel-1.png deleted file mode 100644 index d76efc75..00000000 Binary files a/apps/client/src/game/assets/images/icons/fuel-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/items/coin.png b/apps/client/src/game/assets/images/icons/items/coin.png deleted file mode 100644 index a4307355..00000000 Binary files a/apps/client/src/game/assets/images/icons/items/coin.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/items/stone.png b/apps/client/src/game/assets/images/icons/items/stone.png deleted file mode 100644 index 4f5b32f1..00000000 Binary files a/apps/client/src/game/assets/images/icons/items/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/items/wood.png b/apps/client/src/game/assets/images/icons/items/wood.png deleted file mode 100644 index 2a9e0218..00000000 Binary files a/apps/client/src/game/assets/images/icons/items/wood.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/icons/speed-1.png b/apps/client/src/game/assets/images/icons/speed-1.png deleted file mode 100644 index e770975e..00000000 Binary files a/apps/client/src/game/assets/images/icons/speed-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/flag-1.png b/apps/client/src/game/assets/images/objects/flag-1.png deleted file mode 100644 index 44138cf2..00000000 Binary files a/apps/client/src/game/assets/images/objects/flag-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/flag-2.png b/apps/client/src/game/assets/images/objects/flag-2.png deleted file mode 100644 index a4652afc..00000000 Binary files a/apps/client/src/game/assets/images/objects/flag-2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/stone-1.png b/apps/client/src/game/assets/images/objects/stone-1.png deleted file mode 100644 index 02c43535..00000000 Binary files a/apps/client/src/game/assets/images/objects/stone-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/blue.png b/apps/client/src/game/assets/images/objects/tree/1/blue.png deleted file mode 100644 index c2b2457b..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/blue.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/green.png b/apps/client/src/game/assets/images/objects/tree/1/green.png deleted file mode 100644 index c4b29589..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/green.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/stone.png b/apps/client/src/game/assets/images/objects/tree/1/stone.png deleted file mode 100644 index b154a4b6..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/teal.png b/apps/client/src/game/assets/images/objects/tree/1/teal.png deleted file mode 100644 index 4f2b05a4..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/teal.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/toxic.png b/apps/client/src/game/assets/images/objects/tree/1/toxic.png deleted file mode 100644 index 256bf429..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/toxic.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/1/violet.png b/apps/client/src/game/assets/images/objects/tree/1/violet.png deleted file mode 100644 index ed7dc9d9..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/1/violet.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/blue.png b/apps/client/src/game/assets/images/objects/tree/2/blue.png deleted file mode 100644 index 33f59b0f..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/blue.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/green.png b/apps/client/src/game/assets/images/objects/tree/2/green.png deleted file mode 100644 index ddb6a160..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/green.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/stone.png b/apps/client/src/game/assets/images/objects/tree/2/stone.png deleted file mode 100644 index 13108060..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/teal.png b/apps/client/src/game/assets/images/objects/tree/2/teal.png deleted file mode 100644 index 2b2fe0f3..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/teal.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/toxic.png b/apps/client/src/game/assets/images/objects/tree/2/toxic.png deleted file mode 100644 index f126962b..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/toxic.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/2/violet.png b/apps/client/src/game/assets/images/objects/tree/2/violet.png deleted file mode 100644 index 6abf2853..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/2/violet.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/blue.png b/apps/client/src/game/assets/images/objects/tree/3/blue.png deleted file mode 100644 index 071e9a16..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/blue.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/green.png b/apps/client/src/game/assets/images/objects/tree/3/green.png deleted file mode 100644 index 0c408459..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/green.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/stone.png b/apps/client/src/game/assets/images/objects/tree/3/stone.png deleted file mode 100644 index 387bf222..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/teal.png b/apps/client/src/game/assets/images/objects/tree/3/teal.png deleted file mode 100644 index ff426c58..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/teal.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/toxic.png b/apps/client/src/game/assets/images/objects/tree/3/toxic.png deleted file mode 100644 index c408f5c7..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/toxic.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/3/violet.png b/apps/client/src/game/assets/images/objects/tree/3/violet.png deleted file mode 100644 index baa1adc7..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/3/violet.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/blue.png b/apps/client/src/game/assets/images/objects/tree/4/blue.png deleted file mode 100644 index d1a6485c..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/blue.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/green.png b/apps/client/src/game/assets/images/objects/tree/4/green.png deleted file mode 100644 index b2729d46..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/green.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/stone.png b/apps/client/src/game/assets/images/objects/tree/4/stone.png deleted file mode 100644 index 93f2737a..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/teal.png b/apps/client/src/game/assets/images/objects/tree/4/teal.png deleted file mode 100644 index 942d8a81..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/teal.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/toxic.png b/apps/client/src/game/assets/images/objects/tree/4/toxic.png deleted file mode 100644 index aebc3238..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/toxic.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/4/violet.png b/apps/client/src/game/assets/images/objects/tree/4/violet.png deleted file mode 100644 index 2323eb4f..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/4/violet.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/blue.png b/apps/client/src/game/assets/images/objects/tree/5/blue.png deleted file mode 100644 index a7f9b491..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/blue.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/green.png b/apps/client/src/game/assets/images/objects/tree/5/green.png deleted file mode 100644 index 6103efdb..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/green.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/stone.png b/apps/client/src/game/assets/images/objects/tree/5/stone.png deleted file mode 100644 index 68928561..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/stone.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/teal.png b/apps/client/src/game/assets/images/objects/tree/5/teal.png deleted file mode 100644 index f42ec6b0..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/teal.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/toxic.png b/apps/client/src/game/assets/images/objects/tree/5/toxic.png deleted file mode 100644 index 7695da7f..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/toxic.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/objects/tree/5/violet.png b/apps/client/src/game/assets/images/objects/tree/5/violet.png deleted file mode 100644 index 71d85a34..00000000 Binary files a/apps/client/src/game/assets/images/objects/tree/5/violet.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/hairstyle/hair-classic-right.png b/apps/client/src/game/assets/images/unit/hairstyle/hair-classic-right.png deleted file mode 100644 index a8614bd1..00000000 Binary files a/apps/client/src/game/assets/images/unit/hairstyle/hair-classic-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/hairstyle/hair-coal-long-right.png b/apps/client/src/game/assets/images/unit/hairstyle/hair-coal-long-right.png deleted file mode 100644 index b944061e..00000000 Binary files a/apps/client/src/game/assets/images/unit/hairstyle/hair-coal-long-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/hairstyle/orange-with-beard.png b/apps/client/src/game/assets/images/unit/hairstyle/orange-with-beard.png deleted file mode 100644 index c0d8c48d..00000000 Binary files a/apps/client/src/game/assets/images/unit/hairstyle/orange-with-beard.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/head/head-1-right.png b/apps/client/src/game/assets/images/unit/head/head-1-right.png deleted file mode 100644 index e6fdeffd..00000000 Binary files a/apps/client/src/game/assets/images/unit/head/head-1-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/top/black-top-right.png b/apps/client/src/game/assets/images/unit/top/black-top-right.png deleted file mode 100644 index 57f74ecd..00000000 Binary files a/apps/client/src/game/assets/images/unit/top/black-top-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/top/blue-top-right.png b/apps/client/src/game/assets/images/unit/top/blue-top-right.png deleted file mode 100644 index db0ef6c8..00000000 Binary files a/apps/client/src/game/assets/images/unit/top/blue-top-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/top/dark-silver-top-right.png b/apps/client/src/game/assets/images/unit/top/dark-silver-top-right.png deleted file mode 100644 index 0d2c0feb..00000000 Binary files a/apps/client/src/game/assets/images/unit/top/dark-silver-top-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/top/green-top-right.png b/apps/client/src/game/assets/images/unit/top/green-top-right.png deleted file mode 100644 index bdfc5df6..00000000 Binary files a/apps/client/src/game/assets/images/unit/top/green-top-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/unit/top/violet-top-right.png b/apps/client/src/game/assets/images/unit/top/violet-top-right.png deleted file mode 100644 index c9950acc..00000000 Binary files a/apps/client/src/game/assets/images/unit/top/violet-top-right.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/chest-1.png b/apps/client/src/game/assets/images/wagon/chest-1.png deleted file mode 100644 index df644b98..00000000 Binary files a/apps/client/src/game/assets/images/wagon/chest-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/clouds/1.png b/apps/client/src/game/assets/images/wagon/clouds/1.png deleted file mode 100644 index c42cd97d..00000000 Binary files a/apps/client/src/game/assets/images/wagon/clouds/1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/clouds/2.png b/apps/client/src/game/assets/images/wagon/clouds/2.png deleted file mode 100644 index e19d36a1..00000000 Binary files a/apps/client/src/game/assets/images/wagon/clouds/2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/clouds/3.png b/apps/client/src/game/assets/images/wagon/clouds/3.png deleted file mode 100644 index bc13e610..00000000 Binary files a/apps/client/src/game/assets/images/wagon/clouds/3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/clouds/4.png b/apps/client/src/game/assets/images/wagon/clouds/4.png deleted file mode 100644 index 25ad0282..00000000 Binary files a/apps/client/src/game/assets/images/wagon/clouds/4.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/engine-1.png b/apps/client/src/game/assets/images/wagon/engine-1.png deleted file mode 100644 index 27a0b79f..00000000 Binary files a/apps/client/src/game/assets/images/wagon/engine-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/fuel-1.png b/apps/client/src/game/assets/images/wagon/fuel-1.png deleted file mode 100644 index 4c8d0e24..00000000 Binary files a/apps/client/src/game/assets/images/wagon/fuel-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/fuel-2.png b/apps/client/src/game/assets/images/wagon/fuel-2.png deleted file mode 100644 index dbd146b5..00000000 Binary files a/apps/client/src/game/assets/images/wagon/fuel-2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/fuel-container.png b/apps/client/src/game/assets/images/wagon/fuel-container.png deleted file mode 100644 index 1e2cfd0a..00000000 Binary files a/apps/client/src/game/assets/images/wagon/fuel-container.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/wagon-1.png b/apps/client/src/game/assets/images/wagon/wagon-1.png deleted file mode 100644 index c59632c9..00000000 Binary files a/apps/client/src/game/assets/images/wagon/wagon-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/wagon-2.png b/apps/client/src/game/assets/images/wagon/wagon-2.png deleted file mode 100644 index 7b3c6833..00000000 Binary files a/apps/client/src/game/assets/images/wagon/wagon-2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/wagon/wheel-1.png b/apps/client/src/game/assets/images/wagon/wheel-1.png deleted file mode 100644 index a57a0496..00000000 Binary files a/apps/client/src/game/assets/images/wagon/wheel-1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/water/1.png b/apps/client/src/game/assets/images/water/1.png deleted file mode 100644 index 155b6ad0..00000000 Binary files a/apps/client/src/game/assets/images/water/1.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/water/2.png b/apps/client/src/game/assets/images/water/2.png deleted file mode 100644 index 4eba0919..00000000 Binary files a/apps/client/src/game/assets/images/water/2.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/water/3.png b/apps/client/src/game/assets/images/water/3.png deleted file mode 100644 index b44cb514..00000000 Binary files a/apps/client/src/game/assets/images/water/3.png and /dev/null differ diff --git a/apps/client/src/game/assets/images/water/4.png b/apps/client/src/game/assets/images/water/4.png deleted file mode 100644 index 727115b1..00000000 Binary files a/apps/client/src/game/assets/images/water/4.png and /dev/null differ diff --git a/apps/client/src/game/chunks/forest.ts b/apps/client/src/game/chunks/forest.ts deleted file mode 100644 index 57368027..00000000 --- a/apps/client/src/game/chunks/forest.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - type IGameChunkTheme, - type IGameForestChunk, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Stone, Tree } from "../objects" -import type { GameScene } from "../scenes/gameScene.ts" -import { GameChunk } from "./gameChunk" - -interface IForestOptions { - center: IGameForestChunk["center"] - width: number - height: number - theme: IGameChunkTheme - scene: GameScene -} - -export class Forest extends GameChunk implements IGameForestChunk { - constructor({ width, height, center, theme, scene }: IForestOptions) { - super({ - title: "Grand Wood", - type: "FOREST", - width, - height, - center, - theme, - scene, - }) - - const treesToPrepare = Math.round( - (this.area.area.endX - this.area.area.startX) / 10, - ) - this.initTrees(treesToPrepare) - this.initStones(3) - } - - live() { - super.live() - - for (const obj of this.objects) { - void obj.live() - } - } - - initTrees(count: number) { - for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() - const size = getRandomInRange(75, 90) - const tree = new Tree({ - scene: this.scene, - x: point.x, - y: point.y, - size, - resource: 1, - health: 20, - variant: this.area.theme, - }) - this.objects.push(tree) - } - } - - initStones(count: number) { - for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() - const stone = new Stone({ - scene: this.scene, - x: point.x, - y: point.y, - resource: 1, - }) - this.objects.push(stone) - } - } -} diff --git a/apps/client/src/game/chunks/gameChunk.ts b/apps/client/src/game/chunks/gameChunk.ts deleted file mode 100644 index 66c396c5..00000000 --- a/apps/client/src/game/chunks/gameChunk.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { - type IGameChunk, - type IGameChunkTheme, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Area, type GameObject, Tree } from "../objects" -import type { GameScene } from "../scenes/gameScene.ts" - -interface IGameChunkOptions { - center: IGameChunk["center"] - title: IGameChunk["title"] - type: IGameChunk["type"] - theme: IGameChunkTheme - width: number - height: number - scene: GameScene -} - -export class GameChunk implements IGameChunk { - public id: string - public title: string - public type: IGameChunk["type"] - public center!: IGameChunk["center"] - public area!: Area - - public scene: GameScene - public objects: GameObject[] = [] - - constructor({ - title, - type, - theme, - width, - height, - center, - scene, - }: IGameChunkOptions) { - this.id = createId() - this.center = center - this.title = title - this.type = type - - this.scene = scene - - this.initArea({ width, height, theme }) - } - - public live() {} - - private initArea({ - width, - height, - theme, - }: { - width: number - height: number - theme: IGameChunkTheme - }) { - const halfWidth = Math.round(width / 2) - const halfHeight = Math.round(height / 2) - - const area = { - startX: this.center.x - halfWidth, - endX: this.center.x + halfWidth, - startY: this.center.y - halfHeight, - endY: this.center.y + halfHeight, - } - - this.area = new Area({ scene: this.scene, theme, area }) - } - - public getRandomPoint() { - return { - x: getRandomInRange(this.area.area.startX, this.area.area.endX), - y: getRandomInRange(this.area.area.startY, this.area.area.endY), - } - } - - public getRandomOutPoint() { - const height = this.area.area.endY - this.area.area.startY - const offsetFromTop = Math.round(height / 4) - - return { - x: this.area.area.endX, - y: getRandomInRange( - this.area.area.startY + offsetFromTop, - this.area.area.endY, - ), - } - } - - public checkIfPointIsInArea(point: { x: number; y: number }): boolean { - if (point.x >= this.area.area.startX && point.x <= this.area.area.endX) { - if (point.y >= this.area.area.startY && point.y <= this.area.area.endY) { - return true - } - } - - return false - } - - removeObject(object: GameObject) { - const index = this.objects.indexOf(object) - this.objects.splice(index, 1) - } - - getAvailableTree(): Tree | undefined { - const trees = this.objects.filter( - (obj) => - obj instanceof Tree && - obj.state !== "DESTROYED" && - !obj.isReserved && - obj.isReadyToChop, - ) - if (!trees || !trees.length) { - return undefined - } - - return trees[Math.floor(Math.random() * trees.length)] as Tree - } -} diff --git a/apps/client/src/game/chunks/index.ts b/apps/client/src/game/chunks/index.ts deleted file mode 100644 index f795be06..00000000 --- a/apps/client/src/game/chunks/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { Forest } from "./forest" -export { GameChunk } from "./gameChunk" -export { Village } from "./village" -export { LakeChunk } from "./lake" diff --git a/apps/client/src/game/chunks/lake.ts b/apps/client/src/game/chunks/lake.ts deleted file mode 100644 index f701959d..00000000 --- a/apps/client/src/game/chunks/lake.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - type IGameChunkTheme, - type IGameLakeChunk, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Lake, Stone, Tree } from "../objects" -import { GameChunk } from "./gameChunk" -import type { GameScene } from "../scenes/gameScene.ts"; - -interface ILakeOptions { - scene: GameScene - center: IGameLakeChunk["center"] - width: number - height: number - theme: IGameChunkTheme -} - -export class LakeChunk extends GameChunk implements IGameLakeChunk { - constructor({ scene, width, height, center, theme }: ILakeOptions) { - super({ - scene, - width, - height, - center, - theme, - title: "Lake with a Secret", - type: "LAKE", - }) - - const treesToPrepare = Math.round( - (this.area.area.endX - this.area.area.startX) / 30, - ) - this.initTrees(treesToPrepare) - this.initStones(3) - this.initLake() - } - - live() { - super.live() - - for (const obj of this.objects) { - void obj.live() - } - } - - initLake() { - const lake = new Lake({ - scene: this.scene, - x: this.center.x - 100, - y: this.center.y + 400 - }) - const lake2 = new Lake({ - scene: this.scene, - x: this.center.x - 600, - y: this.center.y + 500 - }) - this.objects.push(lake, lake2) - } - - initTrees(count: number) { - for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() - const size = getRandomInRange(75, 90) - const tree = new Tree({ - scene: this.scene, - x: point.x, - y: point.y, - size, - resource: 1, - health: 20, - variant: this.area.theme, - }) - this.objects.push(tree) - } - } - - initStones(count: number) { - for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() - const stone = new Stone({ - scene: this.scene, - x: point.x, - y: point.y, - resource: 1 - }) - this.objects.push(stone) - } - } -} diff --git a/apps/client/src/game/chunks/village.ts b/apps/client/src/game/chunks/village.ts deleted file mode 100644 index 8c6e65f1..00000000 --- a/apps/client/src/game/chunks/village.ts +++ /dev/null @@ -1,418 +0,0 @@ -import { - type IGameChunkTheme, - type IGameObjectFlag, - type IGameVillageChunk, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Flag, Stone, Tree } from "../objects" -import { Campfire } from "../objects/buildings/campfire" -import { ConstructionArea } from "../objects/buildings/constructionArea" -import { Store } from "../objects/buildings/store" -import { WagonStop } from "../objects/buildings/wagonStop" -import { Warehouse } from "../objects/buildings/warehouse" -import { Courier, Farmer } from "../objects/units" -import type { GameScene } from "../scenes/gameScene" -import { BuildScript } from "../scripts/buildScript" -import { ChopTreeScript } from "../scripts/chopTreeScript" -import { MoveToTargetScript } from "../scripts/moveToTargetScript" -import { - PlaceItemInWarehouseScript -} from "../scripts/placeItemInWarehouseScript" -import { PlantNewTreeScript } from "../scripts/plantNewTreeScript" -import { GameChunk } from "./gameChunk" - -interface IVillageOptions { - scene: GameScene - width: number - height: number - center: IGameVillageChunk["center"] - theme: IGameChunkTheme -} - -export class Village extends GameChunk implements IGameVillageChunk { - constructor({ width, height, center, theme, scene }: IVillageOptions) { - super({ title: "", type: "VILLAGE", theme, width, height, center, scene }) - - this.title = this.getRandomTitle() - - this.initFlags("RESOURCE", 80) - //this.initFlags("MOVEMENT", 30) - this.initTrees(20) - this.initStones(5) - - this.initCourier(1) - this.initFarmer(1) - this.initBuildings() - } - - live() { - super.live() - - for (const object of this.objects) { - if (object instanceof Farmer && !object.script) { - this.addTaskToFarmer(object) - continue - } - - if (object instanceof Courier && !object.script) { - this.addTaskToCourier(object) - } - } - } - - addTaskToCourier(object: Courier) { - const random = getRandomInRange(1, 500) - if (random !== 1) { - return - } - - // Need to build Store - const warehouse = this.getWarehouse() - const store = this.getStore() - const wood = warehouse?.getItemByType("WOOD") - if (wood?.amount && wood.amount >= 25 && !store) { - // Let's build! - const target = this.getConstructionArea() - if (!target) { - return - } - - const buildFunc = (): boolean => { - warehouse?.inventory.reduceOrDestroyItem("WOOD", 25) - this.buildStore() - - return true - } - object.script = new BuildScript({ - object, - target, - buildFunc, - }) - - return - } - - // If unit have smth in inventory - const item = object.inventory.checkIfAlreadyHaveItem("WOOD") - if (item) { - const target = this.getWarehouse() - if (!target) { - return - } - - const placeItemFunc = () => { - if (object.target instanceof Warehouse) { - void object.target.inventory.addOrCreateItem(item.type, item.amount) - void object.inventory.destroyItem(item.id) - } - } - object.script = new PlaceItemInWarehouseScript({ - object, - target, - placeItemFunc, - }) - - return - } - - // If there is an available tree - const availableTree = this.getAvailableTree() - if (availableTree) { - const chopTreeFunc = (): boolean => { - object.chopTree() - if (!object.target || object.target.state === "DESTROYED") { - object.state = "IDLE" - if (object.target instanceof Tree) { - void object.inventory.addOrCreateItem( - "WOOD", - object.target?.resource, - ) - } - return true - } - return false - } - - object.script = new ChopTreeScript({ - object, - target: availableTree, - chopTreeFunc, - }) - - return - } - - const target = this.getRandomMovementFlagInVillage() - if (!target) { - return - } - object.script = new MoveToTargetScript({ - object, - target, - }) - } - - addTaskToFarmer(object: Farmer) { - const target = this.checkIfNeedToPlantTree() - if (target) { - const plantNewTreeFunc = () => { - this.plantNewTree(target) - } - - object.script = new PlantNewTreeScript({ - object, - target, - plantNewTreeFunc, - }) - return - } - - // No Trees needed? - const random = getRandomInRange(1, 300) - if (random <= 1) { - const target = this.getRandomMovementFlagInVillage() - if (!target) { - return - } - object.script = new MoveToTargetScript({ - object, - target, - }) - return - } - } - - initFlag(type: IGameObjectFlag["type"]) { - const randomPoint = this.getRandomPoint() - this.objects.push( - new Flag({ - scene: this.scene, - type, - x: randomPoint.x, - y: randomPoint.y, - }), - ) - } - - initFlags(type: IGameObjectFlag["type"], count: number) { - for (let i = 0; i < count; i++) { - this.initFlag(type) - } - } - - initTrees(count: number) { - for (let i = 0; i < count; i++) { - const flag = this.getRandomEmptyResourceFlagInVillage() - if (flag) { - const size = getRandomInRange(65, 85) - const tree = new Tree({ - scene: this.scene, - x: flag.x, - y: flag.y, - size, - resource: 1, - health: 20, - variant: this.area.theme, - }) - flag.target = tree - - this.objects.push(tree) - } - } - } - - initStones(count: number) { - for (let i = 0; i < count; i++) { - const flag = this.getRandomEmptyResourceFlagInVillage() - if (flag) { - const stone = new Stone({ - scene: this.scene, - x: flag.x, - y: flag.y, - resource: 1, - }) - flag.target = stone - this.objects.push(stone) - } - } - } - - initCourier(count = 1) { - for (let i = 0; i < count; i++) { - const randomPoint = this.getRandomPoint() - const courier = new Courier({ - scene: this.scene, - x: randomPoint.x, - y: randomPoint.y, - }) - - this.objects.push(courier) - } - } - - initFarmer(count = 1) { - for (let i = 0; i < count; i++) { - const randomPoint = this.getRandomPoint() - const farmer = new Farmer({ - scene: this.scene, - x: randomPoint.x, - y: randomPoint.y, - }) - - this.objects.push(farmer) - } - } - - initBuildings() { - const campfire = new Campfire({ - scene: this.scene, - x: this.center.x, - y: this.center.y, - }) - - const warehouse = new Warehouse({ - scene: this.scene, - x: this.center.x + 270, - y: this.center.y - 150, - }) - - const wagonStop = new WagonStop({ - scene: this.scene, - x: this.center.x - 780, - y: this.center.y + 380, - }) - - const constructionArea = new ConstructionArea({ - scene: this.scene, - x: this.center.x + 600, - y: this.center.y + 250, - }) - - this.objects.push(campfire, warehouse, wagonStop, constructionArea) - } - - buildStore() { - const constructionArea = this.getConstructionArea() - if (!constructionArea) { - return - } - - constructionArea.state = "DESTROYED" - - this.removeObject(constructionArea) - this.objects.push( - new Store({ - scene: this.scene, - x: constructionArea.x, - y: constructionArea.y, - }), - ) - } - - getWarehouse() { - return this.objects.find((b) => b instanceof Warehouse) as - | Warehouse - | undefined - } - - getStore() { - return this.objects.find((b) => b instanceof Store) as Store | undefined - } - - getConstructionArea() { - return this.objects.find((b) => b instanceof ConstructionArea) as - | ConstructionArea - | undefined - } - - public getWagonStopPoint() { - for (const object of this.objects) { - if (object instanceof WagonStop) { - return { x: object.x, y: object.y } - } - } - return { x: 500, y: 500 } - } - - getRandomEmptyResourceFlagInVillage() { - const flags = this.objects.filter( - (f) => - f instanceof Flag && - f.type === "RESOURCE" && - !f.target && - !f.isReserved, - ) - return flags.length > 0 - ? (flags[Math.floor(Math.random() * flags.length)] as Flag) - : undefined - } - - getResourceFlagInVillageAmount() { - return this.objects.filter( - (f) => f instanceof Flag && f.type === "RESOURCE", - ).length - } - - getRandomMovementFlagInVillage() { - const flags = this.objects.filter( - (f) => f instanceof Flag && f.type === "MOVEMENT", - ) - return flags.length > 0 - ? flags[Math.floor(Math.random() * flags.length)] - : undefined - } - - getRandomTitle() { - const titles = [ - "Windy Peak", - "Green Grove", - "Oak Coast", - "Forest Harbor", - "Elven Forest", - "Stone Outpost", - "Watermelon Paradise", - "Magic Valley", - "Royal Haven", - "Phantom Cliff", - ] - return titles[Math.floor(Math.random() * titles.length)] - } - - checkIfNeedToPlantTree() { - const treesNow = this.objects.filter( - (t) => t instanceof Tree && t.state !== "DESTROYED", - ) - if (treesNow.length < 40) { - return this.getRandomEmptyResourceFlagInVillage() - } - } - - plantNewTree(flag: Flag) { - const tree = new Tree({ - scene: this.scene, - x: flag.x, - y: flag.y, - resource: 1, - size: 12, - health: 20, - variant: this.area.theme, - }) - - flag.target = tree - flag.isReserved = false - this.objects.push(tree) - } - - getTreesAmount() { - return this.objects.filter( - (obj) => obj instanceof Tree && obj.state !== "DESTROYED", - ).length - } - - checkIfThereAreNotEnoughTrees() { - const max = this.getResourceFlagInVillageAmount() - const now = this.getTreesAmount() - - return now < max / 3 - } -} diff --git a/apps/client/src/game/common/event.ts b/apps/client/src/game/common/event.ts deleted file mode 100644 index 62bf3704..00000000 --- a/apps/client/src/game/common/event.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { - type GameSceneType, - type IGameEvent, - getDatePlusSeconds, -} from "../../../../../packages/api-sdk/src" - -interface IEventOptions { - title: IGameEvent["title"] - description: IGameEvent["description"] - type: IGameEvent["type"] - secondsToEnd: number - scene?: GameSceneType - poll: IGameEvent["poll"] - quest: IGameEvent["quest"] - offers: IGameEvent["offers"] -} - -export class Event implements IGameEvent { - public id: string - public title: IGameEvent["title"] - public description: IGameEvent["description"] - public type: IGameEvent["type"] - public status: IGameEvent["status"] - public scene?: GameSceneType - public endsAt!: Date - public deletesAt!: Date - public poll?: IGameEvent["poll"] - public quest?: IGameEvent["quest"] - public offers?: IGameEvent["offers"] - - constructor({ - title, - description, - type, - secondsToEnd, - scene, - poll, - quest, - offers, - }: IEventOptions) { - this.id = createId() - this.title = title - this.description = description - this.type = type - this.scene = scene - this.poll = poll - this.quest = quest - this.offers = offers - this.status = "STARTED" - - this.setEndsAtPlusSeconds(secondsToEnd) - - //sendMessage(type) - } - - public checkStatus() { - if (this.endsAt.getTime() <= new Date().getTime()) { - this.status = "STOPPED" - } - if (this.deletesAt.getTime() <= new Date().getTime()) { - this.status = "STOPPED" - } - - return this.status - } - - public setEndsAtPlusSeconds(seconds: number) { - this.endsAt = getDatePlusSeconds(seconds) - this.deletesAt = getDatePlusSeconds(seconds + 30) - } -} diff --git a/apps/client/src/game/common/generators/unitName.ts b/apps/client/src/game/common/generators/unitName.ts deleted file mode 100644 index b7b6ea68..00000000 --- a/apps/client/src/game/common/generators/unitName.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const generateUnitUserName = (): string => { - const maleNames = [ - "Valto Bizu", - "Zapris Hlel", - "Sinkmire Winglace", - "Hakir Elisor", - "Mapitu Uldan", - "Aetes Shangueiros", - "Nemesion Balgran", - "Garffon Lisalor", - "Golash Aena", - "Alistair al Pair", - "Sasgix Eranal", - "Petrosque Quinal", - "Laegon Umeran", - "Hersperon Oderle", - "Callister Grafft", - "Zangard Kaalin", - "Xernes Adafin", - "Xanus Elhora", - "Alistair Chapira", - "Salvestro Elmaris", - "Elusidor Riecto", - "Usir Lierin", - "Golash Yosalr", - ] - - return maleNames[Math.floor(Math.random() * maleNames.length)] -} diff --git a/apps/client/src/game/common/generators/unitTop.ts b/apps/client/src/game/common/generators/unitTop.ts deleted file mode 100644 index 513428b5..00000000 --- a/apps/client/src/game/common/generators/unitTop.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IGameObjectUnit } from "../../../../../../packages/api-sdk/src" - -export const generateUnitTop = (): Partial< - IGameObjectUnit["visual"]["top"] -> => { - const availableTopsForUnits: IGameObjectUnit["visual"]["top"][] = [ - "GREEN_SHIRT", - "BLUE_SHIRT", - "DARK_SILVER_SHIRT", - ] - - return availableTopsForUnits[ - Math.floor(Math.random() * availableTopsForUnits.length) - ] -} diff --git a/apps/client/src/game/common/group.ts b/apps/client/src/game/common/group.ts deleted file mode 100644 index 0856dde6..00000000 --- a/apps/client/src/game/common/group.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { - IGameGroup, - IGameObjectPlayer, -} from "../../../../../packages/api-sdk/src" -import type { Player } from "../objects/units" - -export class Group implements IGameGroup { - id: string - players: IGameObjectPlayer[] = [] - - constructor() { - this.id = createId() - } - - public getGroup(): IGameGroup { - return { - id: this.id, - players: this.players.map((p) => { - return { - ...p, - script: undefined, - live: undefined, - } - }), - } - } - - join(player: Player): boolean { - const check = this.findPlayer(player.id) - if (check) { - return false - } - - this.players.push(player) - return true - } - - remove(player: IGameObjectPlayer): boolean { - const check = this.findPlayer(player.id) - if (!check) { - return false - } - - const index = this.players.indexOf(player) - this.players.splice(index, 1) - return true - } - - findPlayer(id: string) { - return this.players.find((p) => p.id === id) - } - - disband() { - this.players = [] - } -} diff --git a/apps/client/src/game/common/index.ts b/apps/client/src/game/common/index.ts deleted file mode 100644 index 07ad0570..00000000 --- a/apps/client/src/game/common/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { Inventory } from "./inventory" -export { Skill } from "./skill" -export { Event } from "./event" -export { Group } from "./group" -export { Route } from "./route" -export { Poll } from "./poll" diff --git a/apps/client/src/game/common/inventory.ts b/apps/client/src/game/common/inventory.ts deleted file mode 100644 index bf261ccb..00000000 --- a/apps/client/src/game/common/inventory.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { - IGameInventory, - IGameInventoryItem, - ItemType, -} from "../../../../../packages/api-sdk/src" -import { db } from "../../../../api/src/db/db.client" - -interface IInventoryOptions { - objectId: string - id: string - saveInDb: boolean -} - -export class Inventory implements IGameInventory { - public id: string - public objectId: string - public items: IGameInventoryItem[] = [] - public saveInDb: boolean - - constructor({ id, objectId, saveInDb }: IInventoryOptions) { - this.id = id - this.objectId = objectId - this.saveInDb = saveInDb - } - - public async init() { - await this.updateFromDB() - } - - public async destroyItem(id: string) { - const itemIndex = this.items.findIndex((i) => i.id === id) - if (itemIndex < 0) { - return - } - - this.items.splice(itemIndex, 1) - - if (this.saveInDb) { - await this.destroyItemInDB(id) - } - } - - public async reduceOrDestroyItem(type: ItemType, amount: number) { - const item = this.checkIfAlreadyHaveItem(type) - if (!item) { - return false - } - - if (amount > item.amount) { - return false - } - - if (amount === item.amount) { - await this.destroyItem(item.id) - return true - } - - if (this.saveInDb) { - await this.decrementAmountOfItemInDB(item.id, amount) - } - - item.amount -= amount - return true - } - - public async addOrCreateItem(type: ItemType, amount: number) { - if (this.saveInDb) { - return this.addOrCreateItemInDB(type, amount) - } - - const item = this.checkIfAlreadyHaveItem(type) - if (!item) { - this.createItem(type, amount) - return - } - - item.amount += amount - } - - async addOrCreateItemInDB(type: ItemType, amount: number) { - const item = await this.checkIfAlreadyHaveItemInDB(this.id, type) - if (!item) { - await this.createItemInDB(this.id, type, amount) - await this.updateFromDB() - return - } - - await this.incrementAmountOfItemInDB(item.id, amount) - await this.updateFromDB() - } - - async destroyItemInDB(id: string) { - await db.inventoryItem.delete({ - where: { id }, - }) - await this.updateFromDB() - } - - public tryGetItemInDB(type: ItemType) { - return this.checkIfAlreadyHaveItemInDB(this.id, type) - } - - async checkAndBreakItem(item: IGameInventoryItem, decrement: number) { - if (item.durability <= decrement) { - await this.destroyItemInDB(item.id) - await this.updateFromDB() - return - } - - item.durability -= decrement - await db.inventoryItem.update({ - where: { id: item.id }, - data: { - durability: { decrement }, - }, - }) - } - - createItemInDB(inventoryId: string, type: ItemType, amount: number) { - return db.inventoryItem.create({ - data: { - id: createId(), - type, - inventoryId, - amount, - }, - }) - } - - incrementAmountOfItemInDB(id: string, amount: number) { - return db.inventoryItem.update({ - where: { id }, - data: { - amount: { - increment: amount, - }, - }, - }) - } - - decrementAmountOfItemInDB(id: string, amount: number) { - return db.inventoryItem.update({ - where: { id }, - data: { - amount: { - decrement: amount, - }, - }, - }) - } - - checkIfAlreadyHaveItemInDB(inventoryId: string, type: ItemType) { - return db.inventoryItem.findFirst({ - where: { inventoryId, type }, - }) - } - - checkIfAlreadyHaveItem(type: ItemType) { - return this.items.find((item) => item.type === type) - } - - createItem(type: ItemType, amount: number) { - const item: IGameInventoryItem = { - id: createId(), - createdAt: new Date(), - updatedAt: new Date(), - type, - amount, - durability: 100, - inventoryId: "", - } - this.items.push(item) - } - - async updateFromDB() { - const items = await db.inventoryItem.findMany({ - where: { inventoryId: this.id }, - }) - this.items = items as IGameInventoryItem[] - } -} diff --git a/apps/client/src/game/common/poll.ts b/apps/client/src/game/common/poll.ts deleted file mode 100644 index 96c8308d..00000000 --- a/apps/client/src/game/common/poll.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { - type IGameObjectPlayer, - type IGamePoll, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { VoteAction } from "../actions/voteAction" -import type { GameScene } from "../scenes/gameScene" - -interface IPollOptions { - scene: GameScene - votesToSuccess: IGamePoll["votesToSuccess"] -} - -export class Poll implements IGamePoll { - public id: string - public status: IGamePoll["status"] - public action: IGamePoll["action"] - public votesToSuccess: IGamePoll["votesToSuccess"] - public votes: IGamePoll["votes"] = [] - - public scene: GameScene - - constructor({ votesToSuccess, scene }: IPollOptions) { - this.scene = scene - - this.id = createId() - this.status = "ACTIVE" - this.votesToSuccess = votesToSuccess - - this.action = new VoteAction({ poll: this }) - } - - public vote(player: IGameObjectPlayer): boolean { - if (this.votes.find((v) => v.id === player.id)) { - return false - } - - this.votes.push({ id: player.id, userName: player.userName }) - return true - } - - public generatePollId(): string { - const id = getRandomInRange(1, 9).toString() - for (const event of this.scene.eventService.events) { - if (event.poll?.action.command === `go ${id}`) { - return this.generatePollId() - } - } - return id - } -} diff --git a/apps/client/src/game/common/route.ts b/apps/client/src/game/common/route.ts deleted file mode 100644 index dfff415c..00000000 --- a/apps/client/src/game/common/route.ts +++ /dev/null @@ -1,159 +0,0 @@ -import type { - IGameChunk, - IGameRoute, -} from "../../../../../packages/api-sdk/src" -import { Flag } from "../objects" -import type { GameScene } from "../scenes/gameScene" - -interface IRoutePoint { - x: number - y: number -} - -interface IRouteArea { - startX: number - endX: number - startY: number - endY: number -} - -interface IRouteOptions { - scene: GameScene -} - -export class Route implements IGameRoute { - public startPoint!: IRoutePoint - public endPoint!: IRoutePoint - public chunks: IGameChunk[] = [] - - public scene: GameScene - public flags: Flag[] = [] - public areas: IRouteArea[] = [] - - constructor({ scene }: IRouteOptions) { - this.scene = scene - } - - public addChunk(chunk: IGameChunk) { - this.chunks.push({ - id: chunk.id, - type: chunk.type, - title: chunk.title, - center: chunk.center, - area: chunk.area, - }) - } - - public setEndPoint({ x, y }: IRoutePoint) { - this.endPoint = { x, y } - } - - public addFlag({ x, y }: IRoutePoint) { - const movementFlag = new Flag({ - scene: this.scene, - type: "WAGON_MOVEMENT", - x, - y, - }) - - const prevFlag = this.flags[this.flags.length - 1] - if (prevFlag) { - this.initArea(prevFlag, movementFlag) - } - - this.flags.push(movementFlag) - } - - public addGlobalFlag(end: IRoutePoint) { - const prevGlobalFlag = this.flags[this.flags.length - 1] - if (!prevGlobalFlag) { - return this.addFlag(end) - } - - this.generatePath({ x: prevGlobalFlag.x, y: prevGlobalFlag.y }, end) - this.addFlag({ x: end.x, y: end.y }) - } - - public getNextFlag() { - return this.flags[0] - } - - public removeFlag(flag: Flag) { - const index = this.flags.findIndex((f) => f.id === flag.id) - if (index >= 0) { - this.flags.splice(index, 1) - } - } - - public initArea(flag1: Flag, flag2: Flag) { - const offset = 150 - const halfOffset = offset / 2 - - const startX = Math.min(flag1.x, flag2.x) - offset - const endX = Math.max(flag1.x, flag2.x) + offset - - const startY = Math.min(flag1.y, flag2.y) - halfOffset - const endY = Math.max(flag1.y, flag2.y) + halfOffset - - const area = { - startX, - endX, - startY, - endY, - } - - this.areas.push(area) - } - - private isInArea(area: IRouteArea, point: IRoutePoint) { - return ( - area.startX < point.x && - point.x < area.endX && - area.startY < point.y && - point.y < area.endY - ) - } - - public checkIfPointIsOnWagonPath(point: IRoutePoint) { - for (const area of this.areas) { - if (this.isInArea(area, point)) { - return true - } - } - - return false - } - - generatePath(start: IRoutePoint, end: IRoutePoint) { - const pathDistance = Route.getDistanceBetween2Points(start, end) - console.log("path", pathDistance) - - const pointsCount = Math.round(pathDistance / 150) + 1 - console.log("points between", pointsCount) - - const stepX = Math.round((end.x - start.x) / pointsCount) - const stepY = Math.round((end.y - start.y) / pointsCount) - - let nowX = start.x - let nowY = start.y - - for (let i = 0; i < pointsCount; i++) { - nowX += stepX - nowY += stepY - this.addFlag({ x: nowX, y: nowY }) - } - } - - public static getDistanceBetween2Points( - point1: { - x: number - y: number - }, - point2: { - x: number - y: number - }, - ) { - return Math.sqrt((point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2) - } -} diff --git a/apps/client/src/game/common/skill.ts b/apps/client/src/game/common/skill.ts deleted file mode 100644 index e15d5195..00000000 --- a/apps/client/src/game/common/skill.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { IGameSkill } from "../../../../../packages/api-sdk/src" -import { db } from "../../../../api/src/db/db.client" - -interface ISkillOptions { - id: string -} - -export class Skill implements IGameSkill { - public id: string - public objectId: string | null = null - public type!: IGameSkill["type"] - - public lvl = 0 - public xp = 0 - public xpNextLvl = 0 - - constructor({ id }: ISkillOptions) { - this.id = id - } - - public async init() { - await this.readFromDB() - } - - public async addXp(increment = 1) { - this.xp += increment - - if (this.xp >= this.xpNextLvl) { - await this.lvlUpInDB() - await this.init() - return - } - - return db.skill.update({ - where: { id: this.id }, - data: { xp: { increment } }, - }) - } - - public lvlUpInDB() { - const xpNextLvl = Math.floor(this.xpNextLvl * 1.5) - return db.skill.update({ - where: { id: this.id }, - data: { - lvl: { increment: 1 }, - xp: 0, - xpNextLvl, - }, - }) - } - - async readFromDB() { - const skill = await db.skill.findUnique({ - where: { id: this.id }, - }) - if (!skill) { - return - } - - this.objectId = skill.objectId - this.type = skill.type as IGameSkill["type"] - this.lvl = skill.lvl - this.xp = skill.xp - this.xpNextLvl = skill.xpNextLvl - } - - public static async findAllInDB(objectId: string) { - return db.skill.findMany({ - where: { objectId }, - }) - } - - public static createInDB(objectId: string, type: IGameSkill["type"]) { - return db.skill.create({ - data: { - id: createId(), - objectId, - type, - }, - }) - } -} diff --git a/apps/client/src/game/components/buildingInterface.ts b/apps/client/src/game/components/buildingInterface.ts deleted file mode 100644 index 252a38e1..00000000 --- a/apps/client/src/game/components/buildingInterface.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectBuilding } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -export class BuildingInterface extends GraphicsContainer { - public building: IGameObjectBuilding - - public wood: number | undefined - public stone: number | undefined - - constructor(building: IGameObjectBuilding) { - super({ type: "INTERFACE" }) - - this.x = 0 - this.y = 0 - - this.building = building - - this.init() - } - - init() { - this.wood = - this.building.inventory.items.find((item) => item.type === "WOOD") - ?.amount ?? 0 - this.stone = - this.building.inventory.items.find((item) => item.type === "STONE") - ?.amount ?? 0 - - this.drawWood() - this.drawStone() - } - - rebuild() { - this.removeChild(...this.children) - this.drawWood() - this.drawStone() - } - - animate() { - this.visible = true - this.update() - } - - update() { - const wood = this.building.inventory.items.find( - (item) => item.type === "WOOD", - )?.amount - const stone = this.building.inventory.items.find( - (item) => item.type === "STONE", - )?.amount - - if (wood !== this.wood || stone !== this.stone) { - this.wood = wood - this.stone = stone - this.rebuild() - } - - this.wood = wood - this.stone = stone - } - - drawWood() { - if (!this.wood || this.wood <= 0) { - return - } - - const container = new GraphicsContainer({ type: "PLAYER_COINS" }) - - const woodSprite = Sprite.from("wood1") - woodSprite.width = 48 - woodSprite.height = 48 - - // const basicText = new Text({ - // text: this.wood, - // style: { - // fontSize: 16, - // fill: 0xfef3c7, - // align: "left", - // }, - // }) - // - // basicText.x = 14 - // basicText.y = 26 - - container.addChild(woodSprite) - - container.x = -50 - container.y = -74 - - this.addChild(container) - } - - drawStone() { - if (!this.stone || this.stone <= 0) { - return - } - - const container = new GraphicsContainer({ type: "PLAYER_COINS" }) - - const sprite = Sprite.from("stoneRes1") - sprite.width = 48 - sprite.height = 48 - - // const basicText = new Text({ - // text: this.stone, - // style: { - // fontSize: 16, - // fill: 0xfef3c7, - // align: "left", - // }, - // }) - // - // basicText.x = 14 - // basicText.y = 26 - - container.addChild(sprite) - - container.x = 4 - container.y = -74 - - this.addChild(container) - } -} diff --git a/apps/client/src/game/components/dialogueInterface.ts b/apps/client/src/game/components/dialogueInterface.ts deleted file mode 100644 index 8492b67b..00000000 --- a/apps/client/src/game/components/dialogueInterface.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { type Container, Graphics, Text } from "pixi.js" -import type { IGameObjectUnit } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -export class DialogueInterface extends GraphicsContainer { - public unit: IGameObjectUnit - public messages: { id: string; text: string; isShowed: boolean }[] - public showingSpeed: number - - constructor(unit: IGameObjectUnit) { - super({ type: "INTERFACE" }) - - this.unit = unit - this.messages = [] - - this.showingSpeed = 0.0005 - - this.x = 0 - this.y = 0 - } - - create(message: { id: string; text: string }) { - const container = new GraphicsContainer({ type: "INTERFACE" }) - - const basicText = new Text({ - text: message.text, - style: { - fontFamily: "Noto Serif", - fontSize: 16, - fontWeight: "500", - fill: 0x694f62, - align: "left", - wordWrap: true, - wordWrapWidth: 300, - }, - }) - - const rectOffsetX = 8 - const rectOffsetY = 4 - const rectWidth = basicText.width + rectOffsetX * 2 - const rectHeight = basicText.height + rectOffsetY * 2 - - const graphics = new Graphics() - graphics.roundRect(-rectOffsetX, -rectOffsetY, rectWidth, rectHeight, 8) - graphics.fill(0xffffff) - - container.addChild(graphics, basicText) - - container.x = -container.width / 2 + 8 - container.y = -container.height - 75 - - this.addChild(container) - } - - remove(container: Container) { - return this.removeChild(container) - } - - animate() { - this.visible = true - this.zIndex = 0 - - // Add new messages to show - if (this.unit?.dialogue?.messages) { - for (const message of this.unit.dialogue.messages) { - const existed = this.messages.find((m) => m.id === message.id) - if (!existed) { - this.messages.push({ ...message, isShowed: false }) - } - } - } - - // If no active - create new show block! - const needToShowMessages = this.messages.filter((m) => !m.isShowed) - if (needToShowMessages.length > 0 && this.children.length <= 0) { - this.create(needToShowMessages[0]) - - needToShowMessages[0].isShowed = true - this.showingSpeed = this.getShowingSpeed( - needToShowMessages[0].text.length, - ) - } - - for (const container of this.children) { - container.visible = true - container.zIndex = 0 - container.alpha -= this.showingSpeed - - if (container.alpha <= 0.8) { - this.remove(container) - } - } - } - - getShowingSpeed(messageLength: number) { - return 0.0006 - (messageLength * 4) / 1000000 - } -} diff --git a/apps/client/src/game/components/fireParticlesContainer.ts b/apps/client/src/game/components/fireParticlesContainer.ts deleted file mode 100644 index 42495f71..00000000 --- a/apps/client/src/game/components/fireParticlesContainer.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Sprite } from "pixi.js" -import { getRandomInRange } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IFireParticlesContainerOptions { - x: number - y: number - areaWidth: number -} - -export class FireParticlesContainer extends GraphicsContainer { - public areaWidth: number - public offset = 0 - - constructor({ x, y, areaWidth }: IFireParticlesContainerOptions) { - super({ type: "FIRE_PARTICLE", direction: "LEFT" }) - - this.x = x - this.y = y - this.areaWidth = areaWidth - } - - createRandom() { - const sprite = Sprite.from(this.getRandomSpriteIndex()) - sprite.anchor.set(0.5, 1) - - const half = this.width / 2 - sprite.x = getRandomInRange(-half, half) - sprite.scale = getRandomInRange(10, 20) / 10 - - this.addChild(sprite) - } - - getRandomSpriteIndex() { - const random = getRandomInRange(1, 1000) - if (random <= 500) { - return "fireParticle1" - } - if (random <= 750) { - return "fireParticle2" - } - return "fireParticle3" - } - - animate(power = 1) { - this.offset -= power + 1 - - const activeNow = power * 8 + 1 - const canCreate = this.children.length < activeNow && this.offset <= 0 - if (canCreate) { - this.createRandom() - this.offset = power * getRandomInRange(90, 110) + 3 - } - - for (const container of this.children) { - container.visible = true - - container.y -= 0.28 - container.alpha -= 0.008 - - if (container.alpha <= 0) { - this.removeChild(container) - } - } - } -} diff --git a/apps/client/src/game/components/graphicsContainer.ts b/apps/client/src/game/components/graphicsContainer.ts deleted file mode 100644 index 42c8c421..00000000 --- a/apps/client/src/game/components/graphicsContainer.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Container, Sprite } from "pixi.js" -import type { - GraphicsContainerType, - IGameObjectDirection, -} from "../../../../../packages/api-sdk/src" - -interface IGraphicsContainerOptions { - type: GraphicsContainerType - direction?: IGameObjectDirection -} - -export class GraphicsContainer extends Container { - public type: GraphicsContainerType - public direction: IGameObjectDirection = "RIGHT" - - constructor({ type, direction }: IGraphicsContainerOptions) { - super() - this.type = type - - if (direction) { - this.direction = direction - } - } - - static createWithSprite( - spriteIndex: string, - direction: IGameObjectDirection, - type: GraphicsContainerType, - ) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 1) - - const container = new GraphicsContainer({ type, direction }) - container.addChild(sprite) - - return container - } -} diff --git a/apps/client/src/game/components/unitHairContainer.ts b/apps/client/src/game/components/unitHairContainer.ts deleted file mode 100644 index 8ec6fc92..00000000 --- a/apps/client/src/game/components/unitHairContainer.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Sprite } from "pixi.js" -import type { - IGameObjectDirection, - IGameObjectUnit, -} from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IUnitHairContainerOptions { - direction: IGameObjectDirection - visual: IGameObjectUnit["visual"]["hairstyle"] -} - -export class UnitHairContainer extends GraphicsContainer { - public visual: IGameObjectUnit["visual"]["hairstyle"] - - constructor({ direction, visual }: IUnitHairContainerOptions) { - super({ type: "UNIT_HAIR", direction }) - this.visual = visual - } - - static create( - spriteIndex: string, - direction: IGameObjectDirection, - visual: IGameObjectUnit["visual"]["hairstyle"], - ) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 1) - - if (direction === "LEFT") { - // Flip horizontally - sprite.scale.x = -1 - } - - const container = new UnitHairContainer({ direction, visual }) - container.addChild(sprite) - - return container - } - - static createWithBothDirections( - spriteIndex: string, - visual: IGameObjectUnit["visual"]["hairstyle"], - ) { - const containers = [] - - containers.push(UnitHairContainer.create(spriteIndex, "LEFT", visual)) - containers.push(UnitHairContainer.create(spriteIndex, "RIGHT", visual)) - - return containers - } - - static getAll() { - return [ - ...UnitHairContainer.createWithBothDirections( - "unitHairClassic", - "CLASSIC", - ), - ...UnitHairContainer.createWithBothDirections( - "unitHairCoalLong", - "COAL_LONG", - ), - ...UnitHairContainer.createWithBothDirections( - "unitHairOrangeWithBeard", - "ORANGE_WITH_BEARD", - ), - ] - } -} diff --git a/apps/client/src/game/components/unitHeadContainer.ts b/apps/client/src/game/components/unitHeadContainer.ts deleted file mode 100644 index 3273f695..00000000 --- a/apps/client/src/game/components/unitHeadContainer.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Sprite } from "pixi.js" -import type { - IGameObjectDirection, - IGameObjectUnit, -} from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IUnitHeadContainerOptions { - direction: IGameObjectDirection - visual: IGameObjectUnit["visual"]["head"] -} - -export class UnitHeadContainer extends GraphicsContainer { - public visual: IGameObjectUnit["visual"]["head"] - - constructor({ direction, visual }: IUnitHeadContainerOptions) { - super({ type: "UNIT_HEAD", direction }) - this.visual = visual - } - - static create( - spriteIndex: string, - direction: IGameObjectDirection, - visual: IGameObjectUnit["visual"]["head"], - ) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 1) - - if (direction === "LEFT") { - // Flip horizontally - sprite.scale.x = -1 - } - - const container = new UnitHeadContainer({ direction, visual }) - container.addChild(sprite) - - return container - } - - static createWithBothDirections( - spriteIndex: string, - visual: IGameObjectUnit["visual"]["head"], - ) { - const containers = [] - - containers.push(UnitHeadContainer.create(spriteIndex, "LEFT", visual)) - containers.push(UnitHeadContainer.create(spriteIndex, "RIGHT", visual)) - - return containers - } - - static getAll() { - return [...UnitHeadContainer.createWithBothDirections("unitHead1", "1")] - } -} diff --git a/apps/client/src/game/components/unitInterface.ts b/apps/client/src/game/components/unitInterface.ts deleted file mode 100644 index 35f8b2cb..00000000 --- a/apps/client/src/game/components/unitInterface.ts +++ /dev/null @@ -1,317 +0,0 @@ -import { Graphics, Sprite, Text } from "pixi.js" -import type { IGameObjectUnit } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -export class UnitInterface extends GraphicsContainer { - public children: GraphicsContainer[] = [] - public unit: IGameObjectUnit - - public userName = "" - public coins = 0 - public wood = 0 - public stone = 0 - - public showInHandItemIndex = 0 - public showInHandTimerSeconds = 0 - public showToolTimerSeconds = 0 - public showWood = false - public showStone = false - - public haveAxe = false - public showAxe = false - public havePickaxe = false - public showPickaxe = false - - constructor(unit: IGameObjectUnit) { - super({ type: "INTERFACE" }) - - this.x = -15 - this.y = 5 - - this.unit = unit - - this.init() - } - - init() { - this.coins = this.unit.coins - this.wood = - this.unit.inventory.items.find((item) => item.type === "WOOD")?.amount ?? - 0 - this.stone = - this.unit.inventory.items.find((item) => item.type === "STONE")?.amount ?? - 0 - - this.haveAxe = !!this.unit.inventory.items.find( - (item) => item.type === "AXE", - ) - this.havePickaxe = !!this.unit.inventory.items.find( - (item) => item.type === "PICKAXE", - ) - - this.drawUserName() - this.drawWood() - this.drawStone() - this.drawAxe() - this.drawPickaxe() - - this.setShowInHandTimer() - this.setShowToolTimer() - } - - rebuild() { - this.removeChild(...this.children) - this.drawUserName() - this.drawWood() - this.drawStone() - this.drawAxe() - this.drawPickaxe() - this.showInHandTimerSeconds = 0 - } - - update() { - const userName = this.unit.userName - const wood = - this.unit.inventory.items.find((item) => item.type === "WOOD")?.amount ?? - 0 - const stone = - this.unit.inventory.items.find((item) => item.type === "STONE")?.amount ?? - 0 - const haveAxe = !!this.unit.inventory.items.find( - (item) => item.type === "AXE", - ) - const havePickaxe = !!this.unit.inventory.items.find( - (item) => item.type === "PICKAXE", - ) - - if ( - userName !== this.userName || - this.unit.coins !== this.coins || - wood !== this.wood || - stone !== this.stone || - haveAxe !== this.haveAxe || - havePickaxe !== this.havePickaxe - ) { - this.userName = userName - this.coins = this.unit.coins - this.wood = wood - this.stone = stone - this.haveAxe = haveAxe - this.havePickaxe = havePickaxe - this.rebuild() - } - - this.userName = this.unit.userName - this.coins = this.unit.coins - this.wood = wood - this.stone = stone - this.haveAxe = haveAxe - this.havePickaxe = havePickaxe - } - - animate() { - this.visible = true - this.update() - - for (const container of this.children) { - container.visible = true - - if (container.type === "PLAYER_COINS") { - if (!this.coins) { - container.visible = false - } - } - - if (container.type === "PLAYER_WOOD") { - if (this.wood <= 0 || !this.showWood) { - container.visible = false - } - } - - if (container.type === "PLAYER_STONE") { - if (this.stone <= 0 || !this.showStone) { - container.visible = false - } - } - - if (container.type === "PLAYER_AXE") { - if (!this.haveAxe || !this.showAxe) { - container.visible = false - } - } - - if (container.type === "PLAYER_PICKAXE") { - if (!this.havePickaxe || !this.showPickaxe) { - container.visible = false - } - } - } - } - - drawUserName() { - if (!this.unit.userName) { - return - } - - const container = new GraphicsContainer({ type: "INTERFACE" }) - - const basicText = new Text({ - text: this.unit.userName, - style: { - fontFamily: "Noto Serif", - fontSize: 14, - fontWeight: "600", - fill: 0x451a03, - align: "center", - }, - }) - - const graphics = new Graphics() - graphics.roundRect(-6, -2, basicText.width + 12, basicText.height + 4, 0) - graphics.fill(0xfef3c7) - - container.addChild(graphics, basicText) - - container.x = -container.width / 2 + 24 - container.y = -84 - - this.addChild(container) - } - - drawWood() { - const container = new GraphicsContainer({ type: "PLAYER_WOOD" }) - - const woodSprite = Sprite.from("wood1") - woodSprite.width = 32 - woodSprite.height = 32 - - container.addChild(woodSprite) - - container.x = -18 - container.y = -48 - - this.addChild(container) - } - - drawStone() { - const container = new GraphicsContainer({ type: "PLAYER_STONE" }) - - const woodSprite = Sprite.from("stoneRes1") - woodSprite.width = 32 - woodSprite.height = 32 - - container.addChild(woodSprite) - - container.x = -18 - container.y = -48 - - this.addChild(container) - } - - drawAxe() { - const container = new GraphicsContainer({ type: "PLAYER_AXE" }) - - const sprite = Sprite.from("toolAxe1") - sprite.width = 64 - sprite.height = 64 - - container.addChild(sprite) - - container.x = -10 - container.y = -68 - - this.addChild(container) - } - - drawPickaxe() { - const container = new GraphicsContainer({ type: "PLAYER_PICKAXE" }) - - const sprite = Sprite.from("toolPickaxe1") - sprite.width = 64 - sprite.height = 64 - - container.addChild(sprite) - - container.x = -10 - container.y = -68 - - this.addChild(container) - } - - showWoodInHand() { - this.showWood = true - } - - showStoneInHand() { - this.showStone = true - } - - showAxeInHand() { - this.showAxe = true - this.showToolTimerSeconds = 5 - } - - showPickaxeInHand() { - this.showPickaxe = true - this.showToolTimerSeconds = 5 - } - - setShowInHandTimer() { - return setInterval(() => { - if (this.showInHandTimerSeconds <= 0) { - this.showNextItem() - return - } - - this.showInHandTimerSeconds -= 1 - }, 1000) - } - - setShowToolTimer() { - return setInterval(() => { - if (this.showToolTimerSeconds <= 0) { - this.showAxe = false - this.showPickaxe = false - return - } - - this.showToolTimerSeconds -= 1 - }) - } - - getResourcesArray() { - return this.unit.inventory.items.filter( - (item) => item.type === "WOOD" || item.type === "STONE", - ) - } - - showNextItem() { - const items = this.getResourcesArray() - if (!items) { - return - } - - if (items.length < this.showInHandItemIndex + 1) { - this.showInHandItemIndex = 0 - } - - this.showWood = false - this.showStone = false - this.showInHandTimerSeconds = 5 - - if (!items[this.showInHandItemIndex]?.type) { - return - } - - switch (items[this.showInHandItemIndex].type) { - case "WOOD": - this.showWoodInHand() - break - case "STONE": - this.showStoneInHand() - break - } - - this.showInHandItemIndex += 1 - } -} diff --git a/apps/client/src/game/components/unitTopContainer.ts b/apps/client/src/game/components/unitTopContainer.ts deleted file mode 100644 index 03236b85..00000000 --- a/apps/client/src/game/components/unitTopContainer.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Sprite } from "pixi.js" -import type { - IGameObjectDirection, - IGameObjectUnit, -} from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IUnitTopContainerOptions { - direction: IGameObjectDirection - visual: IGameObjectUnit["visual"]["top"] -} - -export class UnitTopContainer extends GraphicsContainer { - public visual: IGameObjectUnit["visual"]["top"] - - constructor({ direction, visual }: IUnitTopContainerOptions) { - super({ type: "UNIT_TOP", direction }) - this.visual = visual - } - - static create( - spriteIndex: string, - direction: IGameObjectDirection, - visual: IGameObjectUnit["visual"]["top"], - ) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 1) - - if (direction === "LEFT") { - // Flip horizontally - sprite.scale.x = -1 - } - - const container = new UnitTopContainer({ direction, visual }) - container.addChild(sprite) - - return container - } - - static createWithBothDirections( - spriteIndex: string, - visual: IGameObjectUnit["visual"]["top"], - ) { - const containers = [] - - containers.push(UnitTopContainer.create(spriteIndex, "LEFT", visual)) - containers.push(UnitTopContainer.create(spriteIndex, "RIGHT", visual)) - - return containers - } - - static getAll() { - return [ - ...UnitTopContainer.createWithBothDirections("violetTop", "VIOLET_SHIRT"), - ...UnitTopContainer.createWithBothDirections("blackTop", "BLACK_SHIRT"), - ...UnitTopContainer.createWithBothDirections("greenTop", "GREEN_SHIRT"), - ...UnitTopContainer.createWithBothDirections("blueTop", "BLUE_SHIRT"), - ...UnitTopContainer.createWithBothDirections( - "darkSilverTop", - "DARK_SILVER_SHIRT", - ), - ] - } -} diff --git a/apps/client/src/game/components/wagonCargoContainer.ts b/apps/client/src/game/components/wagonCargoContainer.ts deleted file mode 100644 index bceba39b..00000000 --- a/apps/client/src/game/components/wagonCargoContainer.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Sprite } from "pixi.js" -import { GraphicsContainer } from "./graphicsContainer" - -export class WagonCargoContainer extends GraphicsContainer { - constructor() { - super({ type: "WAGON_CARGO", direction: "RIGHT" }) - } - - static create() { - const chest1 = Sprite.from("chest1") - chest1.anchor.set(0.5, 1) - chest1.visible = false - - const container = new WagonCargoContainer() - container.addChild(chest1) - - container.x = 72 - container.y = -56 - - return container - } -} diff --git a/apps/client/src/game/components/wagonEngineCloudsContainer.ts b/apps/client/src/game/components/wagonEngineCloudsContainer.ts deleted file mode 100644 index 5c690636..00000000 --- a/apps/client/src/game/components/wagonEngineCloudsContainer.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { type Container, Sprite } from "pixi.js" -import { getRandomInRange } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -export class WagonEngineCloudsContainer extends GraphicsContainer { - public offset = 0 - - constructor() { - super({ type: "WAGON_ENGINE_CLOUD", direction: "LEFT" }) - - this.x = -106 - this.y = -118 - } - - createRandom() { - const sprite = Sprite.from(this.getRandomSpriteIndex()) - sprite.anchor.set(0.5, 1) - sprite.scale = 0.75 - sprite.visible = false - - this.addChild(sprite) - } - - getRandomSpriteIndex() { - const random = getRandomInRange(1, 1000) - if (random <= 500) { - return "wagonEngineCloud1" - } - if (random <= 750) { - return "wagonEngineCloud2" - } - if (random <= 995) { - return "wagonEngineCloud3" - } - return "wagonEngineCloud4" - } - - remove(container: Container) { - return this.removeChild(container) - } - - animate(speed: number) { - this.offset -= speed + 1 - - const cloudsActive = speed * 8 + 1 - const canCreateCloud = - this.children.length < cloudsActive && this.offset <= 0 - if (canCreateCloud) { - this.createRandom() - this.offset = speed * getRandomInRange(170, 190) + 3 - } - - for (const container of this.children) { - container.visible = true - - container.x -= speed / 3 + 0.07 - container.y -= 0.06 - container.scale = 0.75 - container.alpha -= 0.005 - - if (container.alpha <= 0) { - this.remove(container) - } - } - } -} diff --git a/apps/client/src/game/components/wagonEngineContainer.ts b/apps/client/src/game/components/wagonEngineContainer.ts deleted file mode 100644 index e3089ec2..00000000 --- a/apps/client/src/game/components/wagonEngineContainer.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectDirection } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IWagonEngineContainerOptions { - direction: IGameObjectDirection -} - -export class WagonEngineContainer extends GraphicsContainer { - constructor({ direction }: IWagonEngineContainerOptions) { - super({ type: "WAGON_ENGINE", direction }) - } - - static create(spriteIndex: string, direction: IGameObjectDirection) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 1) - - const container = new WagonEngineContainer({ direction }) - container.addChild(sprite) - - return container - } -} diff --git a/apps/client/src/game/components/wagonFuelBoxContainer.ts b/apps/client/src/game/components/wagonFuelBoxContainer.ts deleted file mode 100644 index 5042cdcc..00000000 --- a/apps/client/src/game/components/wagonFuelBoxContainer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Sprite } from "pixi.js" -import { GraphicsContainer } from "./graphicsContainer" -import { WagonFuelContainer } from "./wagonFuelContainer" - -export class WagonFuelBoxContainer extends GraphicsContainer { - public children: Sprite[] | WagonFuelContainer[] = [] - - constructor() { - super({ type: "WAGON_FUEL", direction: "RIGHT" }) - } - - static create() { - const storage = Sprite.from("wagonFuelContainer1") - storage.anchor.set(0.5, 1) - - const container = new WagonFuelBoxContainer() - const fuel = new WagonFuelContainer() - container.addChild(storage, fuel) - - container.x = 0 - container.y = -18 - - return container - } -} diff --git a/apps/client/src/game/components/wagonFuelContainer.ts b/apps/client/src/game/components/wagonFuelContainer.ts deleted file mode 100644 index 2defbd33..00000000 --- a/apps/client/src/game/components/wagonFuelContainer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Sprite } from "pixi.js" -import { getRandomInRange } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -export class WagonFuelContainer extends GraphicsContainer { - constructor() { - super({ type: "WAGON_FUEL", direction: "RIGHT" }) - - this.initFuelContainer() - } - - initFuelContainer() { - const offsetX = 76 - const offsetY = 52 - - for (let i = 1; i < 10; i++) { - const sprite = this.getRandomFuelSprite() - sprite.x = i * 12 - offsetX - sprite.y = -offsetY - this.addChild(sprite) - } - } - - getRandomFuelSprite() { - const random = getRandomInRange(1, 2) - if (random === 1) { - return Sprite.from("wagonFuel1") - } - return Sprite.from("wagonFuel2") - } -} diff --git a/apps/client/src/game/components/wagonWheelContainer.ts b/apps/client/src/game/components/wagonWheelContainer.ts deleted file mode 100644 index 10fdb078..00000000 --- a/apps/client/src/game/components/wagonWheelContainer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectDirection } from "../../../../../packages/api-sdk/src" -import { GraphicsContainer } from "./graphicsContainer" - -interface IWagonWheelContainerOptions { - direction: IGameObjectDirection - side: "LEFT" | "RIGHT" -} - -export class WagonWheelContainer extends GraphicsContainer { - public side: IWagonWheelContainerOptions["side"] - - constructor({ direction, side }: IWagonWheelContainerOptions) { - super({ type: "WAGON_WHEEL", direction }) - this.side = side - } - - static create( - spriteIndex: string, - direction: IGameObjectDirection, - side: IWagonWheelContainerOptions["side"], - ) { - const sprite = Sprite.from(spriteIndex) - sprite.anchor.set(0.5, 0.5) - - const container = new WagonWheelContainer({ direction, side }) - container.addChild(sprite) - - return container - } -} diff --git a/apps/client/src/game/game.ts b/apps/client/src/game/game.ts deleted file mode 100644 index b5207963..00000000 --- a/apps/client/src/game/game.ts +++ /dev/null @@ -1,316 +0,0 @@ -import { Application, Container } from "pixi.js" -import type { - IGameObject, - IGameObjectMechanic, - IGameObjectPlayer, - IGameObjectRaider, - IGameObjectTrader, - WebSocketMessage, - GameSceneType, -} from "../../../../packages/api-sdk/src" -import { type GameObject, type Wagon } from "./objects" -import { Mechanic, Player, Raider, Trader } from "./objects/units" -import type { GameScene } from "./scenes/gameScene" -import { MovingScene } from "./scenes/movingScene" -import { AssetsManager, AudioManager, WebSocketManager } from "./utils" -import { BackgroundGenerator } from "./utils/generators/background" - -export class Game extends Container { - public children: GameObject[] = [] - public app!: Application - public audio!: AudioManager - public scene!: GameScene - public bg!: BackgroundGenerator - - public tick = 0 - public cameraOffsetX = 0 - public cameraMovementSpeedX = 0.008 - public cameraOffsetY = 0 - public cameraMovementSpeedY = 0.008 - public cameraX = 0 - public cameraY = 0 - public cameraPerfectX = 0 - public cameraPerfectY = 0 - - constructor() { - super() - - this.app = new Application() - this.audio = new AudioManager() - this.bg = new BackgroundGenerator(this.app) - - void this.init() - } - - async play() { - // setInterval(() => { - // console.log("FPS", this.app.ticker.FPS) - // console.log("Objects", this.children.length) - // }, 1000) - } - - changeCameraPosition(wagon: Wagon) { - const columnWidth = this.app.screen.width / 6 - const rowHeight = this.app.screen.height / 6 - - let leftPadding = - wagon.direction === "LEFT" ? columnWidth * 4 : columnWidth * 2 - let topPadding = rowHeight * 3 - - if (wagon.speedPerSecond === 0) { - leftPadding = columnWidth * 3 - - if (wagon.state === "IDLE" && !wagon.cargoType) { - // At Village stop - leftPadding = columnWidth - topPadding = rowHeight * 4 - } - } - - this.cameraPerfectX = -wagon.x + leftPadding - this.cameraPerfectY = -wagon.y + topPadding - - // If first load - if (Math.abs(-wagon.x - this.cameraX) > 3000) { - this.cameraX = this.cameraPerfectX - } - if (Math.abs(-wagon.y - this.cameraY) > 3000) { - this.cameraY = this.cameraPerfectY - } - } - - moveCamera() { - const cameraMaxSpeed = 0.2 - const bufferX = Math.abs(this.cameraPerfectX - this.cameraX) - const moduleX = this.cameraPerfectX - this.cameraX > 0 ? 1 : -1 - const addToX = bufferX > cameraMaxSpeed ? cameraMaxSpeed : bufferX - - if (this.cameraX !== this.cameraPerfectX) { - this.cameraX += addToX * moduleX - } - - const bufferY = Math.abs(this.cameraPerfectY - this.cameraY) - const moduleY = this.cameraPerfectY - this.cameraY > 0 ? 1 : -1 - const addToY = bufferY > cameraMaxSpeed ? cameraMaxSpeed : bufferY - - if (this.cameraY !== this.cameraPerfectY) { - this.cameraY += addToY * moduleY - } - - // if (Math.abs(this.cameraOffsetX) >= 20) { - // this.cameraMovementSpeedX *= -1 - // } - // this.cameraOffsetX += this.cameraMovementSpeedX - // - // if (Math.abs(this.cameraOffsetY) >= 30) { - // this.cameraMovementSpeedY *= -1 - // } - // this.cameraOffsetY += this.cameraMovementSpeedY - - this.parent.x = this.cameraX - this.parent.y = this.cameraY - } - - rebuildScene() { - this.removeChild(...this.children) - } - - findObject(id: string) { - return this.children.find((obj) => obj.id === id) - } - - async init() { - await this.app.init({ - background: "#239063", - resizeTo: window, - antialias: false, - roundPixels: false, - resolution: 1, - }) - document.getElementById("game-canvas")?.appendChild(this.app.canvas) - - await AssetsManager.init() - - this.audio.playSound("FOREST_BACKGROUND") - - //const bg = this.bg.getGeneratedBackgroundTilingSprite() - //bg.width = 10000 - //bg.height = 10000 - //this.app.stage.addChild(bg) - - this.app.stage.addChild(this) - - WebSocketManager.init(this) - - this.scene = new MovingScene({ game: this }) - - this.app.ticker.add(() => { - this.tick = this.app.ticker.FPS - - this.scene.live() - - this.animateObjects() - this.removeDestroyedObjects() - - const wagon = this.scene.wagonService.wagon - this.changeCameraPosition(wagon) - - this.moveCamera() - }) - } - - public initScene(scene: GameSceneType) { - if (this.scene) { - this.scene.destroy() - } - - if (scene === "MOVING") { - this.scene = new MovingScene({ game: this }) - return - } - } - - initPlayer(object: IGameObjectPlayer) { - const player = new Player({ game: this, object }) - this.addChild(player) - } - - updatePlayer(object: IGameObjectPlayer) { - const player = this.findObject(object.id) - if (player instanceof Player) { - player.update(object) - } - } - - initTrader(object: IGameObjectTrader) { - const unit = new Trader({ game: this, object }) - this.addChild(unit) - } - - updateTrader(object: IGameObjectTrader) { - const unit = this.findObject(object.id) - if (unit instanceof Trader) { - unit.update(object) - } - } - - initMechanic(object: IGameObjectMechanic) { - const unit = new Mechanic({ game: this, object }) - this.addChild(unit) - } - - updateMechanic(object: IGameObjectMechanic) { - const unit = this.findObject(object.id) - if (unit instanceof Mechanic) { - unit.update(object) - } - } - - initRaider(object: IGameObjectRaider) { - const raider = new Raider({ game: this, object }) - this.addChild(raider) - } - - updateRaider(object: IGameObjectRaider) { - const raider = this.findObject(object.id) - if (raider instanceof Raider) { - raider.update(object) - } - } - - public checkIfThisFlagIsTarget(id: string) { - for (const obj of this.children) { - if (obj.target?.id === id) { - return true - } - } - } - - animateObjects() { - for (const object of this.children) { - object?.animate() - object?.live() - } - } - - removeDestroyedObjects() { - for (const object of this.children) { - if (object.state === "DESTROYED") { - const index = this.children.indexOf(object) - this.children.splice(index, 1) - return - } - } - } - - handleMessage(message: WebSocketMessage) { - if (message.object) { - this.handleMessageObject(message.object) - } - if (message.event) { - this.handleMessageEvent(message.event) - } - } - - handleMessageObject(object: Partial) { - if (!object.id) { - return - } - - const obj = this.findObject(object.id) - if (!obj) { - if (object.entity === "PLAYER") { - this.initPlayer(object as IGameObjectPlayer) - return - } - if (object.entity === "TRADER") { - this.initTrader(object as IGameObjectTrader) - return - } - if (object.entity === "MECHANIC") { - this.initMechanic(object as IGameObjectMechanic) - return - } - if (object.entity === "RAIDER") { - this.initRaider(object as IGameObjectRaider) - return - } - return - } - - if (object.entity === "PLAYER") { - this.updatePlayer(object as IGameObjectPlayer) - return - } - if (object.entity === "TRADER") { - this.updateTrader(object as IGameObjectTrader) - return - } - if (object.entity === "MECHANIC") { - this.updateMechanic(object as IGameObjectMechanic) - return - } - if (object.entity === "RAIDER") { - this.updateRaider(object as IGameObjectRaider) - return - } - } - - handleMessageEvent(event: WebSocketMessage["event"]) { - if (event === "RAID_STARTED") { - this.audio.playSound("MARCHING_WITH_HORNS") - } - if (event === "GROUP_FORM_STARTED") { - this.audio.playSound("MARCHING_WITH_HORNS") - } - if (event === "MAIN_QUEST_STARTED") { - this.audio.playSound("MARCHING_WITH_HORNS") - } - if (event === "SCENE_CHANGED") { - this.rebuildScene() - } - if (event === "IDEA_CREATED") { - this.audio.playSound("YEAH") - } - } -} diff --git a/apps/client/src/game/index.ts b/apps/client/src/game/index.ts deleted file mode 100644 index 8a2ec643..00000000 --- a/apps/client/src/game/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Game } from "./game" - -const game = new Game() -void game.play() - -export { game } diff --git a/apps/client/src/game/objects/area.ts b/apps/client/src/game/objects/area.ts deleted file mode 100644 index 5c15c7f5..00000000 --- a/apps/client/src/game/objects/area.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { IGameObjectArea } from "../../../../../packages/api-sdk/src" -import type { GameScene } from "../scenes/gameScene.ts" -import { GameObject } from "./gameObject.ts" - -interface IAreaOptions { - scene: GameScene - theme: IGameObjectArea["theme"] - area: IGameObjectArea["area"] -} - -export class Area extends GameObject implements IGameObjectArea { - public theme: IGameObjectArea["theme"] - public area: IGameObjectArea["area"] - - constructor({ scene, theme, area }: IAreaOptions) { - const x = area.startX - const y = area.startY - - super({ scene, x, y }) - - this.theme = theme - this.area = area - - this.initGraphics() - } - - private initGraphics() { - this.scene.game.bg.changePaletteByTheme(this.theme) - - const bg = this.scene.game.bg.getGeneratedBackgroundTilingSprite() - bg.width = this.area.endX - this.area.startX - bg.height = this.area.endY - this.area.startY - - this.addChild(bg) - } - - animate() { - super.animate() - - this.zIndex = -1 - } -} diff --git a/apps/client/src/game/objects/buildings/building.ts b/apps/client/src/game/objects/buildings/building.ts deleted file mode 100644 index 87c66f78..00000000 --- a/apps/client/src/game/objects/buildings/building.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { - IGameObjectBuilding, - ItemType, -} from "../../../../../../packages/api-sdk/src" -import { Inventory } from "../../common" -import type { GameScene } from "../../scenes/gameScene.ts" -import { GameObject } from "../gameObject.ts" - -interface IBuildingOptions { - scene: GameScene - x: number - y: number -} - -export class Building extends GameObject implements IGameObjectBuilding { - public inventory!: Inventory - - constructor({ scene, x, y }: IBuildingOptions) { - super({ scene, x, y }) - - this.state = "IDLE" - this.initInventory() - } - - public animate() { - super.animate() - - this.zIndex = Math.round(this.y - 5) - - if (this.state === "DESTROYED") { - this.visible = false - } - } - - private initInventory() { - this.inventory = new Inventory({ - objectId: this.id, - id: createId(), - saveInDb: false, - }) - } - - public getItemByType(type: ItemType) { - if (!this.inventory?.items) { - return - } - - return this.inventory.items.find((item) => item.type === type) - } -} diff --git a/apps/client/src/game/objects/buildings/campfire.ts b/apps/client/src/game/objects/buildings/campfire.ts deleted file mode 100644 index 35057796..00000000 --- a/apps/client/src/game/objects/buildings/campfire.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { type AnimatedSprite, Sprite } from "pixi.js" -import type { IGameBuildingCampfire } from "../../../../../../packages/api-sdk/src" -import { FireParticlesContainer } from "../../components/fireParticlesContainer" -import type { GameScene } from "../../scenes/gameScene.ts" -import { AssetsManager } from "../../utils" -import { Building } from "./building" - -interface ICampfireOptions { - scene: GameScene - x: number - y: number -} - -export class Campfire extends Building implements IGameBuildingCampfire { - private fireAnimation!: AnimatedSprite - private fireParticles!: FireParticlesContainer - - constructor({ scene, x, y }: ICampfireOptions) { - super({ scene, x, y }) - - this.initGraphics() - } - - public animate() { - super.animate() - - this.fireAnimation.animationSpeed = 0.08 - this.fireAnimation.play() - - this.fireParticles.animate(1) - - this.handleSoundByState() - } - - private initGraphics() { - const sprite = Sprite.from("campfire1") - sprite.anchor.set(0.5, 1) - - this.fireAnimation = AssetsManager.getAnimatedSpriteCampfire() - this.fireParticles = new FireParticlesContainer({ - x: 0, - y: -40, - areaWidth: 40, - }) - - this.addChild(sprite, this.fireAnimation, this.fireParticles) - } - - private handleSoundByState() { - if (!this.visible) { - return - } - - if (this.state === "IDLE") { - this.scene.game.audio.playSound("FIRE_BURN") - } - } -} diff --git a/apps/client/src/game/objects/buildings/constructionArea.ts b/apps/client/src/game/objects/buildings/constructionArea.ts deleted file mode 100644 index 43a5e5a7..00000000 --- a/apps/client/src/game/objects/buildings/constructionArea.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameBuildingConstructionArea } from "../../../../../../packages/api-sdk/src" -import type { GameScene } from "../../scenes/gameScene" -import { Building } from "./building" - -interface IConstructionAreaOptions { - scene: GameScene - x: number - y: number -} - -export class ConstructionArea - extends Building - implements IGameBuildingConstructionArea -{ - constructor({ scene, x, y }: IConstructionAreaOptions) { - super({ scene, x, y }) - - this.initGraphics() - } - - private initGraphics() { - const sprite = Sprite.from("constructionArea1") - if (sprite) { - sprite.anchor.set(0.5, 0.92) - this.addChild(sprite) - } - } -} diff --git a/apps/client/src/game/objects/buildings/store.ts b/apps/client/src/game/objects/buildings/store.ts deleted file mode 100644 index f4190fb6..00000000 --- a/apps/client/src/game/objects/buildings/store.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameBuildingStore } from "../../../../../../packages/api-sdk/src" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Building } from "./building" - -interface IStoreOptions { - scene: GameScene - x: number - y: number -} - -export class Store extends Building implements IGameBuildingStore { - constructor({ scene, x, y }: IStoreOptions) { - super({ scene, x, y }) - - this.initGraphics() - } - - private initGraphics() { - const sprite = Sprite.from("store1") - if (sprite) { - sprite.anchor.set(0.5, 1) - this.addChild(sprite) - } - } -} diff --git a/apps/client/src/game/objects/buildings/wagonStop.ts b/apps/client/src/game/objects/buildings/wagonStop.ts deleted file mode 100644 index 2a5c376e..00000000 --- a/apps/client/src/game/objects/buildings/wagonStop.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameBuildingWagonStop } from "../../../../../../packages/api-sdk/src" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Building } from "./building" - -interface IWagonStopOptions { - scene: GameScene - x: number - y: number -} - -export class WagonStop extends Building implements IGameBuildingWagonStop { - constructor({ scene, x, y }: IWagonStopOptions) { - super({ scene, x, y }) - - this.initGraphics() - } - - private initGraphics() { - const sprite = Sprite.from("wagonStop1") - if (sprite) { - sprite.anchor.set(0.5, 0.92) - this.addChild(sprite) - } - } - - animate() { - super.animate() - - this.zIndex = Math.round(this.y - 100) - } -} diff --git a/apps/client/src/game/objects/buildings/warehouse.ts b/apps/client/src/game/objects/buildings/warehouse.ts deleted file mode 100644 index ff3079f2..00000000 --- a/apps/client/src/game/objects/buildings/warehouse.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameBuildingWarehouse } from "../../../../../../packages/api-sdk/src" -import { BuildingInterface } from "../../components/buildingInterface" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Building } from "./building" - -interface IWarehouseOptions { - scene: GameScene - x: number - y: number -} - -export class Warehouse extends Building implements IGameBuildingWarehouse { - public interface!: BuildingInterface - - constructor({ scene, x, y }: IWarehouseOptions) { - super({ scene, x, y }) - - this.initGraphics() - // this.initInterface() - } - - private initGraphics() { - const sprite = Sprite.from("warehouse1") - if (sprite) { - sprite.anchor.set(0.5, 1) - this.addChild(sprite) - } - } - - private initInterface() { - this.interface = new BuildingInterface(this) - this.addChild(this.interface) - } - - animate() { - super.animate() - - //this.interface.animate() - } -} diff --git a/apps/client/src/game/objects/flag.ts b/apps/client/src/game/objects/flag.ts deleted file mode 100644 index 86a37516..00000000 --- a/apps/client/src/game/objects/flag.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectFlag } from "../../../../../packages/api-sdk/src" -import type { GameScene } from "../scenes/gameScene.ts" -import { GameObject } from "./gameObject.ts" - -interface IFlagOptions { - scene: GameScene - x: number - y: number - type: IGameObjectFlag["type"] - offsetX?: number - offsetY?: number -} - -export class Flag extends GameObject implements IGameObjectFlag { - public type!: IGameObjectFlag["type"] - - public isReserved: boolean - public offsetX: number - public offsetY: number - - constructor({ scene, x, y, type, offsetX, offsetY }: IFlagOptions) { - super({ scene, x, y }) - - this.type = type - this.isReserved = false - this.offsetX = offsetX ?? 0 - this.offsetY = offsetY ?? 0 - - this.visible = false - - this.initGraphics() - } - - public live() { - if (this.target?.state === "DESTROYED") { - this.removeTarget() - } - } - - private initGraphics() { - const sprite = this.getSpriteByType() - if (sprite) { - sprite.anchor.set(0.5, 1) - this.addChild(sprite) - } - } - - getSpriteByType() { - if ( - this.type === "MOVEMENT" || - this.type === "WAGON_NEAR_MOVEMENT" || - this.type === "WAGON_MOVEMENT" - ) { - return Sprite.from("flag1") - } - if (this.type === "RESOURCE") { - return Sprite.from("flag2") - } - } - - public animate() { - if (this.scene.game.checkIfThisFlagIsTarget(this.id)) { - this.visible = true - return - } - - if (this.type === "WAGON_MOVEMENT") { - this.visible = true - return - } - - if (this.state === "DESTROYED") { - this.visible = false - return - } - - this.visible = false - } -} diff --git a/apps/client/src/game/objects/gameObject.ts b/apps/client/src/game/objects/gameObject.ts deleted file mode 100644 index fba6edc3..00000000 --- a/apps/client/src/game/objects/gameObject.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { Container } from "pixi.js" -import type { - IGameObject, - IGameScript, -} from "../../../../../packages/api-sdk/src" -import type { GameScene } from "../scenes/gameScene.ts" - -interface IGameObjectOptions { - scene: GameScene - id?: string - x?: number - y?: number -} - -export class GameObject extends Container implements IGameObject { - public id: string - public state!: IGameObject["state"] - public direction: IGameObject["direction"] - public entity: IGameObject["entity"] - public target: IGameObject["target"] - public health!: IGameObject["health"] - public speedPerSecond!: IGameObject["speedPerSecond"] - public size!: IGameObject["size"] - - public scene: GameScene - public script: IGameScript | undefined - public minDistance = 1 - public isOnWagonPath = false - - constructor({ scene, x, y, id }: IGameObjectOptions) { - super() - - this.scene = scene - - this.id = id ?? createId() - this.x = x ?? 0 - this.y = y ?? 0 - this.entity = "TREE" - this.direction = "RIGHT" - - this.scene.game.addChild(this) - } - - animate(): void { - this.zIndex = Math.round(this.y) - } - - live(): void {} - - public move() { - const isOnTarget = this.checkIfIsOnTarget() - if (isOnTarget) { - this.stop() - return false - } - - if (!this.target || !this.target.x || !this.target.y) { - this.stop() - return false - } - - const distanceToX = this.getDistanceToTargetX() - const distanceToY = this.getDistanceToTargetY() - - // Fix diagonal speed - const speed = this.speedPerSecond / this.scene.game.tick - const finalSpeed = distanceToX > 0 && distanceToY > 0 ? speed * 0.75 : speed - - this.moveX(finalSpeed > distanceToX ? distanceToX : finalSpeed) - this.moveY(finalSpeed > distanceToY ? distanceToY : finalSpeed) - return true - } - - moveX(speed: number) { - if (!this.target?.x || this.target.x === this.x) { - return - } - - if (this.x < this.target.x) { - this.direction = "RIGHT" - this.x += speed - } - if (this.x > this.target.x) { - this.x -= speed - this.direction = "LEFT" - } - } - - moveY(speed: number) { - if (!this.target?.y || this.target.y === this.y) { - return - } - - if (this.y < this.target.y) { - this.y += speed - } - if (this.y > this.target.y) { - this.y -= speed - } - } - - stop() { - this.state = "IDLE" - } - - public destroy() { - super.destroy() - this.size = 0 - this.health = 0 - this.state = "DESTROYED" - } - - checkIfIsOnTarget() { - return ( - this.getDistanceToTargetX() + this.getDistanceToTargetY() <= - this.minDistance - ) - } - - getDistanceToTargetX() { - if (!this.target?.x) { - return 0 - } - return Math.abs(this.target.x - this.x) - } - - getDistanceToTargetY() { - if (!this.target?.y) { - return 0 - } - return Math.abs(this.target.y - this.y) - } - - public setTarget(target: IGameObject) { - this.target = target - this.state = "MOVING" - } - - public removeTarget() { - this.target = undefined - } -} diff --git a/apps/client/src/game/objects/index.ts b/apps/client/src/game/objects/index.ts deleted file mode 100644 index 8fb10428..00000000 --- a/apps/client/src/game/objects/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { GameObject } from "./gameObject" -export { Rabbit } from "./rabbit" -export { Stone } from "./stone" -export { Tree } from "./tree" -export { Wolf } from "./wolf" -export { Flag } from "./flag" -export { Lake } from "./lake" -export { Area } from "./area" -export { Wagon } from "./wagon" diff --git a/apps/client/src/game/objects/lake.ts b/apps/client/src/game/objects/lake.ts deleted file mode 100644 index 47f242c1..00000000 --- a/apps/client/src/game/objects/lake.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { IGameObjectLake } from "../../../../../packages/api-sdk/src" -import { AssetsManager } from "../utils" -import { GameObject } from "./gameObject.ts" -import { GameScene } from "../scenes/gameScene"; -import { Water } from "./water"; - -interface ILakeOptions { - scene: GameScene - x: number - y: number -} - -export class Lake extends GameObject implements IGameObjectLake { - public water: Water[] = [] - - constructor({ scene, x, y }: ILakeOptions) { - super({ scene, x, y }) - - this.generate(13) - this.initGraphics() - } - - public animate() { - super.animate(); - - this.zIndex = 0 - } - - generate(r: number) { - for (let y = r; y >= -r; --y) { - for (let x = -r; x <= r; x++) { - const value = x ** 2 + y ** 2 - - if (value < r ** 2) { - this.draw(x, y) - } - } - } - } - - draw(x: number, y: number) { - const water = new Water({ scene: this.scene, x: x * 32, y: y * 32 }) - this.water.push(water) - } - - init(width: number, height: number) { - const gridX = Math.ceil(width / 32) - const gridY = Math.floor(height / 32) - - console.log(gridX, gridY) - - //const center = { x: Math.round(width / 2), y: Math.round(height / 2) } - - for (let i = 0; i < gridX; i++) { - for (let j = 0; j < gridY; j++) { - const x = i * 32 - const y = j * 32 - - // if (x <= center.x && y <= center.y) { - // continue - // } - - const water = new Water({ scene: this.scene, x, y }) - this.water.push(water) - } - } - } - - private initGraphics() { - for (const w of this.water) { - const sprite = AssetsManager.getRandomSpriteForWater() - sprite.anchor.set(0.5, 1) - sprite.x = w.x - sprite.y = w.y - this.addChild(sprite) - } - } -} diff --git a/apps/client/src/game/objects/rabbit.ts b/apps/client/src/game/objects/rabbit.ts deleted file mode 100644 index 67044982..00000000 --- a/apps/client/src/game/objects/rabbit.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectRabbit } from "../../../../../packages/api-sdk/src" -import type { Game } from "../game" -import { GameObject } from "./gameObject.ts" - -interface IRabbitOptions { - game: Game - object: IGameObjectRabbit -} - -export class Rabbit extends GameObject implements IGameObjectRabbit { - public animationAngle = 0 - - constructor({ game, object }: IRabbitOptions) { - super({ game, ...object }) - - this.update(object) - this.init() - } - - init() { - const spriteRight = Sprite.from("rabbitRight") - const spriteLeft = Sprite.from("rabbitLeft") - - spriteRight.anchor.set(0.5, 1) - spriteLeft.anchor.set(0.5, 1) - - spriteLeft.direction = "LEFT" - spriteRight.direction = "RIGHT" - - this.addChild(spriteRight, spriteLeft) - } - - animate() { - // Hide all - for (const t of this.children) { - t.visible = false - } - - // Visible only 1 - const sprite = this.children.find((t) => t.direction === this.direction) - if (sprite) { - sprite.visible = true - } - - if (this.state === "MOVING") { - this.angle = this.animationAngle - this.shakeAnimation() - } - } - - shakeAnimation() { - if (this.animationAngle >= 4) { - this.animationAngle = 0 - return - } - this.animationAngle += 0.08 - } -} diff --git a/apps/client/src/game/objects/stone.ts b/apps/client/src/game/objects/stone.ts deleted file mode 100644 index 760d5e0f..00000000 --- a/apps/client/src/game/objects/stone.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Sprite } from "pixi.js" -import { - type IGameObjectStone, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import type { GameScene } from "../scenes/gameScene" -import { GameObject } from "./gameObject.ts" - -interface IStoneOptions { - scene: GameScene - x: number - y: number - resource?: number - size?: number - health?: number -} - -export class Stone extends GameObject implements IGameObjectStone { - public type!: IGameObjectStone["type"] - public resource!: number - - public isReserved = false - public animationAngle = 0 - public animationHighSpeed = 0.05 - - constructor({ scene, x, y, resource, size }: IStoneOptions) { - super({ scene, x, y }) - - this.state = "IDLE" - this.resource = resource ?? getRandomInRange(1, 5) - this.size = size ?? 100 - - this.initGraphics() - } - - private initGraphics() { - const sprite = this.getSpriteByType() - if (sprite) { - sprite.anchor.set(0.5, 1) - this.addChild(sprite) - } - } - - getSpriteByType() { - if (this.type === "1") { - return Sprite.from("stone1") - } - } - - public animate() { - super.animate() - - if (this.state === "DESTROYED") { - this.visible = false - } - - if (this.state === "MINING") { - this.scale = 0.98 - this.shakeAnimation() - } - } - - shakeAnimation() { - if (Math.abs(this.animationAngle) >= 0.5) { - this.animationHighSpeed *= -1 - } - this.animationAngle += this.animationHighSpeed - this.angle = this.animationAngle - } - - live() { - if (this.state === "MINING") { - if (this.health <= 0) { - this.setAsMined() - } - - const random = getRandomInRange(1, 20) - if (random <= 1 && this.health > 0) { - this.state = "IDLE" - this.isReserved = false - } - - return - } - - if (this.state === "DESTROYED") { - return - } - } - - mine() { - this.state = "MINING" - this.isReserved = true - this.health -= 0.08 - } - - setAsMined() { - this.size = 0 - this.health = 0 - this.state = "DESTROYED" - } -} diff --git a/apps/client/src/game/objects/tree.ts b/apps/client/src/game/objects/tree.ts deleted file mode 100644 index 34d819e5..00000000 --- a/apps/client/src/game/objects/tree.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { Sprite } from "pixi.js" -import { - type IGameObjectTree, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import type { GameScene } from "../scenes/gameScene" -import { GameObject } from "./gameObject" - -interface ITreeOptions { - scene: GameScene - x: number - y: number - resource?: number - size?: number - health?: number - growSpeed?: number - type?: IGameObjectTree["type"] - variant?: IGameObjectTree["variant"] -} - -export class Tree extends GameObject implements IGameObjectTree { - public type!: IGameObjectTree["type"] - public variant!: IGameObjectTree["variant"] - public resource!: number - public isReadyToChop!: boolean - - public isReserved = false - private minSizeToChop = 75 - private maxSize = 100 - private growSpeedPerSecond = 0.5 - private animationAngle = getRandomInRange(-1, 1) - private animationSlowSpeed = 0.04 - private animationHighSpeed = 0.15 - - constructor({ - scene, - x, - y, - resource, - size, - health, - type, - variant, - }: ITreeOptions) { - super({ scene, x, y }) - - this.state = "IDLE" - this.resource = resource ?? getRandomInRange(1, 5) - this.size = size ?? 100 - this.health = health ?? 100 - this.type = type ?? this.getNewType() - this.variant = variant ?? this.getNewVariant() - - this.initGraphics() - } - - public live() { - this.checkHealth() - - switch (this.state) { - case "IDLE": - this.grow() - break - case "CHOPPING": - this.handleChoppingState() - break - case "DESTROYED": - break - } - } - - public animate() { - super.animate() - - this.scale = this.size / 100 - - if (this.state === "IDLE") { - this.shakeOnWind() - } - - if (this.state === "DESTROYED") { - this.visible = false - } - - if (this.state === "CHOPPING") { - this.shakeAnimation() - } - } - - public chop() { - this.state = "CHOPPING" - this.isReserved = true - this.health -= 0.08 - } - - private initGraphics() { - const sprite = this.getSpriteByType() - if (sprite) { - sprite.anchor.set(0.5, 1) - - // Some random to flip horizontally - const random = getRandomInRange(1, 2) - if (random === 1) { - sprite.scale.x = -1 - } - - this.addChild(sprite) - } - } - - private getSpriteByType() { - if (this.variant === "GREEN") { - return Sprite.from(`tree${this.type}Green`) - } - if (this.variant === "BLUE") { - return Sprite.from(`tree${this.type}Blue`) - } - if (this.variant === "STONE") { - return Sprite.from(`tree${this.type}Stone`) - } - if (this.variant === "TEAL") { - return Sprite.from(`tree${this.type}Teal`) - } - if (this.variant === "TOXIC") { - return Sprite.from(`tree${this.type}Toxic`) - } - if (this.variant === "VIOLET") { - return Sprite.from(`tree${this.type}Violet`) - } - } - - private shakeAnimation() { - if (Math.abs(this.animationAngle) >= 2.5) { - this.animationHighSpeed *= -1 - } - this.animationAngle += this.animationHighSpeed - this.angle = this.animationAngle - } - - private shakeOnWind() { - if (Math.abs(this.animationAngle) >= 1.5) { - this.animationSlowSpeed *= -1 - } - this.animationAngle += this.animationSlowSpeed - this.angle = this.animationAngle - } - - private checkHealth() { - if (this.health <= 0) { - this.destroy() - } - } - - private handleChoppingState() { - const random = getRandomInRange(1, 20) - if (random <= 1) { - this.state = "IDLE" - this.isReserved = false - } - } - - private grow() { - if (this.size >= this.minSizeToChop && !this.isReadyToChop) { - this.isReadyToChop = true - } - if (this.size >= this.maxSize) { - return - } - - this.size += this.growSpeedPerSecond / this.scene.game.tick - } - - private getNewType(): IGameObjectTree["type"] { - const types: IGameObjectTree["type"][] = ["1", "2", "3", "4", "5"] - const index = getRandomInRange(0, types.length - 1) - return types[index] - } - - private getNewVariant(): IGameObjectTree["variant"] { - const variants: IGameObjectTree["variant"][] = [ - "GREEN", - "BLUE", - "STONE", - "TEAL", - "TOXIC", - "VIOLET", - ] - const index = getRandomInRange(0, variants.length - 1) - return variants[index] - } -} diff --git a/apps/client/src/game/objects/units/courier.ts b/apps/client/src/game/objects/units/courier.ts deleted file mode 100644 index d245987f..00000000 --- a/apps/client/src/game/objects/units/courier.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { IGameObjectCourier } from "../../../../../../packages/api-sdk/src" -import { generateUnitUserName } from "../../common/generators/unitName.ts" -import { generateUnitTop } from "../../common/generators/unitTop.ts" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface ICourierOptions { - scene: GameScene - x: number - y: number -} - -export class Courier extends Unit implements IGameObjectCourier { - constructor({ scene, x, y }: ICourierOptions) { - super({ - scene, - x, - y, - }) - - this.speedPerSecond = 100 - this.minDistance = 15 - this.userName = generateUnitUserName() - - this.initVisual({ - head: "1", - hairstyle: "BOLD", - top: generateUnitTop(), - }) - } -} diff --git a/apps/client/src/game/objects/units/farmer.ts b/apps/client/src/game/objects/units/farmer.ts deleted file mode 100644 index db146a64..00000000 --- a/apps/client/src/game/objects/units/farmer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { IGameObjectFarmer } from "../../../../../../packages/api-sdk/src" -import { generateUnitUserName } from "../../common/generators/unitName.ts" -import { generateUnitTop } from "../../common/generators/unitTop.ts" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface IFarmerOptions { - scene: GameScene - x: number - y: number -} - -export class Farmer extends Unit implements IGameObjectFarmer { - constructor({ scene, x, y }: IFarmerOptions) { - super({ - scene, - x, - y, - }) - - this.speedPerSecond = 70 - this.minDistance = 10 - this.userName = generateUnitUserName() - - this.initVisual({ - head: "1", - hairstyle: "ORANGE_WITH_BEARD", - top: generateUnitTop(), - }) - } -} diff --git a/apps/client/src/game/objects/units/index.ts b/apps/client/src/game/objects/units/index.ts deleted file mode 100644 index 26dc7bb6..00000000 --- a/apps/client/src/game/objects/units/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { Courier } from "./courier" -export { Farmer } from "./farmer" -export { Mechanic } from "./mechanic" -export { Player } from "./player" -export { Raider } from "./raider" -export { Trader } from "./trader" -export { Unit } from "./unit" diff --git a/apps/client/src/game/objects/units/mechanic.ts b/apps/client/src/game/objects/units/mechanic.ts deleted file mode 100644 index e0006c71..00000000 --- a/apps/client/src/game/objects/units/mechanic.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { IGameObjectMechanic } from "../../../../../../packages/api-sdk/src" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface IMechanicOptions { - scene: GameScene - x: number - y: number -} - -export class Mechanic extends Unit implements IGameObjectMechanic { - constructor({ scene, x, y }: IMechanicOptions) { - super({ - scene, - x, - y, - }) - - this.userName = "Mechanic" - - this.initVisual({ - head: "1", - hairstyle: "COAL_LONG", - top: "DARK_SILVER_SHIRT", - }) - } - - public animate() { - super.animate() - - this.zIndex = Math.round(this.y + 100) - } -} diff --git a/apps/client/src/game/objects/units/player.ts b/apps/client/src/game/objects/units/player.ts deleted file mode 100644 index c7287bc4..00000000 --- a/apps/client/src/game/objects/units/player.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { - type IGameObjectPlayer, - type IGameSkill, - getRandomInRange, -} from "../../../../../../packages/api-sdk/src" -import { db } from "../../../../../api/src/db/db.client.ts" -import { Inventory, Skill } from "../../common" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface IPlayerOptions { - scene: GameScene - id?: string - x: number - y: number -} - -export class Player extends Unit implements IGameObjectPlayer { - reputation!: number - villainPoints!: number - refuellerPoints!: number - raiderPoints!: number - skills!: Skill[] - lastActionAt!: IGameObjectPlayer["lastActionAt"] - - public inventoryId?: string - - constructor({ scene, id, x, y }: IPlayerOptions) { - super({ scene, id, x, y }) - - this.speedPerSecond = 2 - void this.initFromDB() - } - - async initFromDB() { - await this.readFromDB() - await this.initSkillsFromDB() - super.initVisual({ - head: "1", - hairstyle: "CLASSIC", - top: "VIOLET_SHIRT", - }) - } - - async chopTree() { - super.chopTree() - - await this.findOrCreateSkillInDB("WOODSMAN") - this.upSkill("WOODSMAN") - } - - async mineStone() { - super.mineStone() - - await this.findOrCreateSkillInDB("MINER") - this.upSkill("MINER") - } - - updateCoins(amount: number) { - this.coins = this.coins + amount - - return db.player.update({ - where: { id: this.id }, - data: { - coins: this.coins, - }, - }) - } - - addReputation(amount: number) { - this.reputation += amount - - return db.player.update({ - where: { id: this.id }, - data: { - reputation: this.reputation, - }, - }) - } - - addRefuellerPoints(amount: number) { - if (amount < 0) { - return - } - - this.refuellerPoints += amount - - return db.player.update({ - where: { id: this.id }, - data: { - refuellerPoints: this.refuellerPoints, - }, - }) - } - - addVillainPoints(amount: number) { - this.villainPoints += amount - - return db.player.update({ - where: { id: this.id }, - data: { - villainPoints: { - increment: amount, - }, - }, - }) - } - - addRaiderPoints(amount: number) { - this.raiderPoints += amount - - return db.player.update({ - where: { id: this.id }, - data: { - raiderPoints: { - increment: amount, - }, - }, - }) - } - - public async readFromDB() { - const player = await db.player.findUnique({ where: { id: this.id } }) - if (!player) { - return - } - - this.userName = player.userName - this.coins = player.coins - this.reputation = player.reputation - this.villainPoints = player.villainPoints - this.refuellerPoints = player.refuellerPoints - this.raiderPoints = player.raiderPoints - this.inventoryId = player.inventoryId - } - - public updateLastActionAt() { - this.lastActionAt = new Date() - return db.player.update({ - where: { id: this.id }, - data: { - lastActionAt: new Date(), - }, - }) - } - - public async initInventoryFromDB() { - if (!this.inventoryId) { - return - } - - const inventory = new Inventory({ - objectId: this.id, - id: this.inventoryId, - saveInDb: true, - }) - await inventory.init() - this.inventory = inventory - } - - public async initSkillsFromDB() { - this.skills = [] - const skills = await Skill.findAllInDB(this.id) - for (const skill of skills) { - const instance = new Skill({ id: skill.id }) - await instance.init() - this.skills.push(instance) - } - } - - async findOrCreateSkillInDB(type: IGameSkill["type"]) { - const skill = this.skills.find((skill) => skill.type === type) - if (!skill) { - await Skill.createInDB(this.id, type) - await this.initSkillsFromDB() - return this.skills.find((skill) => skill.type === type) as Skill - } - - return skill - } - - public upSkill(type: IGameSkill["type"]) { - const random = getRandomInRange(1, 200) - if (random <= 1) { - const skill = this.skills.find((skill) => skill.type === type) - if (skill) { - void skill.addXp() - } - } - } -} diff --git a/apps/client/src/game/objects/units/raider.ts b/apps/client/src/game/objects/units/raider.ts deleted file mode 100644 index cbcc6ea9..00000000 --- a/apps/client/src/game/objects/units/raider.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { IGameObjectRaider } from "../../../../../../packages/api-sdk/src" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface IRaiderOptions { - scene: GameScene - x: number - y: number -} - -export class Raider extends Unit implements IGameObjectRaider { - constructor({ scene, x, y }: IRaiderOptions) { - super({ - scene, - x, - y, - }) - - this.speedPerSecond = 1.5 - this.userName = "Raider" - - this.initVisual({ - head: "1", - hairstyle: "BOLD", - top: "BLACK_SHIRT", - }) - } -} diff --git a/apps/client/src/game/objects/units/trader.ts b/apps/client/src/game/objects/units/trader.ts deleted file mode 100644 index 6f0bba05..00000000 --- a/apps/client/src/game/objects/units/trader.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { IGameObjectTrader } from "../../../../../../packages/api-sdk/src" -import { generateUnitUserName } from "../../common/generators/unitName.ts" -import { generateUnitTop } from "../../common/generators/unitTop.ts" -import type { GameScene } from "../../scenes/gameScene.ts" -import { Unit } from "./unit" - -interface ITraderOptions { - scene: GameScene - x: number - y: number -} - -export class Trader extends Unit implements IGameObjectTrader { - constructor({ scene, x, y }: ITraderOptions) { - super({ - scene, - x, - y, - }) - - this.speedPerSecond = 60 - this.minDistance = 5 - this.userName = generateUnitUserName() - - this.initVisual({ - head: "1", - hairstyle: "COAL_LONG", - top: generateUnitTop(), - }) - } -} diff --git a/apps/client/src/game/objects/units/unit.ts b/apps/client/src/game/objects/units/unit.ts deleted file mode 100644 index f0c5a2e8..00000000 --- a/apps/client/src/game/objects/units/unit.ts +++ /dev/null @@ -1,296 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { AnimatedSprite } from "pixi.js" -import { - type IGameObjectUnit, - getRandomInRange, -} from "../../../../../../packages/api-sdk/src" -import { Inventory } from "../../common" -import { DialogueInterface } from "../../components/dialogueInterface" -import type { GraphicsContainer } from "../../components/graphicsContainer" -import { UnitHairContainer } from "../../components/unitHairContainer" -import { UnitHeadContainer } from "../../components/unitHeadContainer" -import { UnitInterface } from "../../components/unitInterface" -import { UnitTopContainer } from "../../components/unitTopContainer" -import type { GameScene } from "../../scenes/gameScene.ts" -import { AssetsManager } from "../../utils" -import { Flag } from "../flag" -import { GameObject } from "../gameObject.ts" -import { Stone } from "../stone.ts" -import { Tree } from "../tree.ts" - -interface IUnitOptions { - scene: GameScene - id?: string - x: number - y: number -} - -export class Unit extends GameObject implements IGameObjectUnit { - public inventory!: Inventory - public visual!: IGameObjectUnit["visual"] - public userName!: IGameObjectUnit["userName"] - public coins = 0 - public dialogue!: IGameObjectUnit["dialogue"] - - private interface!: UnitInterface - private dialogueInterface!: DialogueInterface - children: GraphicsContainer[] = [] - private readonly animationMovingLeft!: AnimatedSprite - private readonly animationMovingRight!: AnimatedSprite - - constructor({ scene, x, y, id }: IUnitOptions) { - super({ scene, x, y, id }) - - this.initInventory() - this.initVisual() - this.initDialogue() - this.coins = 0 - this.state = "IDLE" - - this.animationMovingRight = AssetsManager.getAnimatedSpriteHero("RIGHT") - this.animationMovingLeft = AssetsManager.getAnimatedSpriteHero("LEFT") - - this.initGraphics() - } - - public live() { - this.handleMessages() - - if (this.script) { - return this.script.live() - } - } - - private initInventory() { - this.inventory = new Inventory({ - objectId: this.id, - id: createId(), - saveInDb: false, - }) - } - - public initVisual(visual?: IGameObjectUnit["visual"]) { - this.visual = visual ?? { - head: "1", - hairstyle: "CLASSIC", - top: "VIOLET_SHIRT", - } - } - - private initDialogue() { - this.dialogue = { - messages: [], - } - } - - public addMessage(message: string) { - const MAX_CHARS = 100 - const messagePrepared = - message.trim().slice(0, MAX_CHARS) + - (message.length > MAX_CHARS ? "..." : "") - - this.dialogue.messages.push({ - id: createId(), - text: messagePrepared, - }) - } - - public handleMessages() { - const random = getRandomInRange(1, 200) - if (random === 1) { - this.dialogue.messages.splice(0, 1) - } - } - - public chopTree() { - if (this.target instanceof Tree && this.target.state !== "DESTROYED") { - this.direction = "RIGHT" - this.state = "CHOPPING" - this.checkAndBreakTool("AXE") - - this.target.chop() - } - } - - public mineStone() { - if (this.target instanceof Stone && this.target.state !== "DESTROYED") { - this.direction = "RIGHT" - this.state = "MINING" - this.checkAndBreakTool("PICKAXE") - - this.target.mine() - } - } - - checkAndBreakTool(type: "AXE" | "PICKAXE") { - const tool = this.inventory.items.find((item) => item.type === type) - if (tool) { - //this.target.health -= 0.16 - const random = getRandomInRange(1, 40) - if (random <= 1) { - void this.inventory.checkAndBreakItem(tool, 1) - } - } - } - - private initGraphics() { - const top = this.initTop() - const head = this.initHead() - const hair = this.initHair() - - this.initInterface() - - this.addChild( - ...top, - ...head, - ...hair, - this.animationMovingLeft, - this.animationMovingRight, - this.interface, - this.dialogueInterface, - ) - } - - initTop() { - return UnitTopContainer.getAll() - } - - initHead() { - return UnitHeadContainer.getAll() - } - - initHair() { - return UnitHairContainer.getAll() - } - - initInterface() { - this.interface = new UnitInterface(this) - this.dialogueInterface = new DialogueInterface(this) - } - - public animate() { - super.animate() - - this.zIndex = Math.round(this.y + 1) - - for (const container of this.children) { - container.visible = false - - if (this.state === "MOVING") { - this.animationMovingLeft.animationSpeed = 0.25 - this.animationMovingRight.animationSpeed = 0.25 - - if (this.direction === "RIGHT") { - this.animationMovingRight.visible = true - this.animationMovingRight.play() - } - if (this.direction === "LEFT") { - this.animationMovingLeft.visible = true - this.animationMovingLeft.play() - } - } - - if ( - this.state === "IDLE" || - this.state === "CHOPPING" || - this.state === "MINING" - ) { - this.animationMovingLeft.animationSpeed = 0 - this.animationMovingRight.animationSpeed = 0 - this.animationMovingLeft.currentFrame = 0 - this.animationMovingRight.currentFrame = 0 - - if (this.direction === "LEFT") { - this.animationMovingLeft.visible = true - } - if (this.direction === "RIGHT") { - this.animationMovingRight.visible = true - } - } - - this.drawTop(container) - this.drawHead(container) - this.drawHair(container) - } - - this.interface.animate() - this.dialogueInterface.animate() - - this.showToolInHand() - this.handleSoundByState() - - if (this.target && this.target instanceof Flag) { - this.target.visible = true - } - } - - drawTop(container: GraphicsContainer) { - if (container instanceof UnitTopContainer) { - if (container.visual !== this.visual.top) { - return - } - if (container.direction !== this.direction) { - return - } - - container.visible = true - } - } - - drawHead(container: GraphicsContainer) { - if (container instanceof UnitHeadContainer) { - if (container.visual !== this.visual.head) { - return - } - if (container.direction !== this.direction) { - return - } - - container.visible = true - } - } - - drawHair(container: GraphicsContainer) { - if (container instanceof UnitHairContainer) { - if (container.visual !== this.visual.hairstyle) { - return - } - if (container.direction !== this.direction) { - return - } - - container.visible = true - } - } - - showToolInHand() { - if (this.state === "CHOPPING") { - this.interface.showAxeInHand() - } - if (this.state === "MINING") { - this.interface.showPickaxeInHand() - } - } - - handleSoundByState() { - if (this.state === "CHOPPING") { - if (this.inventory?.items.find((item) => item.type === "AXE")) { - this.scene.game.audio.playSound("CHOP_HIT") - return - } - - this.scene.game.audio.playSound("HAND_HIT") - return - } - - if (this.state === "MINING") { - if (this.inventory?.items.find((item) => item.type === "PICKAXE")) { - this.scene.game.audio.playSound("MINE_HIT") - return - } - - this.scene.game.audio.playSound("HAND_HIT") - return - } - } -} diff --git a/apps/client/src/game/objects/wagon.ts b/apps/client/src/game/objects/wagon.ts deleted file mode 100644 index a6cc9613..00000000 --- a/apps/client/src/game/objects/wagon.ts +++ /dev/null @@ -1,293 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { Sprite } from "pixi.js" -import type { IGameObjectWagon } from "../../../../../packages/api-sdk/src" -import { Inventory } from "../common" -import type { GraphicsContainer } from "../components/graphicsContainer" -import { WagonCargoContainer } from "../components/wagonCargoContainer" -import { WagonEngineCloudsContainer } from "../components/wagonEngineCloudsContainer" -import { WagonEngineContainer } from "../components/wagonEngineContainer" -import { WagonFuelBoxContainer } from "../components/wagonFuelBoxContainer" -import { WagonWheelContainer } from "../components/wagonWheelContainer" -import type { GameScene } from "../scenes/gameScene.ts" -import { GameObject } from "./gameObject.ts" -import { Mechanic } from "./units" - -interface IWagonOptions { - scene: GameScene - x: number - y: number -} - -export class Wagon extends GameObject implements IGameObjectWagon { - public fuel!: number - public visibilityArea!: IGameObjectWagon["visibilityArea"] - public cargoType: IGameObjectWagon["cargoType"] - - public children: GraphicsContainer[] = [] - public cargo: Inventory | undefined - public mechanic!: Mechanic - public serverDataArea!: IGameObjectWagon["visibilityArea"] - public collisionArea!: IGameObjectWagon["visibilityArea"] - - constructor({ scene, x, y }: IWagonOptions) { - super({ scene, x, y }) - - this.state = "IDLE" - this.speedPerSecond = 0 - this.fuel = 2000 - this.updateVisibilityArea() - this.updateServerDataArea() - - this.initMechanic() - this.initGraphics() - } - - public live() { - this.updateVisibilityArea() - this.updateServerDataArea() - this.updateCollisionArea() - this.updateMechanic() - this.consumeFuel() - - if (this.state === "IDLE") { - return - } - if (this.state === "WAITING") { - return - } - } - - consumeFuel() { - if (this.speedPerSecond <= 0) { - return - } - - this.fuel -= this.speedPerSecond * 2 - } - - refuel(woodAmount: number) { - if (woodAmount < 0) { - return - } - - this.fuel += woodAmount * 5 * 40 - } - - emptyFuel() { - this.fuel = 0 - } - - updateVisibilityArea() { - const offsetX = 2560 / 2 - const offsetY = 1440 / 2 - - this.visibilityArea = { - startX: this.x - offsetX, - endX: this.x + offsetX, - startY: this.y - offsetY, - endY: this.y + offsetY, - } - } - - updateServerDataArea() { - const offsetX = 2560 * 1.5 - const offsetY = 1440 - - this.serverDataArea = { - startX: this.x - offsetX, - endX: this.x + offsetX, - startY: this.y - offsetY, - endY: this.y + offsetY, - } - } - - updateCollisionArea() { - const offsetX = 250 - const offsetY = 180 - - this.collisionArea = { - startX: this.x - offsetX, - endX: this.x + offsetX, - startY: this.y - offsetY, - endY: this.y + offsetY, - } - } - - public checkIfPointInCollisionArea(point: { x: number; y: number }) { - return ( - this.collisionArea.startX < point.x && - point.x < this.collisionArea.endX && - this.collisionArea.startY < point.y && - point.y < this.collisionArea.endY - ) - } - - public checkIfPointInVisibilityArea(point: { x: number; y: number }) { - return ( - this.visibilityArea.startX < point.x && - point.x < this.visibilityArea.endX && - this.visibilityArea.startY < point.y && - point.y < this.visibilityArea.endY - ) - } - - public checkIfPointInServerDataArea(point: { x: number; y: number }) { - return ( - this.serverDataArea.startX < point.x && - point.x < this.serverDataArea.endX && - this.serverDataArea.startY < point.y && - point.y < this.serverDataArea.endY - ) - } - - initMechanic() { - this.mechanic = new Mechanic({ - scene: this.scene, - x: this.x, - y: this.y, - }) - } - - updateMechanic() { - this.mechanic.live() - this.mechanic.direction = "LEFT" - this.mechanic.x = this.x - 50 - this.mechanic.y = this.y - 48 - } - - public setCargo() { - this.cargo = new Inventory({ - id: createId(), - saveInDb: false, - objectId: this.id, - }) - void this.cargo.addOrCreateItem("WOOD", 100) - this.cargoType = "CHEST" - } - - public emptyCargo() { - this.cargo = undefined - this.cargoType = undefined - } - - private initGraphics() { - const spriteSide = Sprite.from("wagonBase1") - spriteSide.anchor.set(0.5, 1) - spriteSide.scale = 0.75 - - const spriteBase = Sprite.from("wagonBase2") - spriteBase.anchor.set(0.5, 1) - spriteBase.scale = 0.75 - - const cargo = WagonCargoContainer.create() - cargo.scale = 0.75 - - const engine = WagonEngineContainer.create("wagonEngine1", "RIGHT") - engine.scale = 0.75 - - const storage = WagonFuelBoxContainer.create() - storage.scale = 0.75 - - const wheel1 = WagonWheelContainer.create("wagonWheel1", "RIGHT", "LEFT") - const wheel2 = WagonWheelContainer.create("wagonWheel1", "RIGHT", "RIGHT") - wheel1.scale = 0.75 - wheel2.scale = 0.75 - - const clouds = new WagonEngineCloudsContainer() - - this.addChild( - spriteBase, - engine, - cargo, - spriteSide, - storage, - wheel1, - wheel2, - clouds, - ) - } - - public animate() { - super.animate() - - for (const container of this.children) { - container.visible = true - - this.drawWheels(container) - this.drawEngine(container) - this.drawCargo(container) - this.drawFuel(container) - - if (container instanceof WagonEngineCloudsContainer) { - container.animate(this.speedPerSecond) - } - } - - this.handleSoundByState() - } - - drawWheels(container: GraphicsContainer) { - if (container instanceof WagonWheelContainer) { - if (container.side === "LEFT") { - container.x = -123 - container.y = -16 - } - if (container.side === "RIGHT") { - container.x = 123 - container.y = -16 - } - - container.visible = true - - const wheelRotation = this.direction === "LEFT" ? -1 : 1 - - container.angle += (wheelRotation * this.speedPerSecond) / 2.5 - } - } - - drawEngine(container: GraphicsContainer) { - if (container instanceof WagonEngineContainer) { - container.x = -102 - container.y = -58 - - container.visible = true - } - } - - drawCargo(container: GraphicsContainer) { - if (container instanceof WagonCargoContainer) { - if (this.cargoType === "CHEST") { - container.visible = true - for (const c of container.children) { - c.visible = true - } - } - - if (!this.cargoType) { - container.visible = false - } - } - } - - drawFuel(container: GraphicsContainer) { - let initFuel = this.fuel - if (container instanceof WagonFuelBoxContainer) { - for (const c of container.children) { - for (const fuelSprite of c.children) { - fuelSprite.visible = false - initFuel -= 500 - - if (initFuel > 500) { - fuelSprite.visible = true - } - } - } - } - } - - handleSoundByState() { - if (this.state === "MOVING") { - this.scene.game.audio.playSound("WAGON_MOVING") - } - } -} diff --git a/apps/client/src/game/objects/water.ts b/apps/client/src/game/objects/water.ts deleted file mode 100644 index fc3f507b..00000000 --- a/apps/client/src/game/objects/water.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { IGameObjectWater } from "../../../../../packages/api-sdk/src" -import { GameObject } from "./gameObject" -import { GameScene } from "../scenes/gameScene"; - -interface IWaterOptions { - scene: GameScene - x: number - y: number -} - -export class Water extends GameObject implements IGameObjectWater { - constructor({ scene, x, y }: IWaterOptions) { - super({ scene, x, y }) - } -} diff --git a/apps/client/src/game/objects/wolf.ts b/apps/client/src/game/objects/wolf.ts deleted file mode 100644 index 1e17eb04..00000000 --- a/apps/client/src/game/objects/wolf.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Sprite } from "pixi.js" -import type { IGameObjectWolf } from "../../../../../packages/api-sdk/src" -import type { Game } from "../game" -import { GameObject } from "./gameObject.ts" - -interface IWolfOptions { - game: Game - object: IGameObjectWolf -} - -export class Wolf extends GameObject implements IGameObjectWolf { - public animationAngle = 0 - public animationSlowSpeed = 0.1 - - constructor({ game, object }: IWolfOptions) { - super({ game, ...object }) - - this.update(object) - this.init() - } - - init() { - const spriteRight = Sprite.from("wolfRight") - const spriteLeft = Sprite.from("wolfLeft") - - spriteRight.anchor.set(0.5, 1) - spriteLeft.anchor.set(0.5, 1) - - spriteRight.direction = "RIGHT" - spriteLeft.direction = "LEFT" - - this.addChild(spriteRight, spriteLeft) - } - - animate() { - // Hide all - for (const t of this.children) { - t.visible = false - } - - // Visible only 1 - const sprite = this.children.find((t) => t.direction === this.direction) - if (sprite) { - sprite.visible = true - } - - if (this.state === "MOVING") { - this.angle = this.animationAngle - this.shakeAnimation() - } - } - - shakeAnimation() { - if (Math.abs(this.animationAngle) >= 2) { - this.animationSlowSpeed *= -1 - } - this.animationAngle += this.animationSlowSpeed - this.angle = this.animationAngle - } -} diff --git a/apps/client/src/game/quests/noTradingPostQuest.ts b/apps/client/src/game/quests/noTradingPostQuest.ts deleted file mode 100644 index 22d33628..00000000 --- a/apps/client/src/game/quests/noTradingPostQuest.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { IGameQuestTaskFunc } from "../../../../../packages/api-sdk/src" -import type { DonateWoodToVillageAction } from "../actions/donateWoodToVillageAction" -import { Quest } from "./quest" - -interface INoTradingPostQuestOptions { - creatorId: string - taskUpdateFunc1: IGameQuestTaskFunc - taskUpdateFunc2: IGameQuestTaskFunc - taskAction1: DonateWoodToVillageAction -} - -export class NoTradingPostQuest extends Quest { - constructor({ - creatorId, - taskUpdateFunc1, - taskUpdateFunc2, - taskAction1, - }: INoTradingPostQuestOptions) { - super({ - type: "SIDE", - title: "No Trading Post", - description: "The locals need help. Traders are expected to arrive.", - }) - - this.creatorId = creatorId - this.initTasks({ taskUpdateFunc1, taskUpdateFunc2, taskAction1 }) - } - - initTasks({ - taskUpdateFunc1, - taskUpdateFunc2, - taskAction1, - }: { - taskUpdateFunc1: IGameQuestTaskFunc - taskUpdateFunc2: IGameQuestTaskFunc - taskAction1: DonateWoodToVillageAction - }) { - this.tasks = [ - { - id: createId(), - status: "ACTIVE", - description: "Accumulate 25 wood in the warehouse", - progressNow: 0, - progressToSuccess: 25, - updateProgress: taskUpdateFunc1, - action: taskAction1, - }, - { - id: createId(), - status: "ACTIVE", - description: "Build Trading Post", - progressNow: false, - progressToSuccess: true, - updateProgress: taskUpdateFunc2, - }, - ] - } -} diff --git a/apps/client/src/game/quests/quest.ts b/apps/client/src/game/quests/quest.ts deleted file mode 100644 index cb802fce..00000000 --- a/apps/client/src/game/quests/quest.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { IGameQuest } from "../../../../../packages/api-sdk/src" - -interface IQuestOptions { - type: IGameQuest["type"] - title: IGameQuest["title"] - description: IGameQuest["description"] -} - -export class Quest implements IGameQuest { - public id: string - public type: IGameQuest["type"] - public title: IGameQuest["title"] - public description: IGameQuest["description"] - public tasks: IGameQuest["tasks"] - public status: IGameQuest["status"] - public creatorId!: IGameQuest["creatorId"] - public conditions!: IGameQuest["conditions"] - - constructor({ type, title, description }: IQuestOptions) { - this.id = createId() - this.type = type - this.title = title - this.description = description - this.tasks = [] - - this.status = "ACTIVE" - this.conditions = {} - } -} diff --git a/apps/client/src/game/quests/treesAreRunningOutQuest.ts b/apps/client/src/game/quests/treesAreRunningOutQuest.ts deleted file mode 100644 index 8f4e7699..00000000 --- a/apps/client/src/game/quests/treesAreRunningOutQuest.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { IGameQuestTaskFunc } from "../../../../../packages/api-sdk/src" -import type { PlantTreeAction } from "../actions/plantTreeAction" -import { Quest } from "./quest" - -interface ITreesAreRunningOutQuestOptions { - creatorId: string - taskUpdateFunc1: IGameQuestTaskFunc - taskAction1: PlantTreeAction -} - -export class TreesAreRunningOutQuest extends Quest { - constructor({ - creatorId, - taskUpdateFunc1, - taskAction1, - }: ITreesAreRunningOutQuestOptions) { - super({ - type: "SIDE", - title: "The trees are running out!", - description: - "In the village, someone is actively cutting down trees. Help is needed!", - }) - - this.creatorId = creatorId - this.initTasks({ taskUpdateFunc1, taskAction1 }) - } - - initTasks({ - taskUpdateFunc1, - taskAction1, - }: { - taskUpdateFunc1: IGameQuestTaskFunc - taskAction1: PlantTreeAction - }) { - this.tasks = [ - { - id: createId(), - status: "ACTIVE", - description: "There should be at least 30 trees", - progressNow: 0, - progressToSuccess: 30, - updateProgress: taskUpdateFunc1, - action: taskAction1, - }, - ] - } -} diff --git a/apps/client/src/game/scenes/gameScene.ts b/apps/client/src/game/scenes/gameScene.ts deleted file mode 100644 index 71cf7941..00000000 --- a/apps/client/src/game/scenes/gameScene.ts +++ /dev/null @@ -1,469 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import { - type GetSceneResponse, - type IGameChunk, - type IGameChunkTheme, - type IGameInventoryItem, - getDateMinusMinutes, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { type GameChunk, Village } from "../chunks" -import { Group, Route } from "../common" -import type { Game } from "../game" -import { - Flag, - type GameObject, - type Rabbit, - Stone, - Tree, - type Wolf, -} from "../objects" -import { Player, Raider, Trader } from "../objects/units" -import { ChopTreeScript } from "../scripts/chopTreeScript" -import { - MoveOffScreenAndSelfDestroyScript -} from "../scripts/moveOffScreenAndSelfDestroyScript" -import { MoveToTargetScript } from "../scripts/moveToTargetScript" -import { ActionService } from "../services/actionService" -import { EventService } from "../services/eventService" -import { TradeService } from "../services/tradeService" -import { WagonService } from "../services/wagonService" - -interface IGameSceneOptions { - game: Game -} - -export class GameScene { - public id: string - public game: Game - public objects: GameObject[] = [] - public group: Group - public chunks: GameChunk[] = [] - public chunkNow: GameChunk | undefined - - public actionService: ActionService - public eventService: EventService - public tradeService: TradeService - public wagonService: WagonService - - constructor({ game }: IGameSceneOptions) { - this.id = createId() - this.game = game - this.group = new Group() - - this.actionService = new ActionService({ scene: this }) - this.eventService = new EventService({ scene: this }) - this.tradeService = new TradeService({ scene: this }) - this.wagonService = new WagonService({ scene: this }) - } - - public live() { - this.eventService.update() - this.tradeService.update() - this.wagonService.update() - this.updateObjects() - this.updateChunks() - this.updateChunkNow() - } - - public destroy() { - this.objects = [] - } - - getChunkNow(): IGameChunk | null { - if (!this.chunkNow) { - return null - } - - return { - id: this.chunkNow.id, - title: this.chunkNow.title, - type: this.chunkNow.type, - center: this.chunkNow.center, - area: this.chunkNow.area, - } - } - - getWarehouseItems(): IGameInventoryItem[] | undefined { - if (this.chunkNow instanceof Village) { - const warehouse = this.chunkNow.getWarehouse() - if (warehouse) { - return warehouse.inventory.items - } - } - - return undefined - } - - getInfo(): GetSceneResponse { - return { - id: this.id, - commands: this.actionService.getAvailableCommands(), - events: this.eventService.getEvents(), - group: this.group.getGroup(), - wagon: this.wagonService.wagon, - chunk: this.getChunkNow(), - route: this.wagonService.routeService.getRoute(), - warehouseItems: this.getWarehouseItems(), - } - } - - updateObjects() { - this.removeInactivePlayers() - - for (const obj of this.objects) { - this.removeDestroyedObject(obj) - - if (obj instanceof Trader) { - this.tradeService.updateTrader(obj) - continue - } - if (obj instanceof Player) { - this.updatePlayer(obj) - continue - } - if (obj instanceof Raider) { - this.updateRaider(obj) - continue - } - - void obj.live() - } - } - - updateChunks() { - for (const chunk of this.chunks) { - for (const object of chunk.objects) { - if (object.state === "DESTROYED") { - chunk.removeObject(object) - } - } - - chunk.live() - } - } - - updateChunkNow() { - this.chunkNow = undefined - - for (const chunk of this.chunks) { - const isWagonOnThisChunk = chunk.checkIfPointIsInArea({ - x: this.wagonService.wagon.x, - y: this.wagonService.wagon.y, - }) - if (isWagonOnThisChunk) { - this.chunkNow = chunk - } - } - } - - updatePlayer(object: Player) { - object.live() - - if (object.script) { - return - } - - if (object.state === "IDLE") { - const random = getRandomInRange(1, 150) - if (random <= 1) { - const target = this.wagonService.findRandomNearFlag() - - object.script = new MoveToTargetScript({ - object, - target, - }) - } - } - } - - updateRabbit(object: Rabbit) { - object.live() - - if (object.state === "IDLE") { - const random = getRandomInRange(1, 100) - if (random <= 1) { - const randomObj = this.findRandomMovementFlag() - if (!randomObj) { - return - } - object.setTarget(randomObj) - } - } - } - - updateWolf(object: Wolf) { - object.live() - - if (object.state === "IDLE") { - const random = getRandomInRange(1, 100) - if (random <= 1) { - const randomObj = this.findRandomMovementFlag() - if (!randomObj) { - return - } - object.setTarget(randomObj) - } - } - } - - updateRaider(object: Raider) { - object.live() - - if (object.script) { - return - } - - // If there is an available tree - const availableTree = this.chunkNow?.getAvailableTree() - if (availableTree) { - const chopTreeFunc = (): boolean => { - object.chopTree() - if (!object.target || object.target.state === "DESTROYED") { - object.state = "IDLE" - if (object.target instanceof Tree) { - void object.inventory.addOrCreateItem( - "WOOD", - object.target?.resource, - ) - } - return true - } - return false - } - - object.script = new ChopTreeScript({ - object, - target: availableTree, - chopTreeFunc, - }) - - return - } - - if (object.state === "IDLE") { - const random = getRandomInRange(1, 100) - if (random <= 1) { - const randomObj = this.findRandomMovementFlag() - if (!randomObj) { - return - } - object.setTarget(randomObj) - } - } - } - - removeObject(object: GameObject) { - const index = this.objects.indexOf(object) - this.objects.splice(index, 1) - } - - async findOrCreatePlayer(id: string) { - const player = this.findPlayer(id) - if (!player && this.actionService.isActionPossible("CREATE_NEW_PLAYER")) { - return this.createPlayer(id) - } - return player - } - - public findPlayer(id: string) { - const player = this.objects.find((p) => p.id === id) - if (player instanceof Player) { - return player - } - } - - public findActivePlayers() { - return this.objects.filter((obj) => obj instanceof Player) as Player[] - } - - public removeInactivePlayers() { - const players = this.findActivePlayers() - for (const player of players) { - const checkTime = getDateMinusMinutes(8) - if (player.lastActionAt.getTime() <= checkTime.getTime()) { - if (player.script) { - continue - } - - const target = this.wagonService.findRandomOutFlag() - const selfDestroyFunc = () => { - this.group.remove(player) - this.removeObject(player) - } - - player.script = new MoveOffScreenAndSelfDestroyScript({ - target, - object: player, - selfDestroyFunc, - }) - } - } - } - - removeDestroyedObject(obj: GameObject) { - if (obj.state === "DESTROYED") { - this.removeObject(obj) - } - } - - async initPlayer(id: string) { - const instance = new Player({ scene: this, id, x: -100, y: -100 }) - await instance.initFromDB() - await instance.initInventoryFromDB() - - const flag = this.wagonService.findRandomOutFlag() - instance.x = flag.x - instance.y = flag.y - - return instance - } - - public async createPlayer(id: string): Promise { - const player = this.findPlayer(id) - if (!player) { - const instance = await this.initPlayer(id) - this.objects.push(instance) - return instance - } - return player - } - - getTreeToChop() { - // Part 1: Check trees on Wagon Path - const onlyOnPath = this.chunkNow?.objects.filter( - (obj) => - obj instanceof Tree && - obj.state !== "DESTROYED" && - !obj.isReserved && - obj.isOnWagonPath, - ) - if (onlyOnPath && onlyOnPath.length > 0) { - return this.determineNearestObject( - this.wagonService.wagon, - onlyOnPath, - ) as Tree - } - - // Part 2: Check nearest free tree - const other = this.chunkNow?.objects.filter( - (obj) => - obj instanceof Tree && - obj.state !== "DESTROYED" && - !obj.isReserved && - obj.isReadyToChop, - ) - if (other && other.length > 0) { - return this.determineNearestObject(this.wagonService.wagon, other) as Tree - } - } - - getStoneToMine() { - // Part 1: Check on Wagon Path - const onlyOnPath = this.chunkNow?.objects.filter( - (obj) => - obj instanceof Stone && - obj.state !== "DESTROYED" && - !obj.isReserved && - obj.isOnWagonPath, - ) - if (onlyOnPath && onlyOnPath.length > 0) { - return this.determineNearestObject( - this.wagonService.wagon, - onlyOnPath, - ) as Stone - } - - // Part 2: Check nearest free - const other = this.chunkNow?.objects.filter( - (obj) => - obj instanceof Stone && obj.state !== "DESTROYED" && !obj.isReserved, - ) - if (other && other.length > 0) { - return this.determineNearestObject( - this.wagonService.wagon, - other, - ) as Stone - } - } - - determineNearestObject( - point: { - x: number - y: number - }, - objects: GameObject[], - ) { - let closestObject = objects[0] - let shortestDistance = undefined - - for (const object of objects) { - const distance = Route.getDistanceBetween2Points(point, object) - if (!shortestDistance || distance < shortestDistance) { - shortestDistance = distance - closestObject = object - } - } - - return closestObject - } - - initRaiders(count: number) { - for (let i = 0; i < count; i++) { - const flag = this.wagonService.findRandomOutFlag() - - this.objects.push(new Raider({ scene: this, x: flag.x, y: flag.y })) - } - } - - public stopRaid() { - for (const object of this.objects) { - if (object instanceof Raider) { - const target = this.wagonService.findRandomOutFlag() - const selfDestroyFunc = () => { - this.removeObject(object) - } - - object.script = new MoveOffScreenAndSelfDestroyScript({ - target, - object, - selfDestroyFunc, - }) - } - } - } - - getRandomTheme(): IGameChunkTheme { - const themes: IGameChunkTheme[] = [ - "GREEN", - "BLUE", - "STONE", - "TEAL", - "VIOLET", - "TOXIC", - ] - return themes[Math.floor(Math.random() * themes.length)] - } - - findRandomMovementFlag() { - const flags = this.chunkNow?.objects.filter( - (f) => f instanceof Flag && f.type === "MOVEMENT", - ) - if (!flags) { - return undefined - } - - return flags.length > 0 - ? flags[Math.floor(Math.random() * flags.length)] - : undefined - } - - findRandomEmptyResourceFlag() { - const flags = this.objects.filter( - (f) => f instanceof Flag && f.type === "RESOURCE" && !f.target, - ) - return flags.length > 0 - ? flags[Math.floor(Math.random() * flags.length)] - : undefined - } -} diff --git a/apps/client/src/game/scenes/movingScene.ts b/apps/client/src/game/scenes/movingScene.ts deleted file mode 100644 index 9b85965d..00000000 --- a/apps/client/src/game/scenes/movingScene.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { Game } from "../game" -import { GameScene } from "./gameScene" - -interface IMovingSceneOptions { - game: Game -} - -export class MovingScene extends GameScene { - constructor({ game }: IMovingSceneOptions) { - super({ - game, - }) - - void this.init() - } - - public async init() { - const village = this.initStartingVillage() - const wagonStartPoint = village.getWagonStopPoint() - - this.wagonService.initWagon(wagonStartPoint) - await this.initGroupPlayers() - - // void this.live() - } - - initStartingVillage() { - const initialOffsetX = 500 - const initialOffsetY = 2000 - const width = 3600 - const height = 2000 - const area = { - width, - height, - center: { - x: Math.round(width / 2 + initialOffsetX), - y: Math.round(height / 2 + initialOffsetY), - }, - } - const village = this.wagonService.routeService.generateRandomVillage({ - center: area.center, - width: area.width, - height: area.height, - theme: this.getRandomTheme(), - scene: this, - }) - this.chunks.push(village) - - return village - } - - async initGroupPlayers() { - if (!this.group) { - return - } - - for (const player of this.group.players) { - const instance = await this.initPlayer(player.id) - this.objects.push(instance) - } - } -} diff --git a/apps/client/src/game/scripts/buildScript.ts b/apps/client/src/game/scripts/buildScript.ts deleted file mode 100644 index b38c9079..00000000 --- a/apps/client/src/game/scripts/buildScript.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IBuildScriptOptions { - object: GameObject - target: IGameObject - buildFunc: () => boolean -} - -export class BuildScript extends Script { - constructor({ target, object, buildFunc }: IBuildScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.build(buildFunc), - ] - } - - build(func: () => boolean): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - const isFinished = func() - if (isFinished) { - this.markTaskAsDone() - } - }, - } - } -} diff --git a/apps/client/src/game/scripts/chopTreeScript.ts b/apps/client/src/game/scripts/chopTreeScript.ts deleted file mode 100644 index 107b33df..00000000 --- a/apps/client/src/game/scripts/chopTreeScript.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IPlantNewTreeScriptOptions { - object: GameObject - target: IGameObject - chopTreeFunc: () => boolean -} - -export class ChopTreeScript extends Script { - constructor({ target, object, chopTreeFunc }: IPlantNewTreeScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.chopTree(chopTreeFunc), - ] - } - - chopTree(func: () => boolean): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - const isFinished = func() - if (isFinished) { - this.markTaskAsDone() - } - }, - } - } -} diff --git a/apps/client/src/game/scripts/mineStoneScript.ts b/apps/client/src/game/scripts/mineStoneScript.ts deleted file mode 100644 index 731cc4d2..00000000 --- a/apps/client/src/game/scripts/mineStoneScript.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IMineStoneScriptOptions { - object: GameObject - target: IGameObject - mineStoneFunc: () => boolean -} - -export class MineStoneScript extends Script { - constructor({ target, object, mineStoneFunc }: IMineStoneScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.mineStone(mineStoneFunc), - ] - } - - mineStone(func: () => boolean): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - const isFinished = func() - if (isFinished) { - this.markTaskAsDone() - } - }, - } - } -} diff --git a/apps/client/src/game/scripts/moveOffScreenAndSelfDestroyScript.ts b/apps/client/src/game/scripts/moveOffScreenAndSelfDestroyScript.ts deleted file mode 100644 index 6e709fa3..00000000 --- a/apps/client/src/game/scripts/moveOffScreenAndSelfDestroyScript.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IMoveOffScreenAndSelfDestroyScriptOptions { - object: GameObject - target: IGameObject - selfDestroyFunc: () => void -} - -export class MoveOffScreenAndSelfDestroyScript extends Script { - constructor({ - target, - object, - selfDestroyFunc, - }: IMoveOffScreenAndSelfDestroyScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.selfDestroy(selfDestroyFunc), - ] - } - - selfDestroy(func: () => void): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - func() - this.markTaskAsDone() - }, - } - } -} diff --git a/apps/client/src/game/scripts/moveToTargetScript.ts b/apps/client/src/game/scripts/moveToTargetScript.ts deleted file mode 100644 index b6c9184a..00000000 --- a/apps/client/src/game/scripts/moveToTargetScript.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { IGameObject } from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IMoveToRandomTargetScriptOptions { - object: GameObject - target: IGameObject -} - -export class MoveToTargetScript extends Script { - constructor({ target, object }: IMoveToRandomTargetScriptOptions) { - super({ object }) - - this.tasks = [this.setTarget(target), this.runToTarget()] - this.isInterruptible = true - } -} diff --git a/apps/client/src/game/scripts/moveToTradePostAndTradeScript.ts b/apps/client/src/game/scripts/moveToTradePostAndTradeScript.ts deleted file mode 100644 index c86c62ad..00000000 --- a/apps/client/src/game/scripts/moveToTradePostAndTradeScript.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IMoveToTradePostAndTradeScriptOptions { - object: GameObject - target: IGameObject - startTradeFunc: () => void -} - -export class MoveToTradePostAndTradeScript extends Script { - constructor({ - target, - object, - startTradeFunc, - }: IMoveToTradePostAndTradeScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.startTrade(startTradeFunc), - ] - } - - startTrade(func: () => void): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - func() - this.markTaskAsDone() - }, - } - } -} diff --git a/apps/client/src/game/scripts/placeItemInWarehouseScript.ts b/apps/client/src/game/scripts/placeItemInWarehouseScript.ts deleted file mode 100644 index a4f5747c..00000000 --- a/apps/client/src/game/scripts/placeItemInWarehouseScript.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IPlaceItemInWarehouseScriptOptions { - object: GameObject - target: IGameObject - placeItemFunc: () => void -} - -export class PlaceItemInWarehouseScript extends Script { - constructor({ - target, - object, - placeItemFunc, - }: IPlaceItemInWarehouseScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.placeItem(placeItemFunc), - ] - } - - placeItem(func: () => void): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - func() - this.markTaskAsDone() - }, - } - } -} diff --git a/apps/client/src/game/scripts/plantNewTreeScript.ts b/apps/client/src/game/scripts/plantNewTreeScript.ts deleted file mode 100644 index a6e5b7df..00000000 --- a/apps/client/src/game/scripts/plantNewTreeScript.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { - IGameObject, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" -import { Script } from "./script" - -interface IPlantNewTreeScriptOptions { - object: GameObject - target: IGameObject - plantNewTreeFunc: () => void -} - -export class PlantNewTreeScript extends Script { - constructor({ - target, - object, - plantNewTreeFunc, - }: IPlantNewTreeScriptOptions) { - super({ object }) - - this.tasks = [ - this.setTarget(target), - this.runToTarget(), - this.plantNewTree(plantNewTreeFunc), - ] - } - - plantNewTree(func: () => void): IGameTask { - return { - id: "3", - status: "IDLE", - live: () => { - func() - this.markTaskAsDone() - }, - } - } -} diff --git a/apps/client/src/game/scripts/script.ts b/apps/client/src/game/scripts/script.ts deleted file mode 100644 index e795aed6..00000000 --- a/apps/client/src/game/scripts/script.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { - IGameObject, - IGameScript, - IGameTask, -} from "../../../../../packages/api-sdk/src" -import type { GameObject } from "../objects" - -interface IScriptOptions { - object: GameObject -} - -export class Script implements IGameScript { - public id: string - public tasks!: IGameScript["tasks"] - public isInterruptible = false - - public object!: GameObject - - constructor({ object }: IScriptOptions) { - this.id = createId() - this.object = object - } - - live() { - const activeTask = this.getActiveTask() - if (!activeTask) { - const nextTask = this.getNextIdleTask() - if (!nextTask) { - return this.markScriptAsFinished() - } - - return this.markTaskAsActive(nextTask) - } - - return activeTask.live() - } - - getActiveTask() { - return this.tasks.find((t) => t.status === "ACTIVE") - } - - getNextIdleTask() { - return this.tasks.find((t) => t.status === "IDLE") - } - - markTaskAsActive(task: IGameTask) { - task.status = "ACTIVE" - } - - markTaskAsDone() { - const activeTask = this.getActiveTask() - if (!activeTask) { - return - } - - activeTask.status = "DONE" - } - - markScriptAsFinished() { - this.object.script = undefined - } - - setTarget(target: IGameObject): IGameTask { - return { - id: createId(), - status: "IDLE", - live: () => { - this.object.target = target - this.object.state = "MOVING" - this.markTaskAsDone() - }, - } - } - - runToTarget(): IGameTask { - return { - id: createId(), - status: "IDLE", - live: () => { - const isMoving = this.object.move() - if (!isMoving) { - this.markTaskAsDone() - } - }, - } - } -} diff --git a/apps/client/src/game/services/actionService.ts b/apps/client/src/game/services/actionService.ts deleted file mode 100644 index d93aacde..00000000 --- a/apps/client/src/game/services/actionService.ts +++ /dev/null @@ -1,678 +0,0 @@ -import type { - GameSceneType, - IGameActionResponse, - IGameSceneAction, - ItemType, -} from "../../../../../packages/api-sdk/src" -import { ANSWER } from "../../../../../packages/api-sdk/src/lib/actionAnswer" -import { - ADMIN_PLAYER_ID, - DISCORD_SERVER_INVITE_URL, - DONATE_URL, - GITHUB_REPO_URL, -} from "../../../../api/src/config" -import type { Action } from "../actions/action" -import { Village } from "../chunks" -import { Group } from "../common" -import { Stone, Tree } from "../objects" -import type { Warehouse } from "../objects/buildings/warehouse" -import type { Player } from "../objects/units" -import type { GameScene } from "../scenes/gameScene" -import { ChopTreeScript } from "../scripts/chopTreeScript" -import { MineStoneScript } from "../scripts/mineStoneScript" -import { PlantNewTreeScript } from "../scripts/plantNewTreeScript" - -interface ICommandWithAction { - id: string - action: IGameSceneAction - command: string -} - -interface IActionServiceOptions { - scene: GameScene -} - -export class ActionService { - public possibleCommands!: ICommandWithAction[] - public possibleActions!: IGameSceneAction[] - public activeActions!: IGameSceneAction[] - public scene: GameScene - - constructor({ scene }: IActionServiceOptions) { - this.scene = scene - - void this.initActions() - } - - async initActions() { - this.possibleActions = [ - "HELP", - "GIFT", - "TRADE", - "DONATE", - "REFUEL", - "STEAL_FUEL", - "CHOP", - "MINE", - "PLANT", - "START_GROUP_BUILD", - "DISBAND_GROUP", - "JOIN_GROUP", - "START_POLL", - "VOTE", - "START_CHANGING_SCENE", - "START_RAID", - "CREATE_NEW_PLAYER", - "START_CREATING_NEW_ADVENTURE", - "SHOW_MESSAGE", - "GITHUB", - ] - this.activeActions = this.possibleActions - } - - public findActionByCommand(command: string) { - return this.possibleCommands.find((a) => a.command === command) - } - - public findDynamicActionByCommand(command: string) { - const quest = this.scene.eventService.findActionByCommandInQuest(command) - if (quest) { - return quest - } - - const poll = this.scene.eventService.findActionByCommandInPoll(command) - if (poll) { - return poll - } - } - - public async handleAction( - action: IGameSceneAction, - playerId: string, - params?: string[], - ) { - const player = await this.scene.findOrCreatePlayer(playerId) - if (!player) { - return ANSWER.NO_PLAYER_ERROR - } - - this.scene.group.join(player) - player.updateLastActionAt() - - if (action === "SHOW_MESSAGE") { - return this.showMessageAction(player, params) - } - if (action === "REFUEL") { - return this.refuelAction(player, params) - } - if (action === "CHOP") { - return this.chopAction(player) - } - if (action === "MINE") { - return this.mineAction(player) - } - if (action === "PLANT") { - return this.plantAction(player) - } - if (action === "START_RAID") { - return this.startRaidAction(player, params) - } - if (action === "START_CHANGING_SCENE") { - // Admin only - if (player.id !== ADMIN_PLAYER_ID) { - return ANSWER.ERROR - } - return this.startChangingSceneAction(player, params) - } - if (action === "START_GROUP_BUILD") { - // Admin only - if (player.id !== ADMIN_PLAYER_ID) { - return ANSWER.ERROR - } - return this.startGroupBuildAction(player, params) - } - if (action === "DISBAND_GROUP") { - // Admin only - if (player.id !== ADMIN_PLAYER_ID) { - return ANSWER.ERROR - } - return this.disbandGroupAction() - } - if (action === "STEAL_FUEL") { - return this.stealFuelAction(player) - } - if (action === "HELP") { - return this.helpAction(player) - } - if (action === "GITHUB") { - return this.githubAction(player) - } - if (action === "DONATE") { - return this.donateAction(player) - } - if (action === "GIFT") { - return this.giftAction(player, params) - } - if (action === "TRADE") { - return this.tradeAction(player, params) - } - if (action === "CREATE_IDEA") { - return this.createIdeaAction(player, params) - } - - return ANSWER.ERROR - } - - public async handleDynamicAction( - action: Action, - playerId: string, - params: string[], - ): Promise { - const player = await this.scene.findOrCreatePlayer(playerId) - if (!player) { - return ANSWER.NO_PLAYER_ERROR - } - - this.scene.group.join(player) - player.updateLastActionAt() - - const answer = await action.live(player, params) - if (answer) { - return answer - } - - return ANSWER.ERROR - } - - public getAvailableCommands() { - const commands: string[] = [] - for (const action of this.activeActions) { - if (action === "HELP") { - commands.push("!помощь") - } - if (action === "REFUEL") { - commands.push("!заправить [кол-во]") - } - if (action === "CHOP") { - commands.push("!рубить") - } - if (action === "MINE") { - commands.push("!добыть") - } - if (action === "GIFT") { - commands.push("!подарить [название] [кол-во]") - } - if (action === "DONATE") { - commands.push("!донат") - } - } - - return commands - } - - public isActionPossible(action: IGameSceneAction): boolean { - return !!this.activeActions.find((a) => a === action) - } - - private startRaidAction(player: Player, params?: string[]) { - // First param is raidersCount - const raidersCount = params ? Number(params[0]) : 0 - - this.scene.eventService.init({ - title: "The raid has started!", - description: "", - type: "RAID_STARTED", - secondsToEnd: 60 * 5, - }) - this.scene.initRaiders(raidersCount) - - // Raider points - void player.addRaiderPoints(raidersCount) - - return ANSWER.OK - } - - private async showMessageAction(player: Player, params?: string[]) { - if (!this.isActionPossible("SHOW_MESSAGE")) { - return ANSWER.ERROR - } - - if (!params || !params[0]) { - return ANSWER.ERROR - } - - const message = params[0] - player.addMessage(message) - - return ANSWER.OK - } - - private async stealFuelAction(player: Player) { - if (!this.isActionPossible("STEAL_FUEL")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - this.scene.wagonService.wagon.emptyFuel() - - await player.addVillainPoints(1) - - return { - ok: true, - message: `${player.userName}, and you're a villain!`, - } - } - - private async refuelAction(player: Player, params?: string[]) { - if (!this.isActionPossible("REFUEL")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - if (!params) { - return ANSWER.NO_TARGET_ERROR - } - - const count = this.getAmountFromChatCommand(params[0]) - if (!count) { - return ANSWER.WRONG_AMOUNT_ERROR - } - - const items = player.inventory?.items ?? [] - const itemExist = items.find((item) => item.type === "WOOD") - if (!itemExist) { - return { - ok: false, - message: `${player.userName}, you don't have wood.`, - } - } - - const isSuccess = await player.inventory?.reduceOrDestroyItem( - itemExist.type, - count, - ) - if (!isSuccess) { - return { - ok: false, - message: `${player.userName}, not enough wood.`, - } - } - - await player.addRefuellerPoints(count) - - this.scene.wagonService.wagon.refuel(count) - - return { - ok: true, - message: `${player.userName}, you helped refuel the Wagon.`, - } - } - - getAmountFromChatCommand(text: string): number | null { - if (typeof Number(text) === "number" && Number(text) > 0) { - return Math.round(Number(text)) - } - - return null - } - - private async chopAction(player: Player) { - if (!this.isActionPossible("CHOP")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - if (player.script && !player.script.isInterruptible) { - return ANSWER.BUSY_ERROR - } - - const target = this.scene.getTreeToChop() - if (!target) { - return ANSWER.NO_AVAILABLE_TREE_ERROR - } - - const chopTreeFunc = (): boolean => { - void player.chopTree() - if (!player.target || player.target.state === "DESTROYED") { - player.state = "IDLE" - if (player.target instanceof Tree) { - void player.inventory.addOrCreateItem("WOOD", player.target?.resource) - } - return true - } - return false - } - - player.script = new ChopTreeScript({ - object: player, - target, - chopTreeFunc, - }) - - return ANSWER.OK - } - - private async mineAction(player: Player) { - if (!this.isActionPossible("MINE")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - if (player.script && !player.script.isInterruptible) { - return { - ok: false, - message: `${player.userName}, you're busy right now.`, - } - } - - const target = this.scene.getStoneToMine() - if (!target) { - return { - ok: false, - message: `${player.userName}, there is no available stone.`, - } - } - - const mineStoneFunc = (): boolean => { - void player.mineStone() - if (!player.target || player.target.state === "DESTROYED") { - player.state = "IDLE" - if (player.target instanceof Stone) { - void player.inventory.addOrCreateItem( - "STONE", - player.target?.resource, - ) - } - return true - } - return false - } - - player.script = new MineStoneScript({ - object: player, - target, - mineStoneFunc, - }) - - return ANSWER.OK - } - - private plantAction(player: Player) { - if (!this.isActionPossible("PLANT")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - if (player.script && !player.script.isInterruptible) { - return { - ok: false, - message: `${player.userName}, you're busy right now.`, - } - } - - if (this.scene.chunkNow instanceof Village) { - const target = this.scene.chunkNow.checkIfNeedToPlantTree() - if (!target) { - return { - ok: false, - message: `${player.userName}, no space available.`, - } - } - - const plantNewTreeFunc = () => { - if (this.scene.chunkNow instanceof Village) { - this.scene.chunkNow.plantNewTree(target) - } - } - - player.script = new PlantNewTreeScript({ - object: player, - target, - plantNewTreeFunc, - }) - - return ANSWER.OK - } - - return ANSWER.ERROR - } - - private startChangingSceneAction(_: Player, params?: string[]) { - if (!this.isActionPossible("START_CHANGING_SCENE")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - if (!params) { - return ANSWER.NO_TARGET_ERROR - } - - const scene = this.getSceneTypeFromChatCommand(params[1]) - if (!scene) { - return ANSWER.NO_TARGET_ERROR - } - - this.scene.eventService.init({ - type: "SCENE_CHANGING_STARTED", - title: "Changing location", - description: "", - scene, - secondsToEnd: 10, - }) - - return ANSWER.OK - } - - getSceneTypeFromChatCommand(text: string): GameSceneType | null { - if (text === "деревня" || text === "деревню") { - return "VILLAGE" - } - if (text === "защиту" || text === "защита") { - return "DEFENCE" - } - - return null - } - - private startGroupBuildAction(_: Player, params?: string[]) { - if (!this.isActionPossible("START_GROUP_BUILD")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - if (!params) { - return ANSWER.NO_TARGET_ERROR - } - - const scene = this.getSceneTypeFromChatCommand(params[1]) - if (!scene) { - return ANSWER.NO_TARGET_ERROR - } - - this.scene.group = new Group() - - this.scene.eventService.init({ - type: "GROUP_FORM_STARTED", - title: "The group is recruiting!", - description: "", - scene, - secondsToEnd: 120, - }) - - return ANSWER.OK - } - - private disbandGroupAction() { - if (!this.isActionPossible("DISBAND_GROUP")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - this.scene.group?.disband() - - return { - ok: true, - message: "The group has been disbanded!", - } - } - - private helpAction(player: Player) { - if (!this.isActionPossible("HELP")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - return { - ok: true, - message: `${player.userName}, this is an interactive chat game that any viewer can participate in! Basic commands: !chop, !mine. The remaining commands appear in events (on the right of the screen). Join our community: ${DISCORD_SERVER_INVITE_URL}`, - } - } - - private githubAction(player: Player) { - if (!this.isActionPossible("GITHUB")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - return { - ok: true, - message: `${player.userName}, the game code is in the repository: ${GITHUB_REPO_URL}`, - } - } - - private donateAction(player: Player) { - if (!this.isActionPossible("DONATE")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - return { - ok: true, - message: `${player.userName}, support the game: ${DONATE_URL}`, - } - } - - private async giftAction(player: Player, params: string[] | undefined) { - if (!this.isActionPossible("GIFT")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - if (!params) { - return { - ok: false, - message: `${player.userName}, be more specific.`, - } - } - - const item = this.getItemTypeFromChatCommand(params[0]) - if (!item) { - return { - ok: false, - message: `${player.userName}, be more specific.`, - } - } - - const amount = this.getAmountFromChatCommand(params[1]) - if (!amount) { - return { - ok: false, - message: `${player.userName}, be more specific.`, - } - } - - let warehouse: Warehouse | undefined - if (this.scene.chunkNow instanceof Village) { - warehouse = this.scene.chunkNow.getWarehouse() - } - - if (item === "WOOD") { - const isSuccess = await player.inventory.reduceOrDestroyItem(item, amount) - if (!isSuccess) { - return { - ok: false, - message: `${player.userName}, you don't have enough wood.`, - } - } - - await warehouse?.inventory.addOrCreateItem(item, amount) - await player.addReputation(amount) - - return { - ok: true, - message: `${player.userName}, you gave wood to the village! Your reputation has increased.`, - } - } - if (item === "STONE") { - const isSuccess = await player.inventory.reduceOrDestroyItem(item, amount) - if (!isSuccess) { - return { - ok: false, - message: `${player.userName}, you don't have enough stone.`, - } - } - - await warehouse?.inventory.addOrCreateItem(item, amount) - await player.addReputation(amount) - - return { - ok: true, - message: `${player.userName}, you gave stones to the village! Your reputation has increased.`, - } - } - - return { - ok: false, - message: `${player.userName}, be more specific.`, - } - } - - getItemTypeFromChatCommand(text: string): ItemType | null { - if (text === "wood") { - return "WOOD" - } - if (text === "stone") { - return "STONE" - } - if (text === "axe") { - return "AXE" - } - if (text === "pickaxe") { - return "PICKAXE" - } - - return null - } - - private async tradeAction(player: Player, params: string[] | undefined) { - if (!this.isActionPossible("TRADE")) { - return ANSWER.CANT_DO_THIS_NOW_ERROR - } - - if (!params) { - return ANSWER.NO_TARGET_ERROR - } - - const amount = this.getAmountFromChatCommand(params[1]) - if (!amount) { - return ANSWER.WRONG_AMOUNT_ERROR - } - - const status = await this.scene.tradeService.findActiveOfferAndTrade( - params[0], - amount, - player, - ) - if (status === "OFFER_ERROR") { - return { - ok: false, - message: "Something is wrong. The deal fell through.", - } - } - if (status === "OFFER_NOT_FOUND") { - return ANSWER.NO_TARGET_ERROR - } - - return { - ok: true, - message: `${player.userName}, successful trade deal!`, - } - } - - private createIdeaAction(player: Player, params: string[] | undefined) { - const text = params ? params[0] : "" - - this.scene.eventService.init({ - title: "New idea from Twitch Viewer!", - description: `${player.userName}: ${text}`, - type: "IDEA_CREATED", - secondsToEnd: 60 * 3, - }) - - return ANSWER.OK - } -} diff --git a/apps/client/src/game/services/eventService.ts b/apps/client/src/game/services/eventService.ts deleted file mode 100644 index 44e1b02f..00000000 --- a/apps/client/src/game/services/eventService.ts +++ /dev/null @@ -1,260 +0,0 @@ -import type { - GameSceneType, - IGameEvent, - IGamePoll, - IGameQuest, - IGameQuestTask, -} from "../../../../../packages/api-sdk/src" -import type { Action } from "../actions/action" -import { Village } from "../chunks" -import { Event } from "../common" -import type { GameScene } from "../scenes/gameScene" -import { PollService } from "./pollService" -import { QuestService } from "./questService" - -interface IEventServiceOptions { - scene: GameScene -} - -export class EventService { - public events: Event[] = [] - public questService: QuestService - public pollService: PollService - public scene: GameScene - - constructor({ scene }: IEventServiceOptions) { - this.scene = scene - this.questService = new QuestService({ scene }) - this.pollService = new PollService({ scene }) - } - - public update() { - for (const event of this.events) { - const status = event.checkStatus() - - if (status === "STOPPED") { - this.handleEnding(event) - this.destroy(event) - } - - this.updateSuccessPollsWithQuest(event) - this.updateClosedQuests(event) - } - - this.pollService.update() - this.questService.update() - } - - public init({ - title, - description, - type, - secondsToEnd, - scene, - poll, - quest, - offers, - }: { - title: IGameEvent["title"] - description: IGameEvent["description"] - type: IGameEvent["type"] - secondsToEnd: number - scene?: GameSceneType - poll?: IGameEvent["poll"] - quest?: IGameEvent["quest"] - offers?: IGameEvent["offers"] - }) { - const event = new Event({ - title, - description, - type, - secondsToEnd, - scene, - poll, - quest, - offers, - }) - - this.events.push(event) - } - - public getEvents(): IGameEvent[] { - return this.events.map((event) => ({ - id: event.id, - title: event.title, - description: event.description, - type: event.type, - status: event.status, - endsAt: event.endsAt, - poll: this.preparePollData(event.poll), - quest: this.prepareQuestData(event.quest), - offers: event.offers, - })) - } - - prepareQuestData(quest: IGameQuest | undefined) { - if (!quest) { - return - } - - const tasks = quest?.tasks.map((t) => { - const action = t.action - ? { - ...t.action, - live: undefined, - scene: undefined, - } - : undefined - return { ...t, action } - }) - - return { - ...quest, - tasks, - } - } - - preparePollData(poll: IGamePoll | undefined) { - if (!poll) { - return - } - - return { - ...poll, - action: { - ...poll.action, - poll: undefined, - live: undefined, - scene: undefined, - }, - scene: undefined, - } - } - - public destroy(event: Event) { - const index = this.events.indexOf(event) - this.events.splice(index, 1) - } - - public findActionByCommandInQuest(command: string) { - for (const event of this.events) { - if (event.quest?.tasks) { - const task = event.quest.tasks.find( - (q) => q.action?.command === command, - ) - if (task?.action) { - return task.action as Action - } - } - } - } - - public findActionByCommandInPoll(command: string) { - for (const event of this.events) { - if (event.poll?.action && event.poll.action.command === command) { - return event.poll?.action as Action - } - } - } - - private handleEnding(event: Event) { - if (event.type === "SCENE_CHANGING_STARTED" && event.scene) { - this.scene.game.initScene(event.scene) - } - if (event.type === "GROUP_FORM_STARTED" && event.scene) { - this.scene.game.initScene(event.scene) - } - if (event.type === "RAID_STARTED") { - this.scene.stopRaid() - } - if (event.type === "TRADE_STARTED") { - this.scene.tradeService.handleTradeIsOver() - } - if (event.type === "VOTING_FOR_NEW_MAIN_QUEST_STARTED") { - this.scene.tradeService.handleTradeIsOver() - } - } - - private destroyAllEventsWithPoll() { - for (const event of this.events) { - if (event.poll) { - this.destroy(event) - } - } - } - - private updateSuccessPollsWithQuest(event: Event) { - if (event.poll?.status !== "SUCCESS" || !event.quest) { - return - } - - const updateProgress1: IGameQuestTask["updateProgress"] = () => { - if ( - !this.scene.wagonService.routeService.route?.flags && - this.events.find((e) => e.type === "MAIN_QUEST_STARTED") - ) { - return { - status: "SUCCESS", - } - } - - const items = - this.scene.wagonService.wagon.cargo?.checkIfAlreadyHaveItem("WOOD") - if (!items) { - return { - status: "FAILED", - progressNow: 0, - } - } - - return { - status: "ACTIVE", - progressNow: items.amount, - } - } - - const tasks = [ - this.questService.createTask({ - updateProgress: updateProgress1, - description: "Transport cargo safely", - progressNow: 100, - progressToSuccess: 60, - }), - ] - - this.init({ - title: "Journey", - description: "", - type: "MAIN_QUEST_STARTED", - secondsToEnd: event.quest.conditions.limitSeconds ?? 9999999, - quest: { - ...event.quest, - status: "ACTIVE", - tasks, - }, - }) - - // Cargo - this.scene.wagonService.wagon.setCargo() - - if (this.scene.chunkNow instanceof Village) { - this.scene.wagonService.routeService.generateAdventure( - this.scene.chunkNow, - event.quest.conditions.chunks ?? 3, - ) - } - - this.scene.tradeService.traderIsMovingWithWagon = true - - this.destroyAllEventsWithPoll() - } - - private updateClosedQuests(event: Event) { - if (event.status === "STARTED" && event.quest) { - if (event.quest.status === "FAILED" || event.quest.status === "SUCCESS") { - // - event.status = "STOPPED" - } - } - } -} diff --git a/apps/client/src/game/services/pollService.ts b/apps/client/src/game/services/pollService.ts deleted file mode 100644 index 076635c4..00000000 --- a/apps/client/src/game/services/pollService.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { - IGameObjectPlayer, - IGamePoll, -} from "../../../../../packages/api-sdk/src" -import type { Player } from "../objects/units" -import type { GameScene } from "../scenes/gameScene" - -interface IPollServiceOptions { - scene: GameScene -} - -export class PollService { - public scene: GameScene - - constructor({ scene }: IPollServiceOptions) { - this.scene = scene - } - - public update() { - for (const event of this.scene.eventService.events) { - if (!event.poll || event.poll.status !== "ACTIVE") { - continue - } - - if (event.poll.votes.length >= event.poll.votesToSuccess) { - event.poll.status = "SUCCESS" - } - } - } - - public findActivePollAndVote(pollId: string, player: Player) { - for (const event of this.scene.eventService.events) { - if (event.poll && event.poll?.id === pollId) { - const voted = this.vote(event.poll, player) - if (!voted) { - return "VOTED_ALREADY" - } - return "VOTE_SUCCESS" - } - } - - return "POLL_NOT_FOUND" - } - - private vote(poll: IGamePoll, player: IGameObjectPlayer): boolean { - if (poll.votes.find((v) => v.id === player.id)) { - return false - } - - poll.votes.push({ id: player.id, userName: player.userName }) - return true - } -} diff --git a/apps/client/src/game/services/questService.ts b/apps/client/src/game/services/questService.ts deleted file mode 100644 index a4a5f7f8..00000000 --- a/apps/client/src/game/services/questService.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { createId } from "@paralleldrive/cuid2" -import type { - IGameQuest, - IGameQuestTask, - IGameQuestTaskFunc, -} from "../../../../../packages/api-sdk/src" -import { DonateWoodToVillageAction } from "../actions/donateWoodToVillageAction" -import { PlantTreeAction } from "../actions/plantTreeAction" -import { Village } from "../chunks" -import { NoTradingPostQuest } from "../quests/noTradingPostQuest" -import { TreesAreRunningOutQuest } from "../quests/treesAreRunningOutQuest" -import type { GameScene } from "../scenes/gameScene" - -interface IQuestServiceOptions { - scene: GameScene -} - -export class QuestService { - public scene: GameScene - - constructor({ scene }: IQuestServiceOptions) { - this.scene = scene - } - - public update() { - this.updateAndFinishActiveQuests() - - if (this.scene.chunkNow instanceof Village) { - this.generateNewSideQuest() - } - - for (const event of this.scene.eventService.events) { - if (!event.quest) { - continue - } - - for (const task of event.quest.tasks) { - if (task.status === "ACTIVE") { - this.updateQuestActiveTask(task) - } - } - } - } - - public create({ - status, - type, - tasks, - conditions, - creatorId, - title, - description, - }: Omit): IGameQuest { - return { - id: createId(), - status, - title, - description, - type, - tasks, - conditions, - creatorId, - } - } - - public createTask({ - updateProgress, - progressToSuccess, - progressNow, - description, - }: Pick< - IGameQuestTask, - "description" | "progressToSuccess" | "progressNow" | "updateProgress" - >): IGameQuestTask { - return { - id: createId(), - status: "ACTIVE", - description, - progressNow, - progressToSuccess, - updateProgress, - } - } - - private updateQuestActiveTask(task: IGameQuestTask) { - const progress = task.updateProgress(task.progressToSuccess) - - if (typeof progress.status !== "undefined") { - task.status = progress.status - } - if (typeof progress.progressNow !== "undefined") { - task.progressNow = progress.progressNow - } - if (typeof progress.progressToSuccess !== "undefined") { - task.progressToSuccess = progress.progressToSuccess - } - } - - private updateAndFinishActiveQuests() { - for (const event of this.scene.eventService.events) { - if (!event.quest || event.quest.status !== "ACTIVE") { - continue - } - - // Tasks done? - if (!event.quest.tasks.find((t) => t.status === "ACTIVE")) { - // - this.scene.wagonService.wagon.emptyCargo() - this.scene.tradeService.traderIsMovingWithWagon = false - - if (!event.quest.tasks.find((t) => t.status === "FAILED")) { - // Reward - event.quest.status = "SUCCESS" - continue - } - - event.quest.status = "FAILED" - } - } - } - - private generateSecondSideQuest() { - const sideQuests = this.scene.eventService.events.filter( - (e) => e.type === "SIDE_QUEST_STARTED", - ) - if (sideQuests.length >= 1) { - return - } - - const taskUpdateFunc1: IGameQuestTask["updateProgress"] = () => { - if (this.scene.chunkNow instanceof Village) { - const treesAmount = this.scene.chunkNow.getTreesAmount() - if (treesAmount >= 30) { - return { - status: "SUCCESS", - progressNow: treesAmount, - } - } - - return { - status: "ACTIVE", - progressNow: treesAmount, - } - } - - return { - status: "ACTIVE", - } - } - - const taskAction1 = new PlantTreeAction({ scene: this.scene }) - - const quest = new TreesAreRunningOutQuest({ - creatorId: "1", - taskUpdateFunc1, - taskAction1, - }) - - this.scene.eventService.init({ - type: "SIDE_QUEST_STARTED", - title: quest.title, - description: quest.description, - secondsToEnd: 9999999, - quest, - }) - } - - private generateNewSideQuest() { - if (!this.scene.chunkNow) { - return - } - - if (this.scene.chunkNow instanceof Village) { - const store = this.scene.chunkNow.getStore() - if (store) { - const notEnough = this.scene.chunkNow.checkIfThereAreNotEnoughTrees() - if (notEnough) { - return this.generateSecondSideQuest() - } - - return - } - } - - const sideQuests = this.scene.eventService.events.filter( - (e) => e.type === "SIDE_QUEST_STARTED", - ) - if (sideQuests.length >= 1) { - return - } - - const taskUpdateFunc1: IGameQuestTaskFunc = () => { - if (this.scene.chunkNow instanceof Village) { - const warehouse = this.scene.chunkNow.getWarehouse() - if (warehouse) { - const wood = warehouse.getItemByType("WOOD") - if (wood?.amount) { - if (wood.amount >= 25) { - return { - status: "SUCCESS", - progressNow: wood.amount, - } - } - - return { - status: "ACTIVE", - progressNow: wood.amount, - } - } - } - } - - return { - status: "ACTIVE", - } - } - - const taskAction1 = new DonateWoodToVillageAction({ scene: this.scene }) - - const taskUpdateFunc2: IGameQuestTaskFunc = () => { - if (this.scene.chunkNow instanceof Village) { - const store = this.scene.chunkNow.getStore() - if (store) { - return { - status: "SUCCESS", - progressNow: true, - } - } - } - - return { - status: "ACTIVE", - progressNow: false, - } - } - - const quest = new NoTradingPostQuest({ - creatorId: "1", - taskUpdateFunc1, - taskUpdateFunc2, - taskAction1, - }) - - this.scene.eventService.init({ - type: "SIDE_QUEST_STARTED", - title: quest.title, - description: quest.description, - secondsToEnd: 9999999, - quest, - }) - } -} diff --git a/apps/client/src/game/services/routeService.ts b/apps/client/src/game/services/routeService.ts deleted file mode 100644 index 5713c161..00000000 --- a/apps/client/src/game/services/routeService.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { - type IGameChunkTheme, - type IGameRoute, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Forest, LakeChunk, Village } from "../chunks" -import { Route } from "../common" -import { Stone, Tree } from "../objects" -import type { GameScene } from "../scenes/gameScene" - -interface IRouteServiceOptions { - scene: GameScene -} - -export class RouteService { - public route: Route | undefined - public scene: GameScene - - constructor({ scene }: IRouteServiceOptions) { - this.scene = scene - } - - public update() { - if (!this.route?.flags || this.route.flags.length <= 0) { - if ( - this.scene.eventService.events.find( - (e) => e.type === "MAIN_QUEST_STARTED", - ) - ) { - return this.finishAdventure() - } - } - - if (this.route) { - for (const flag of this.route.flags) { - void flag.live() - } - } - } - - public getRoute(): IGameRoute | null { - if (!this.route) { - return null - } - - return { - startPoint: this.route.startPoint, - endPoint: this.route.endPoint, - chunks: this.route.chunks, - } - } - - generateAdventure(village: Village, chunks: number) { - const wagonStartPoint = village.getWagonStopPoint() - const villageOutPoint = village.getRandomOutPoint() - - this.route = new Route({ scene: this.scene }) - this.route.addGlobalFlag(wagonStartPoint) - this.route.startPoint = wagonStartPoint - this.route.addChunk(village) - - this.generateChunks({ x: villageOutPoint.x, y: villageOutPoint.y }, chunks) - this.markObjectsAsOnWagonPath(this.route) - } - - generateChunks(startPoint: { x: number; y: number }, amount: number) { - let outPoint = startPoint - - for (let i = 1; i <= amount; i++) { - const chunk = this.generateRandomChunk(outPoint) - outPoint = chunk.getRandomOutPoint() - this.route?.addGlobalFlag(outPoint) - this.route?.addChunk(chunk) - } - - // Generate last chunk - const finalVillageWidth = 3600 - const finalVillage = this.generateRandomVillage({ - center: { x: outPoint.x + finalVillageWidth / 2, y: outPoint.y }, - width: finalVillageWidth, - height: 2000, - theme: this.getRandomTheme(), - scene: this.scene, - }) - this.scene.chunks.push(finalVillage) - const stopPoint = finalVillage.getWagonStopPoint() - this.route?.addGlobalFlag(stopPoint) - this.route?.addChunk(finalVillage) - this.route?.setEndPoint(stopPoint) - } - - generateRandomChunk(startPoint: { x: number; y: number }) { - const random = getRandomInRange(1, 2) - - const width = getRandomInRange(2000, 3000) - const height = getRandomInRange(2500, 3500) - const center = { - x: startPoint.x + width / 2, - y: startPoint.y, - } - - switch (random) { - case 1: - return this.generateRandomForest({ - center, - width, - height, - theme: this.getRandomTheme(), - }) - case 2: - return this.generateRandomLake({ - center, - width, - height, - theme: this.getRandomTheme(), - }) - } - - return this.generateRandomForest({ - center, - width, - height, - theme: this.getRandomTheme(), - }) - } - - markObjectsAsOnWagonPath(route: Route) { - for (const chunk of this.scene.chunks) { - for (const object of chunk.objects) { - if (object instanceof Tree || object instanceof Stone) { - const isOnPath = route.checkIfPointIsOnWagonPath({ - x: object.x, - y: object.y, - }) - if (isOnPath) { - object.isOnWagonPath = true - } - } - } - } - } - - generateRandomVillage({ - center, - width, - height, - theme, - scene, - }: { - center: { x: number; y: number } - width: number - height: number - theme: IGameChunkTheme - scene: GameScene - }) { - return new Village({ width, height, center, theme, scene }) - } - - generateRandomForest({ - center, - width, - height, - theme, - }: { - center: { x: number; y: number } - width: number - height: number - theme: IGameChunkTheme - }) { - const forest = new Forest({ - scene: this.scene, - width, - height, - center, - theme - }) - this.scene.chunks.push(forest) - return forest - } - - generateRandomLake({ - center, - width, - height, - theme, - }: { - center: { x: number; y: number } - width: number - height: number - theme: IGameChunkTheme - }) { - const lake = new LakeChunk({ width, height, center, theme }) - this.scene.chunks.push(lake) - return lake - } - - getRandomTheme(): IGameChunkTheme { - const themes: IGameChunkTheme[] = [ - "GREEN", - "BLUE", - "STONE", - "TEAL", - "VIOLET", - "TOXIC", - ] - return themes[Math.floor(Math.random() * themes.length)] - } - - finishAdventure() { - console.log("Adventure finished!", new Date()) - this.route = undefined - this.scene.wagonService.wagon.emptyCargo() - this.scene.tradeService.traderIsMovingWithWagon = false - this.scene.tradeService.handleTradeIsOver() - - if (this.scene.chunkNow?.id) { - const id = this.scene.chunkNow.id - this.scene.chunks = this.scene.chunks.filter((chunk) => chunk.id === id) - } - } -} diff --git a/apps/client/src/game/services/tradeService.ts b/apps/client/src/game/services/tradeService.ts deleted file mode 100644 index 4c624d99..00000000 --- a/apps/client/src/game/services/tradeService.ts +++ /dev/null @@ -1,317 +0,0 @@ -import { - type ITradeOffer, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Village } from "../chunks" -import { Poll } from "../common" -import { Flag } from "../objects" -import type { Player } from "../objects/units" -import { Trader } from "../objects/units" -import type { GameScene } from "../scenes/gameScene" -import { MoveOffScreenAndSelfDestroyScript } from "../scripts/moveOffScreenAndSelfDestroyScript" -import { MoveToTargetScript } from "../scripts/moveToTargetScript" -import { MoveToTradePostAndTradeScript } from "../scripts/moveToTradePostAndTradeScript" - -interface ITradeServiceOptions { - scene: GameScene -} - -export class TradeService { - public offers: ITradeOffer[] = [] - public tradeWasSuccessful: boolean - public traderIsMovingWithWagon: boolean - public scene: GameScene - - constructor({ scene }: ITradeServiceOptions) { - this.scene = scene - this.traderIsMovingWithWagon = false - this.tradeWasSuccessful = false - } - - public update() { - this.checkAndGenerateTrader() - this.checkClosedOffers() - } - - public getTrader() { - return this.scene.objects.find((obj) => obj instanceof Trader) as - | Trader - | undefined - } - - public getStore() { - if (this.scene.chunkNow instanceof Village) { - return this.scene.chunkNow.getStore() - } - } - - public async findActiveOfferAndTrade( - offerId: string, - amount: number, - player: Player, - ) { - for (const offer of this.offers) { - if (offer.id === offerId) { - const status = await this.trade(offer, amount, player) - if (!status) { - return "OFFER_ERROR" - } - return "OFFER_SUCCESS" - } - } - - return "OFFER_NOT_FOUND" - } - - public async trade( - offer: ITradeOffer, - amount: number, - player: Player, - ): Promise { - if (offer.amount < amount) { - return false - } - - if (offer.type === "BUY") { - const item = player.inventory.checkIfAlreadyHaveItem(offer.item) - if (!item || item.amount < amount) { - return false - } - - await player.updateCoins(offer.unitPrice * amount) - await player.inventory.reduceOrDestroyItem(item.type, amount) - - offer.amount -= amount - return true - } - - return false - } - - public updateTrader(object: Trader) { - object.live() - - if (!object.script) { - if (this.traderIsMovingWithWagon) { - // Moving near Wagon - const random = getRandomInRange(1, 150) - if (random <= 1) { - const target = this.scene.wagonService.findRandomNearFlag() - object.script = new MoveToTargetScript({ - object, - target, - }) - return - } - } - - // Moving to Trade - if (this.checkIfNeedToStartTrade()) { - if (this.scene.chunkNow instanceof Village) { - const target = this.getTradePointFlag() - if (target) { - const startTradeFunc = () => { - this.scene.eventService.init({ - title: "Trade in progress", - description: "", - type: "TRADE_STARTED", - secondsToEnd: 60 * 6, - offers: this.offers, - }) - } - - object.script = new MoveToTradePostAndTradeScript({ - object, - target, - startTradeFunc, - }) - return - } - } - } - } - } - - public handleTradeIsOver() { - const trader = this.getTrader() - if (!trader) { - return - } - - const target = this.scene.wagonService.findRandomOutFlag() - const selfDestroyFunc = () => { - this.scene.removeObject(trader) - } - - trader.script = new MoveOffScreenAndSelfDestroyScript({ - object: trader, - target, - selfDestroyFunc, - }) - - this.removeTrade() - } - - public removeTrade() { - this.offers = [] - for (const event of this.scene.eventService.events) { - if (event.type === "TRADE_STARTED") { - this.scene.eventService.destroy(event) - } - } - } - - private checkIfNeedToStartTrade(): boolean { - if (this.tradeWasSuccessful) { - return false - } - - const activeTrade = this.scene.eventService.events.find( - (e) => e.type === "TRADE_STARTED", - ) - return !activeTrade - } - - private getTradePointFlag() { - return this.scene.chunkNow?.objects.find( - (obj) => obj instanceof Flag && obj.type === "TRADE_POINT", - ) as Flag | undefined - } - - private createTradeTargetFlagNearStore() { - if (this.getTradePointFlag()) { - return - } - - const store = this.getStore() - if (!store) { - return - } - - const flag = new Flag({ - scene: this.scene, - x: store.x + 105, - y: store.y + 10, - type: "TRADE_POINT", - }) - this.scene.chunkNow?.objects.push(flag) - } - - private checkAndGenerateTrader() { - if (this.scene.chunkNow instanceof Village) { - const store = this.scene.chunkNow.getStore() - const trader = this.getTrader() - if (store?.id && !trader?.id) { - this.createTradeTargetFlagNearStore() - this.generateNewTrader() - this.generateTradeOffers() - } - } - } - - private checkClosedOffers() { - for (const offer of this.offers) { - if (offer.amount === 0) { - this.tradeWasSuccessful = true - this.removeTrade() - this.generateNewMainQuest() - } - } - } - - private generateNewTrader() { - const { x, y } = this.scene.wagonService.findRandomOutFlag() - const trader = new Trader({ scene: this.scene, x, y }) - - this.scene.objects.push(trader) - } - - private generateTradeOffers() { - const offersAmount = 1 - const offers = [] - - for (let i = 1; i <= offersAmount; i++) { - const id = this.generateId() - const commandToTrade = `!trade ${id}` - - const offer: ITradeOffer = { - id, - type: "BUY", - amount: 25, - unitPrice: 1, - item: "WOOD", - commandToTrade, - } - - offers.push(offer) - } - - this.offers.push(...offers) - this.tradeWasSuccessful = false - } - - private generateId(startId = 1): string { - const id = startId - for (const offer of this.offers) { - if (offer.id === id.toString()) { - const nextTry = id + 1 - return this.generateId(nextTry) - } - } - return id.toString() - } - - generateNewMainQuest() { - const trader = this.getTrader() - if (!trader) { - return - } - - const store = this.getStore() - if (!store) { - return - } - - const votingEvents = this.scene.eventService.events.filter( - (e) => e.type === "VOTING_FOR_NEW_MAIN_QUEST_STARTED", - ) - if (votingEvents.length >= 1) { - return - } - - const adventureEvents = this.scene.eventService.events.filter( - (e) => e.type === "MAIN_QUEST_STARTED", - ) - if (adventureEvents.length >= 1) { - return - } - - const votesToSuccess = - this.scene.findActivePlayers().length >= 2 - ? this.scene.findActivePlayers().length - : 1 - - const poll = new Poll({ votesToSuccess, scene: this.scene }) - - this.scene.eventService.init({ - type: "VOTING_FOR_NEW_MAIN_QUEST_STARTED", - title: "The merchant offers a quest", - description: "Let's make the quest active? Vote in chat.", - secondsToEnd: 180, - quest: this.scene.eventService.questService.create({ - status: "INACTIVE", - type: "MAIN", - title: "Transport cargo to a neighboring village", - description: - "The merchant is worried about the safety of the items in the chest.", - creatorId: trader.id, - tasks: [], - conditions: { - chunks: getRandomInRange(3, 5), - limitSeconds: 3000, - }, - }), - poll, - }) - } -} diff --git a/apps/client/src/game/services/wagonService.ts b/apps/client/src/game/services/wagonService.ts deleted file mode 100644 index c9b37d4f..00000000 --- a/apps/client/src/game/services/wagonService.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { - getMinusOrPlus, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import { Flag, Wagon } from "../objects" -import type { GameScene } from "../scenes/gameScene" -import { RouteService } from "./routeService" - -interface IWagonServiceOptions { - scene: GameScene -} - -export class WagonService { - public wagon!: Wagon - public outFlags: Flag[] = [] - public nearFlags: Flag[] = [] - public routeService: RouteService - public scene: GameScene - - constructor({ scene }: IWagonServiceOptions) { - this.scene = scene - this.routeService = new RouteService({ scene }) - } - - public update() { - this.updateWagon() - this.updateFlags() - this.routeService.update() - } - - public initWagon({ x, y }: { x: number; y: number }) { - this.wagon = new Wagon({ scene: this.scene, x, y }) - - this.initOutFlags() - this.initNearFlags() - } - - public findRandomOutFlag() { - return this.outFlags[Math.floor(Math.random() * this.outFlags.length)] - } - - public findRandomNearFlag() { - return this.nearFlags[Math.floor(Math.random() * this.nearFlags.length)] - } - - private updateWagon() { - const collisionObjects = - this.scene.chunkNow?.objects.filter( - (obj) => obj.isOnWagonPath && obj.state !== "DESTROYED", - ) ?? [] - for (const collisionObject of collisionObjects) { - const isInArea = this.wagon.checkIfPointInCollisionArea({ - x: collisionObject.x, - y: collisionObject.y, - }) - if (isInArea) { - this.wagon.state = "WAITING" - this.wagon.speedPerSecond = 0 - return - } - } - - if (this.wagon.fuel <= 1) { - this.wagon.state = "WAITING" - this.wagon.speedPerSecond = 0 - return - } - - if (this.wagon.state === "WAITING") { - this.wagon.state = "IDLE" - } - if (this.wagon.state === "IDLE") { - const target = this.routeService.route?.getNextFlag() - if (target) { - this.wagon.target = target - this.wagon.state = "MOVING" - } - } - if (this.wagon.state === "MOVING") { - this.wagon.speedPerSecond = 0.5 - const isMoving = this.wagon.move() - - if (!isMoving) { - if ( - this.wagon.target instanceof Flag && - this.wagon.target.type === "WAGON_MOVEMENT" - ) { - this.routeService.route?.removeFlag(this.wagon.target) - this.wagon.target = undefined - this.wagon.state = "IDLE" - this.wagon.speedPerSecond = 0 - } - } - } - - this.wagon.live() - } - - private updateFlags() { - for (const flag of this.nearFlags) { - flag.x = this.wagon.x + flag.offsetX - flag.y = this.wagon.y + flag.offsetY - } - for (const flag of this.outFlags) { - flag.x = this.wagon.x + flag.offsetX - flag.y = this.wagon.y + flag.offsetY - } - } - - private initOutFlags(count = 20) { - for (let i = 0; i < count; i++) { - this.outFlags.push(this.generateRandomOutFlag()) - } - } - - private initNearFlags(count = 20) { - for (let i = 0; i < count; i++) { - this.nearFlags.push(this.generateRandomNearFlag()) - } - } - - private generateRandomOutFlag() { - const minOffsetX = 1800 - const minOffsetY = 1200 - - const offsetX = - getRandomInRange(minOffsetX, minOffsetX * 1.5) * getMinusOrPlus() - const offsetY = - getRandomInRange(minOffsetY, minOffsetY * 1.5) * getMinusOrPlus() - - return new Flag({ - scene: this.scene, - type: "OUT_OF_SCREEN", - x: this.wagon.x + offsetX, - y: this.wagon.y + offsetY, - offsetX, - offsetY, - }) - } - - private generateRandomNearFlag() { - const minRadius = 280 - const maxRadius = minRadius * 1.1 - - const angle = Math.random() * Math.PI * 2 - const radius = getRandomInRange(minRadius, maxRadius) - - const offsetX = Math.round(Math.cos(angle) * radius) - const offsetY = Math.round(Math.sin(angle) * radius) - - return new Flag({ - scene: this.scene, - type: "WAGON_NEAR_MOVEMENT", - x: this.wagon.x + offsetX, - y: this.wagon.y + offsetY, - offsetX, - offsetY, - }) - } -} diff --git a/apps/client/src/game/utils/assetsManager.ts b/apps/client/src/game/utils/assetsManager.ts deleted file mode 100644 index 9c10778a..00000000 --- a/apps/client/src/game/utils/assetsManager.ts +++ /dev/null @@ -1,426 +0,0 @@ -import { - AnimatedSprite, - type Application, - Assets, - Graphics, - Sprite, - Texture, - TilingSprite, -} from "pixi.js" -import { - type IGameObjectUnit, - getRandomInRange, -} from "../../../../../packages/api-sdk/src" -import campfireAnimation1 from "../assets/images/animation/campfire/1.png" -import campfireAnimation2 from "../assets/images/animation/campfire/2.png" -import campfireAnimation3 from "../assets/images/animation/campfire/3.png" -import campfireAnimation4 from "../assets/images/animation/campfire/4.png" -import campfireAnimation5 from "../assets/images/animation/campfire/5.png" -import fireParticle1 from "../assets/images/animation/campfire/particle-1.png" -import fireParticle2 from "../assets/images/animation/campfire/particle-2.png" -import fireParticle3 from "../assets/images/animation/campfire/particle-3.png" -import heroRight1 from "../assets/images/animation/hero-moving-right/1.png" -import heroRight2 from "../assets/images/animation/hero-moving-right/2.png" -import heroRight3 from "../assets/images/animation/hero-moving-right/3.png" -import heroRight4 from "../assets/images/animation/hero-moving-right/4.png" -import heroRight5 from "../assets/images/animation/hero-moving-right/5.png" -import heroRight6 from "../assets/images/animation/hero-moving-right/6.png" -import campfire1 from "../assets/images/buildings/camp-fire-1.png" -import constructionArea1 from "../assets/images/buildings/construction-1.png" -import store1 from "../assets/images/buildings/store.png" -import wagonStop1 from "../assets/images/buildings/wagon-stop-1.png" -import warehouse1 from "../assets/images/buildings/warehouse-1.png" -import coin1 from "../assets/images/icons/coin-1.png" -import flag1 from "../assets/images/objects/flag-1.png" -import flag2 from "../assets/images/objects/flag-2.png" -import stone1 from "../assets/images/objects/stone-1.png" -import tree1Blue from "../assets/images/objects/tree/1/blue.png" -import tree1Green from "../assets/images/objects/tree/1/green.png" -import tree1Stone from "../assets/images/objects/tree/1/stone.png" -import tree1Teal from "../assets/images/objects/tree/1/teal.png" -import tree1Toxic from "../assets/images/objects/tree/1/toxic.png" -import tree1Violet from "../assets/images/objects/tree/1/violet.png" -import tree2Blue from "../assets/images/objects/tree/2/blue.png" -import tree2Green from "../assets/images/objects/tree/2/green.png" -import tree2Stone from "../assets/images/objects/tree/2/stone.png" -import tree2Teal from "../assets/images/objects/tree/2/teal.png" -import tree2Toxic from "../assets/images/objects/tree/2/toxic.png" -import tree2Violet from "../assets/images/objects/tree/2/violet.png" -import tree3Blue from "../assets/images/objects/tree/3/blue.png" -import tree3Green from "../assets/images/objects/tree/3/green.png" -import tree3Stone from "../assets/images/objects/tree/3/stone.png" -import tree3Teal from "../assets/images/objects/tree/3/teal.png" -import tree3Toxic from "../assets/images/objects/tree/3/toxic.png" -import tree3Violet from "../assets/images/objects/tree/3/violet.png" -import tree4Blue from "../assets/images/objects/tree/4/blue.png" -import tree4Green from "../assets/images/objects/tree/4/green.png" -import tree4Stone from "../assets/images/objects/tree/4/stone.png" -import tree4Teal from "../assets/images/objects/tree/4/teal.png" -import tree4Toxic from "../assets/images/objects/tree/4/toxic.png" -import tree4Violet from "../assets/images/objects/tree/4/violet.png" -import tree5Blue from "../assets/images/objects/tree/5/blue.png" -import tree5Green from "../assets/images/objects/tree/5/green.png" -import tree5Stone from "../assets/images/objects/tree/5/stone.png" -import tree5Teal from "../assets/images/objects/tree/5/teal.png" -import tree5Toxic from "../assets/images/objects/tree/5/toxic.png" -import tree5Violet from "../assets/images/objects/tree/5/violet.png" -import unitHairClassicRight from "../assets/images/unit/hairstyle/hair-classic-right.png" -import unitHairCoalLongRight from "../assets/images/unit/hairstyle/hair-coal-long-right.png" -import unitHairOrangeWithBeard from "../assets/images/unit/hairstyle/orange-with-beard.png" -import unitHead1Right from "../assets/images/unit/head/head-1-right.png" -import blackTopRight from "../assets/images/unit/top/black-top-right.png" -import blueTopRight from "../assets/images/unit/top/blue-top-right.png" -import darkSilverTopRight from "../assets/images/unit/top/dark-silver-top-right.png" -import greenTopRight from "../assets/images/unit/top/green-top-right.png" -import violetTopRight from "../assets/images/unit/top/violet-top-right.png" -import chest1 from "../assets/images/wagon/chest-1.png" -import wagonEngineCloud1 from "../assets/images/wagon/clouds/1.png" -import wagonEngineCloud2 from "../assets/images/wagon/clouds/2.png" -import wagonEngineCloud3 from "../assets/images/wagon/clouds/3.png" -import wagonEngineCloud4 from "../assets/images/wagon/clouds/4.png" -import wagonEngine1 from "../assets/images/wagon/engine-1.png" -import wagonFuel1 from "../assets/images/wagon/fuel-1.png" -import wagonFuel2 from "../assets/images/wagon/fuel-2.png" -import wagonFuelContainer1 from "../assets/images/wagon/fuel-container.png" -import wagonBase1 from "../assets/images/wagon/wagon-1.png" -import wagonBase2 from "../assets/images/wagon/wagon-2.png" -import wagonWheel1 from "../assets/images/wagon/wheel-1.png" -import water1 from "../assets/images/water/1.png" -import water2 from "../assets/images/water/2.png" -import water3 from "../assets/images/water/3.png" -import water4 from "../assets/images/water/4.png" - -export abstract class AssetsManager { - static assets = [ - { alias: "water1", src: water1 }, - { alias: "water2", src: water2 }, - { alias: "water3", src: water3 }, - { alias: "water4", src: water4 }, - { alias: "player1", src: "/hero/hero_64.png" }, - { alias: "playerLeft", src: "/hero/hero_empty_left_64.png" }, - { alias: "playerTopLeft", src: "/hero/top2_left_64.png" }, - { alias: "playerRight", src: "/hero/hero_empty_right_64.png" }, - { alias: "playerTopRight", src: "/hero/top2_right_64.png" }, - { alias: "stone1", src: stone1 }, - { alias: "rabbitLeft", src: "/creatures/rabbit1_left_64.png" }, - { alias: "rabbitRight", src: "/creatures/rabbit1_right_64.png" }, - { alias: "wolfLeft", src: "/creatures/wolf1_left_64.png" }, - { alias: "wolfRight", src: "/creatures/wolf1_right_64.png" }, - { alias: "wood1", src: "/wood/wood1_64.png" }, - { alias: "stoneRes1", src: "/stone/stone_res1_64.png" }, - { alias: "toolAxe1", src: "/tools/axe1_64.png" }, - { alias: "toolPickaxe1", src: "/tools/pickaxe1_64.png" }, - { alias: "campfire1", src: campfire1 }, - { alias: "campfireAnimation1", src: campfireAnimation1 }, - { alias: "campfireAnimation2", src: campfireAnimation2 }, - { alias: "campfireAnimation3", src: campfireAnimation3 }, - { alias: "campfireAnimation4", src: campfireAnimation4 }, - { alias: "campfireAnimation5", src: campfireAnimation5 }, - { alias: "fireParticle1", src: fireParticle1 }, - { alias: "fireParticle2", src: fireParticle2 }, - { alias: "fireParticle3", src: fireParticle3 }, - { alias: "warehouse1", src: warehouse1 }, - { alias: "wagonStop1", src: wagonStop1 }, - { alias: "store1", src: store1 }, - { alias: "constructionArea1", src: constructionArea1 }, - { alias: "flag1", src: flag1 }, - { alias: "flag2", src: flag2 }, - { alias: "wagonWheel1", src: wagonWheel1 }, - { alias: "wagonBase1", src: wagonBase1 }, - { alias: "wagonBase2", src: wagonBase2 }, - { alias: "wagonEngine1", src: wagonEngine1 }, - { alias: "wagonEngineCloud1", src: wagonEngineCloud1 }, - { alias: "wagonEngineCloud2", src: wagonEngineCloud2 }, - { alias: "wagonEngineCloud3", src: wagonEngineCloud3 }, - { alias: "wagonEngineCloud4", src: wagonEngineCloud4 }, - { alias: "wagonFuelContainer1", src: wagonFuelContainer1 }, - { alias: "wagonFuel1", src: wagonFuel1 }, - { alias: "wagonFuel2", src: wagonFuel2 }, - { alias: "chest1", src: chest1 }, - { alias: "coin1", src: coin1 }, - ] - - static animationAssets = [ - { alias: "heroRight1", src: heroRight1 }, - { alias: "heroRight2", src: heroRight2 }, - { alias: "heroRight3", src: heroRight3 }, - { alias: "heroRight4", src: heroRight4 }, - { alias: "heroRight5", src: heroRight5 }, - { alias: "heroRight6", src: heroRight6 }, - ] - - static headAssets = [{ alias: "unitHead1", src: unitHead1Right }] - - static hairAssets = [ - { alias: "unitHairClassic", src: unitHairClassicRight }, - { alias: "unitHairCoalLong", src: unitHairCoalLongRight }, - { alias: "unitHairOrangeWithBeard", src: unitHairOrangeWithBeard }, - ] - - static topAssets = [ - { alias: "violetTop", src: violetTopRight }, - { alias: "blackTop", src: blackTopRight }, - { alias: "greenTop", src: greenTopRight }, - { alias: "blueTop", src: blueTopRight }, - { alias: "darkSilverTop", src: darkSilverTopRight }, - ] - - static treeAssets = [ - { alias: "tree1Green", src: tree1Green }, - { alias: "tree1Blue", src: tree1Blue }, - { alias: "tree1Stone", src: tree1Stone }, - { - alias: "tree1Teal", - src: tree1Teal, - }, - { - alias: "tree1Toxic", - src: tree1Toxic, - }, - { - alias: "tree1Violet", - src: tree1Violet, - }, - { alias: "tree2Green", src: tree2Green }, - { alias: "tree2Blue", src: tree2Blue }, - { alias: "tree2Stone", src: tree2Stone }, - { - alias: "tree2Teal", - src: tree2Teal, - }, - { - alias: "tree2Toxic", - src: tree2Toxic, - }, - { - alias: "tree2Violet", - src: tree2Violet, - }, - { alias: "tree3Green", src: tree3Green }, - { alias: "tree3Blue", src: tree3Blue }, - { alias: "tree3Stone", src: tree3Stone }, - { - alias: "tree3Teal", - src: tree3Teal, - }, - { - alias: "tree3Toxic", - src: tree3Toxic, - }, - { - alias: "tree3Violet", - src: tree3Violet, - }, - { alias: "tree4Green", src: tree4Green }, - { alias: "tree4Blue", src: tree4Blue }, - { alias: "tree4Stone", src: tree4Stone }, - { - alias: "tree4Teal", - src: tree4Teal, - }, - { - alias: "tree4Toxic", - src: tree4Toxic, - }, - { - alias: "tree4Violet", - src: tree4Violet, - }, - { alias: "tree5Green", src: tree5Green }, - { alias: "tree5Blue", src: tree5Blue }, - { alias: "tree5Stone", src: tree5Stone }, - { - alias: "tree5Teal", - src: tree5Teal, - }, - { - alias: "tree5Toxic", - src: tree5Toxic, - }, - { - alias: "tree5Violet", - src: tree5Violet, - }, - ] - - public static async init() { - await Assets.load(AssetsManager.assets) - await Assets.load(AssetsManager.animationAssets) - await Assets.load(AssetsManager.headAssets) - await Assets.load(AssetsManager.hairAssets) - await Assets.load(AssetsManager.topAssets) - await Assets.load(AssetsManager.treeAssets) - } - - public static getAnimatedSpriteHero(direction: IGameObjectUnit["direction"]) { - const images = [ - "heroRight1", - "heroRight2", - "heroRight3", - "heroRight4", - "heroRight5", - "heroRight6", - ] - const textureArray = [] - - for (const image of images) { - const texture = Texture.from(image) - textureArray.push(texture) - } - - const animation = new AnimatedSprite(textureArray) - animation.anchor.set(0.5, 1) - - if (direction === "LEFT") { - // Flip horizontally - animation.scale.x = -1 - } - - return animation - } - - public static getAnimatedSpriteCampfire() { - const images = [ - "campfireAnimation1", - "campfireAnimation2", - "campfireAnimation3", - "campfireAnimation4", - "campfireAnimation5", - ] - const textureArray = [] - - for (const image of images) { - const texture = Texture.from(image) - textureArray.push(texture) - } - - const animation = new AnimatedSprite(textureArray) - animation.anchor.set(0.5, 1) - - return animation - } - - public static getRandomSpriteForBackground(app: Application) { - const graphics1 = new Graphics() - graphics1.rect(0, 0, 64, 64).fill(0x0b8a8f) - const texture1 = app.renderer.generateTexture(graphics1) - - const sprite1 = Sprite.from(texture1) - const sprite2 = Sprite.from("backgroundTeal2") - const sprite3 = Sprite.from("backgroundTeal3") - const sprite4 = Sprite.from("backgroundTeal4") - const sprite5 = Sprite.from("backgroundTeal5") - - const random = getRandomInRange(1, 100) - if (random <= 55) { - return sprite1 - } - if (random <= 93) { - return sprite2 - } - if (random <= 96) { - return sprite5 - } - if (random <= 98) { - return sprite3 - } - return sprite4 - } - - public static getRandomSpriteForWater() { - const sprite1 = Sprite.from("water1") - const sprite2 = Sprite.from("water2") - const sprite3 = Sprite.from("water3") - const sprite4 = Sprite.from("water4") - - const random = getRandomInRange(1, 100) - if (random <= 70) { - return sprite2 - } - if (random <= 80) { - return sprite4 - } - if (random <= 98) { - return sprite1 - } - return sprite3 - } - - public static generateRandomGridBackground({ - app, - width, - height, - }: { - app: Application - width: number - height: number - }) { - const gridX = Math.ceil(width / 64) - const gridY = Math.floor(height / 64) - - const bg: Sprite[] = [] - - for (let i = 0; i < gridX; i++) { - for (let j = 0; j < gridY; j++) { - const background = AssetsManager.getRandomSpriteForBackground(app) - - background.x = i * 64 - background.y = j * 64 - - bg.push(background) - } - } - - return bg - } - - public static async generateAndSaveBackground(app: Application) { - const bg = AssetsManager.generateRandomGridBackground({ - width: 2560, - height: 1440, - app, - }) - app.stage.addChild(...bg) - - return AssetsManager.saveCanvasAsWebp(app) - } - - public static async getGeneratedBackgroundTilingSprite(app: Application) { - const bg = AssetsManager.generateRandomGridBackground({ - width: 2560, - height: 1440, - app, - }) - app.stage.addChild(...bg) - - const blob = await app.renderer.extract.image({ - target: app.stage, - format: "webp", - quality: 1, - }) - - app.stage.removeChild(...bg) - - return new TilingSprite({ - texture: Texture.from(blob), - }) - } - - public static async saveCanvasAsWebp( - app: Application, - imageName = "untitled", - ) { - const blob = await app.renderer.extract.image({ - target: app.stage, - format: "webp", - quality: 1, - }) - - const link = document.createElement("a") - link.href = blob.src - link.download = `${imageName}.webp` - link.click() - link.remove() - app.renderer.destroy() - } -} diff --git a/apps/client/src/game/utils/audioManager.ts b/apps/client/src/game/utils/audioManager.ts deleted file mode 100644 index 8a010c4b..00000000 --- a/apps/client/src/game/utils/audioManager.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { Howl } from "howler" -import chop1Audio from "../assets/audio/chop-1.wav" -import fireBurn1Audio from "../assets/audio/fire-1.wav" -import forest1Audio from "../assets/audio/forest-1.mp3" -import handPunch1Audio from "../assets/audio/hand-punch-1.wav" -import marchWithHorns1Audio from "../assets/audio/marching-with-horns-1.wav" -import mine1Audio from "../assets/audio/mine-1.wav" -import wagon1Audio from "../assets/audio/wagon-1.wav" -import yeah1Audio from "../assets/audio/yeah-1.wav" - -type SoundName = - | "CHOP_HIT" - | "MINE_HIT" - | "HAND_HIT" - | "MARCHING_WITH_HORNS" - | "FOREST_BACKGROUND" - | "WAGON_MOVING" - | "FIRE_BURN" - | "YEAH" - -export class AudioManager { - private chop1 = new Howl({ - src: chop1Audio, - }) - private mine1 = new Howl({ - src: mine1Audio, - rate: 0.7, - volume: 0.4, - }) - private handPunch1 = new Howl({ - src: handPunch1Audio, - volume: 0.2, - rate: 0.8, - }) - private marchWithHorns1 = new Howl({ - src: marchWithHorns1Audio, - volume: 0.7, - }) - private forest1 = new Howl({ - src: forest1Audio, - loop: true, - volume: 0.5, - }) - private wagon1 = new Howl({ - src: wagon1Audio, - rate: 0.7, - volume: 0.08, - }) - private fireBurn1 = new Howl({ - src: fireBurn1Audio, - volume: 0.7, - }) - private yeah1 = new Howl({ - src: yeah1Audio, - volume: 0.8, - }) - - private findSound(name: SoundName): Howl[] { - switch (name) { - case "CHOP_HIT": - return [this.chop1] - case "MINE_HIT": - return [this.mine1] - case "HAND_HIT": - return [this.handPunch1] - case "MARCHING_WITH_HORNS": - return [this.marchWithHorns1] - case "WAGON_MOVING": - return [this.wagon1] - case "FIRE_BURN": - return [this.fireBurn1] - case "YEAH": - return [this.yeah1] - case "FOREST_BACKGROUND": - return [this.forest1] - default: - return [] - } - } - - private play(audios: Howl[]) { - if (!audios.length) { - return - } - - const randomAudio = audios[Math.floor(Math.random() * audios.length)] - if (randomAudio.playing()) { - return - } - - randomAudio.play() - } - - public playSound(name: SoundName) { - return this.play(this.findSound(name)) - } -} diff --git a/apps/client/src/game/utils/generators/background.ts b/apps/client/src/game/utils/generators/background.ts deleted file mode 100644 index e3ffc8b5..00000000 --- a/apps/client/src/game/utils/generators/background.ts +++ /dev/null @@ -1,282 +0,0 @@ -import { Application, Container, Graphics, Sprite, TilingSprite } from "pixi.js" -import { - type IGameChunkTheme, - getRandomInRange, -} from "../../../../../../packages/api-sdk/src" -import { - BACKGROUND_TILE_1, - BACKGROUND_TILE_2, - BACKGROUND_TILE_3, - BACKGROUND_TILE_4, - BACKGROUND_TILE_5, -} from "./backgroundImages" - -interface Palette { - 93: string - 97: string - 103: string - 111: string - 115: string - 123: string - 136: string - 147: string - 149: string - 151: string - 153: string - 156: string - 168: string - 173: string - 203: string - 206: string - 209: string - 211: string - 213: string - 218: string -} - -export class BackgroundGenerator { - app: Application - palette!: Palette - mainColor1!: string - mainColor2!: string - accentColor1!: string - accentColor2!: string - accentColor3!: string - - constructor(app: Application) { - this.app = app - - // Default - this.changePaletteByTheme("GREEN") - this.changePalette() - } - - generate(imageArray: number[]) { - const imageWidth = Math.sqrt(imageArray.length) - - const graphics = new Graphics() - - let index = 0 - for (let y = 0; y < imageWidth; y++) { - for (let x = 0; x < imageWidth; x++) { - const grayscaleKey = imageArray[index] - - if (!(grayscaleKey in this.palette)) { - // Not found! - console.log("Not found key in Palette:", grayscaleKey) - continue - } - - const color = this.palette[grayscaleKey as keyof Palette] - - graphics.rect(x, y, 1, 1).fill(color) - index++ - } - } - - return this.app.renderer.generateTexture({ - target: graphics, - resolution: 4, - }) - } - - public changePaletteByTheme(theme: IGameChunkTheme) { - if (theme === "GREEN") { - this.mainColor1 = "0x239063" - this.mainColor2 = "0x1ebc73" - this.accentColor1 = "0x91db69" - this.accentColor2 = "0xcddf6c" - this.accentColor3 = "0x8fd3ff" - } - if (theme === "TOXIC") { - this.mainColor1 = "0xa2a947" - this.mainColor2 = "0xd5e04b" - this.accentColor1 = "0xf9c22b" - this.accentColor2 = "0xed8099" - this.accentColor3 = "0xb2ba90" - } - if (theme === "VIOLET") { - this.mainColor1 = "0x6b3e75" - this.mainColor2 = "0x905ea9" - this.accentColor1 = "0xfdcbb0" - this.accentColor2 = "0xfbb954" - this.accentColor3 = "0x8fd3ff" - } - if (theme === "BLUE") { - this.mainColor1 = "0x4d65b4" - this.mainColor2 = "0x4d9be6" - this.accentColor1 = "0xa884f3" - this.accentColor2 = "0xc7dcd0" - this.accentColor3 = "0x8ff8e2" - } - if (theme === "TEAL") { - this.mainColor1 = "0x0b5e65" - this.mainColor2 = "0x0b8a8f" - this.accentColor1 = "0xfdcbb0" - this.accentColor2 = "0xfbb954" - this.accentColor3 = "0xf9c22b" - } - if (theme === "STONE") { - this.mainColor1 = "0x374e4a" - this.mainColor2 = "0x547e64" - this.accentColor1 = "0xfca790" - this.accentColor2 = "0xeaaded" - this.accentColor3 = "0x8fd3ff" - } - - this.changePalette() - } - - changePalette() { - this.palette = { - 93: this.mainColor1, - 97: this.mainColor1, - 103: this.mainColor1, - 111: this.mainColor2, - 115: this.mainColor2, - 123: "0xcd683d", // brown - 136: "0xcd683d", // brown - 147: this.accentColor1, - 149: "0x92a984", // light neutral - 151: "0xe6904e", // orange - 153: this.accentColor1, - 156: this.accentColor1, - 168: "0xf68181", // bright pink - 173: "0xfbb954", // light orange - 203: "0x8fd3ff", // light blue - 206: this.accentColor2, - 209: "0xc7dcd0", // almost white - 211: this.accentColor3, - 213: this.accentColor3, - 218: "0xfbff86", // light yellow - } - } - - async getPixelsData() { - const canvas = document.createElement("CANVAS") as HTMLCanvasElement - const ctx = canvas.getContext("2d") - if (!ctx) { - return - } - - const app = new Application() - await app.init() - - const img = Sprite.from("backgroundMini") - app.stage.addChild(img) - - const blob = await app.renderer.extract.image({ - target: app.stage, - format: "webp", - quality: 1, - }) - - ctx.canvas.width = blob.width - ctx.canvas.height = blob.height - ctx.drawImage(blob, 0, 0) - - const imageData = ctx.getImageData( - 0, - 0, - ctx.canvas.width, - ctx.canvas.height, - ) - - const pixels: number[] = [] - - for (let y = 0; y < blob.width; y++) { - for (let x = 0; x < blob.width; x++) { - const [redIndex, greenIndex, blueIndex, _] = - this.getColorIndicesForCoord(x, y, ctx.canvas.width) - - const average = Math.round( - (imageData?.data[redIndex] + - imageData?.data[greenIndex] + - imageData?.data[blueIndex]) / - 3, - ) - - pixels.push(average) - } - } - - // Result: array - console.log(pixels) - - return imageData - } - - getColorIndicesForCoord(x: number, y: number, width: number) { - const red = y * (width * 4) + x * 4 - return [red, red + 1, red + 2, red + 3] - } - - public getGeneratedBackgroundTilingSprite() { - const bg = this.generateRandomGridBackground({ - width: 2000, - height: 1000, - }) - const container = new Container() - container.addChild(...bg) - - const texture = this.app.renderer.generateTexture(container) - container.destroy() - - return new TilingSprite({ - texture, - }) - } - - generateRandomGridBackground({ - width, - height, - }: { - width: number - height: number - }) { - const gridX = Math.ceil(width / 64) - const gridY = Math.floor(height / 64) - - const bg: Sprite[] = [] - - for (let i = 0; i < gridX; i++) { - for (let j = 0; j < gridY; j++) { - const background = this.getRandomSpriteForBackground() - - background.x = i * 64 - background.y = j * 64 - - bg.push(background) - } - } - - return bg - } - - getRandomSpriteForBackground() { - const tileArray = this.getTileByRandomChance() - const sprite = Sprite.from(this.generate(tileArray)) - sprite.scale = 4 - - return sprite - } - - getTileByRandomChance(): number[] { - const randomMax = 100 - const random = getRandomInRange(1, randomMax) - - if (random <= 55) { - return BACKGROUND_TILE_1 - } - if (random <= 93) { - return BACKGROUND_TILE_2 - } - if (random <= 96) { - return BACKGROUND_TILE_3 - } - if (random <= 98) { - return BACKGROUND_TILE_4 - } - return BACKGROUND_TILE_5 - } -} diff --git a/apps/client/src/game/utils/generators/backgroundImages.ts b/apps/client/src/game/utils/generators/backgroundImages.ts deleted file mode 100644 index 0b01ff37..00000000 --- a/apps/client/src/game/utils/generators/backgroundImages.ts +++ /dev/null @@ -1,88 +0,0 @@ -export const BACKGROUND_TILE_1 = [ - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, -] - -export const BACKGROUND_TILE_2 = [ - 93, 93, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 111, 93, - 93, 111, 93, 93, 93, 93, 111, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, - 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, - 111, 93, 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 93, 93, 111, 93, 111, 93, 93, 93, 93, 111, 93, - 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 93, 111, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 111, 93, 93, 111, 93, 93, 111, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 111, 93, 93, 93, 93, 93, 111, 93, 93, 111, 93, - 93, 93, 111, 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 111, 93, 93, - 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 111, 93, - 93, 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 111, - 93, 93, 93, 93, 111, 93, 111, 93, 93, 93, 93, 93, 93, 111, 93, 111, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 93, 111, 93, 93, 111, 93, 93, 93, 93, 111, 93, - 93, 93, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 93, 93, -] - -export const BACKGROUND_TILE_3 = [ - 97, 97, 97, 149, 149, 97, 97, 97, 149, 149, 97, 97, 97, 115, 97, 97, 97, 206, - 97, 149, 115, 115, 97, 115, 115, 97, 97, 97, 103, 115, 103, 97, 97, 206, 206, - 97, 115, 115, 97, 115, 97, 97, 153, 153, 97, 97, 103, 97, 103, 115, 115, 97, - 103, 115, 97, 97, 103, 97, 153, 115, 115, 97, 149, 149, 97, 103, 115, 97, 103, - 115, 103, 97, 97, 97, 103, 115, 115, 103, 115, 115, 97, 97, 97, 97, 97, 97, - 97, 97, 206, 206, 103, 97, 97, 103, 97, 115, 97, 206, 206, 206, 97, 97, 97, - 115, 115, 206, 97, 97, 97, 97, 103, 97, 97, 97, 206, 115, 115, 97, 103, 115, - 115, 103, 97, 149, 103, 206, 206, 97, 97, 97, 103, 115, 115, 97, 103, 115, - 103, 97, 149, 115, 103, 115, 115, 97, 153, 153, 97, 103, 115, 97, 103, 97, - 103, 97, 115, 103, 97, 103, 115, 97, 153, 115, 115, 97, 97, 103, 153, 153, 97, - 97, 97, 97, 97, 103, 97, 97, 103, 115, 115, 103, 97, 103, 153, 115, 115, 97, - 97, 206, 206, 206, 97, 97, 97, 103, 97, 103, 97, 97, 103, 115, 115, 97, 115, - 115, 206, 97, 97, 97, 149, 97, 97, 97, 206, 206, 97, 97, 97, 103, 115, 115, - 103, 97, 206, 97, 115, 149, 97, 97, 103, 115, 115, 103, 97, 103, 115, 103, 97, - 115, 206, 97, 97, 115, 103, 97, 97, 103, 115, 103, 97, 103, 97, 97, 97, 115, - 115, 103, -] - -export const BACKGROUND_TILE_4 = [ - 93, 93, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 111, 93, - 93, 111, 93, 93, 93, 93, 111, 93, 93, 111, 173, 93, 93, 93, 111, 93, 93, 93, - 93, 93, 111, 93, 93, 93, 93, 173, 168, 173, 111, 93, 93, 93, 93, 93, 93, 93, - 111, 93, 93, 93, 93, 103, 173, 93, 111, 93, 93, 93, 211, 111, 93, 93, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 93, 93, 211, 168, 111, 93, 93, 93, 93, 111, 93, - 93, 93, 111, 93, 93, 93, 93, 103, 93, 103, 93, 93, 93, 209, 209, 93, 111, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 93, 209, 173, 173, 173, 93, 111, 93, 93, 111, - 93, 93, 111, 93, 93, 93, 103, 209, 173, 136, 173, 209, 93, 93, 93, 111, 93, - 93, 111, 93, 93, 93, 103, 103, 173, 173, 173, 209, 93, 111, 93, 93, 93, 93, - 93, 93, 111, 93, 93, 103, 209, 209, 103, 93, 93, 111, 93, 93, 93, 93, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 93, 93, 218, 93, 93, 93, 111, 93, 173, 93, 93, - 93, 93, 111, 93, 93, 93, 111, 147, 218, 93, 93, 111, 173, 136, 173, 93, 93, - 93, 93, 93, 111, 93, 103, 93, 93, 111, 93, 103, 103, 173, 93, 93, 93, 111, 93, - 93, 111, 93, 93, 93, 93, 111, 93, 103, 93, 93, 93, 93, 93, 111, 93, 93, 93, - 93, 93, 93, 93, 93, 93, -] - -export const BACKGROUND_TILE_5 = [ - 93, 93, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 111, 93, - 93, 111, 93, 211, 211, 93, 111, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 211, - 173, 173, 173, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 103, 211, 173, - 123, 173, 211, 93, 93, 93, 93, 213, 93, 93, 93, 93, 93, 103, 103, 173, 173, - 173, 211, 111, 93, 93, 93, 151, 213, 93, 93, 93, 111, 93, 103, 211, 211, 156, - 93, 111, 93, 93, 103, 156, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, - 93, 111, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 111, 93, 93, 111, 93, - 93, 111, 93, 93, 111, 203, 93, 93, 111, 93, 93, 111, 93, 93, 93, 93, 93, 111, - 93, 93, 203, 136, 203, 93, 111, 93, 93, 93, 93, 93, 93, 209, 93, 93, 93, 93, - 103, 156, 111, 93, 93, 93, 93, 93, 93, 93, 211, 209, 151, 93, 93, 93, 93, 93, - 111, 93, 93, 93, 111, 93, 93, 103, 209, 151, 209, 209, 93, 111, 93, 93, 93, - 93, 218, 93, 111, 93, 103, 103, 211, 209, 211, 93, 93, 111, 93, 111, 93, 218, - 168, 93, 93, 93, 111, 103, 103, 156, 103, 111, 93, 93, 93, 111, 93, 103, 156, - 111, 93, 93, 111, 93, 93, 93, 93, 111, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, -] diff --git a/apps/client/src/game/utils/index.ts b/apps/client/src/game/utils/index.ts deleted file mode 100644 index e7325dc6..00000000 --- a/apps/client/src/game/utils/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { AssetsManager } from "./assetsManager" -export { AudioManager } from "./audioManager" -export { WebSocketManager } from "./webSocketManager" diff --git a/apps/client/src/game/utils/webSocketManager.ts b/apps/client/src/game/utils/webSocketManager.ts deleted file mode 100644 index 901c091a..00000000 --- a/apps/client/src/game/utils/webSocketManager.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { MessageController } from "../../../../../packages/api-sdk/src" -import type { Game } from "../game" - -export abstract class WebSocketManager { - public static socket: WebSocket - public static messagesPerSecond = 0 - public static kbitPerSecond = 0 - - public static init(game: Game) { - WebSocketManager.socket = new WebSocket("ws://localhost:4002") - - WebSocketManager.setMessagesPerSecondHandler() - - WebSocketManager.socket.addEventListener("message", (event) => { - const message = MessageController.parse(event.data.toString()) - if (!message) { - return - } - - WebSocketManager.messagesPerSecond += 1 - const bytes = JSON.stringify(message).length - WebSocketManager.kbitPerSecond += Math.round((bytes * 8) / 1024) - - game.handleMessage(message) - }) - } - - public static setMessagesPerSecondHandler() { - return setInterval(() => { - // console.log( - // `${WebSocketManager.messagesPerSecond} msg/s, ${WebSocketManager.kbitPerSecond} kbit/s`, - // ) - WebSocketManager.messagesPerSecond = 0 - WebSocketManager.kbitPerSecond = 0 - }, 1000) - } -} diff --git a/bun.lockb b/bun.lockb index b130ac7a..399c9f15 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index da5061b0..3c82480c 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "hono": "4.4.5", "howler": "2.2.4", "jsonwebtoken": "9.0.2", + "lucide-svelte": "0.394.0", "pixi.js": "8.1.6", "react": "18.3.1", "react-dom": "18.3.1" diff --git a/src/lib/components/Profile.svelte b/src/lib/components/Profile.svelte index c876f283..30edd6f3 100644 --- a/src/lib/components/Profile.svelte +++ b/src/lib/components/Profile.svelte @@ -36,14 +36,13 @@ const handleMenuClick = () => { {/if} {:else} - + Войти {/if}
@@ -55,26 +54,19 @@ const handleMenuClick = () => { } .twitch { + color: white; + text-decoration: none; padding: 0.5em 1.2em; - color: white; background-color: var(--color-twitch); transition: all 0.2s; } .twitch:hover { + text-decoration: none; transform: scale(1.04); opacity: 0.8; } - .twitch a { - color: white; - text-decoration: none; - } - - .twitch a:hover { - text-decoration: none; - } - .profile-avatar { padding: 4px; width: 58px; diff --git a/src/routes/+layout.server.ts b/src/routes/(game)/play/+layout.server.ts similarity index 100% rename from src/routes/+layout.server.ts rename to src/routes/(game)/play/+layout.server.ts diff --git a/src/routes/(game)/play/+layout.svelte b/src/routes/(game)/play/+layout.svelte new file mode 100644 index 00000000..d0d7e89e --- /dev/null +++ b/src/routes/(game)/play/+layout.svelte @@ -0,0 +1,25 @@ + + +
+ {#if isAvailable} + + {:else} +
Игра пока находится на стадии разработки. Вернуться на Главную
+ {/if} +
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/+page.svelte b/src/routes/(game)/play/+page.svelte new file mode 100644 index 00000000..8a9e9242 --- /dev/null +++ b/src/routes/(game)/play/+page.svelte @@ -0,0 +1,59 @@ + + +
+
+ + + + +
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameChunkInfo.svelte b/src/routes/(game)/play/GameChunkInfo.svelte new file mode 100644 index 00000000..37c5bd4c --- /dev/null +++ b/src/routes/(game)/play/GameChunkInfo.svelte @@ -0,0 +1,36 @@ + + +
+ {#if type === "VILLAGE"} + + {:else if type === "FOREST"} + + {:else if type === "LAKE"} + + {/if} + +

{title}

+
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameHeader.svelte b/src/routes/(game)/play/GameHeader.svelte new file mode 100644 index 00000000..a20cc133 --- /dev/null +++ b/src/routes/(game)/play/GameHeader.svelte @@ -0,0 +1,33 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameInterface.svelte b/src/routes/(game)/play/GameInterface.svelte new file mode 100644 index 00000000..0fbfc2ea --- /dev/null +++ b/src/routes/(game)/play/GameInterface.svelte @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/src/routes/(game)/play/GameItem.svelte b/src/routes/(game)/play/GameItem.svelte new file mode 100644 index 00000000..dca854b1 --- /dev/null +++ b/src/routes/(game)/play/GameItem.svelte @@ -0,0 +1,35 @@ + + +
+ {#if type === "WOOD"} + + {:else if type === "STONE"} + + {:else if type === "COIN"} + + {/if} + +

{amount}

+
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameLoader.svelte b/src/routes/(game)/play/GameLoader.svelte new file mode 100644 index 00000000..dee23448 --- /dev/null +++ b/src/routes/(game)/play/GameLoader.svelte @@ -0,0 +1,57 @@ + + +
+
+ +
+
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameLocation.svelte b/src/routes/(game)/play/GameLocation.svelte new file mode 100644 index 00000000..7867fbc5 --- /dev/null +++ b/src/routes/(game)/play/GameLocation.svelte @@ -0,0 +1,18 @@ + + +
+ + +
+ + \ No newline at end of file diff --git a/src/routes/(game)/play/GameWarehouseInfo.svelte b/src/routes/(game)/play/GameWarehouseInfo.svelte new file mode 100644 index 00000000..7f0f92e6 --- /dev/null +++ b/src/routes/(game)/play/GameWarehouseInfo.svelte @@ -0,0 +1,42 @@ + + +
+
+ +

Warehouse

+
+ +
+ {#each items as item} + + {/each} +
+
+ + \ No newline at end of file diff --git a/src/routes/+error.svelte b/src/routes/(website)/+error.svelte similarity index 100% rename from src/routes/+error.svelte rename to src/routes/(website)/+error.svelte diff --git a/src/routes/(website)/+layout.server.ts b/src/routes/(website)/+layout.server.ts new file mode 100644 index 00000000..95ad281a --- /dev/null +++ b/src/routes/(website)/+layout.server.ts @@ -0,0 +1,7 @@ +import type { LayoutServerLoad } from "./$types" + +export const load = (async ({ locals }) => { + return { + profile: locals.profile, + } +}) satisfies LayoutServerLoad diff --git a/src/routes/+layout.svelte b/src/routes/(website)/+layout.svelte similarity index 94% rename from src/routes/+layout.svelte rename to src/routes/(website)/+layout.svelte index 0d5db439..a48c4aa9 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/(website)/+layout.svelte @@ -1,7 +1,7 @@
diff --git a/src/routes/+page.server.ts b/src/routes/(website)/+page.server.ts similarity index 100% rename from src/routes/+page.server.ts rename to src/routes/(website)/+page.server.ts diff --git a/src/routes/+page.svelte b/src/routes/(website)/+page.svelte similarity index 100% rename from src/routes/+page.svelte rename to src/routes/(website)/+page.svelte diff --git a/src/routes/(website)/about/+page.svelte b/src/routes/(website)/about/+page.svelte new file mode 100644 index 00000000..4d68056b --- /dev/null +++ b/src/routes/(website)/about/+page.svelte @@ -0,0 +1,145 @@ + + + + Об игре | Чат-игра для Twitch + + + +
+

+ Об игре +

+

Фундамент уже готов.
Идет большой процесс проработки деталей и создания основного геймплея.

+

Ориентир - конец лета 2024.

+
+ +
+
+
+

Необычный input

+
+
+

Для создания юнита и выполнения разнообразных действий в игре требуется писать команды в Twitch чате. + Например, написав команду "!рубить", юнит начнет рубить ближайшее дерево.

+
+
+
+
+

Генерируемые локации

+
+
+

Путешествуя в открытом мире, игроки встречают уникальные места. Все благодаря динамичной генерации + чанков и глубокой работе с текстурами. Нет заранее созданной игровой карты.

+
+
+
+
+

Квесты

+
+
+

Основные модификаторы игры. Активные квесты меняют доступные команды для игроков. Движение Машины также + зависит от главного активного задания.

+
+
+
+ +
+
+ +
+
+ +
+

Благодарности

+

Спасибо моим зрителям: sava5621 за вкусные шавухи, BezSovesty за помощь на + старте, flack_zombi за упорство в рубке деревьев, PeregonStream за крутые рейды. + Спасибо tozikab_, 6alt1ca, derailon, sloghniy, MaN0ol, dO_Oy, VombatDrago, + sleeplessness8. +
Вы все крутые!

+
+ + \ No newline at end of file diff --git a/src/routes/auth/profile/+server.ts b/src/routes/(website)/auth/profile/+server.ts similarity index 100% rename from src/routes/auth/profile/+server.ts rename to src/routes/(website)/auth/profile/+server.ts diff --git a/src/routes/auth/sign-in/+page.svelte b/src/routes/(website)/auth/sign-in/+page.svelte similarity index 100% rename from src/routes/auth/sign-in/+page.svelte rename to src/routes/(website)/auth/sign-in/+page.svelte diff --git a/src/routes/auth/sign-in/+server.ts b/src/routes/(website)/auth/sign-in/+server.ts similarity index 100% rename from src/routes/auth/sign-in/+server.ts rename to src/routes/(website)/auth/sign-in/+server.ts diff --git a/src/routes/character/+page.server.ts b/src/routes/(website)/character/+page.server.ts similarity index 100% rename from src/routes/character/+page.server.ts rename to src/routes/(website)/character/+page.server.ts diff --git a/src/routes/character/+page.svelte b/src/routes/(website)/character/+page.svelte similarity index 100% rename from src/routes/character/+page.svelte rename to src/routes/(website)/character/+page.svelte diff --git a/src/routes/character/[slug]/+page.server.ts b/src/routes/(website)/character/[slug]/+page.server.ts similarity index 100% rename from src/routes/character/[slug]/+page.server.ts rename to src/routes/(website)/character/[slug]/+page.server.ts diff --git a/src/routes/character/[slug]/+page.svelte b/src/routes/(website)/character/[slug]/+page.svelte similarity index 63% rename from src/routes/character/[slug]/+page.svelte rename to src/routes/(website)/character/[slug]/+page.svelte index 5bed906a..d4c256d7 100644 --- a/src/routes/character/[slug]/+page.svelte +++ b/src/routes/(website)/character/[slug]/+page.svelte @@ -6,73 +6,73 @@ export let data: PageServerData
-

{data.character.name}

-

Игровой персонаж, созданный valentina8177

+

{data.character.name}

+

Игровой персонаж, созданный valentina8177

-
- -
+
+ +
-
-
-

Малый

-

Уровень проработанности

-
- -
-
-
-
-
-
-
-
-
-
    -
  • Рубашка: Common Blue
  • -
  • Прическа: Classic Brown
  • -
  • Аксессуар: Нет
  • -
  • Звук: Нет
  • -
  • Статус Героя: Нет
  • -
  • Уникальный URL: Нет
  • -
+
+
+

Малый

+

Уровень проработанности

-
- {data.character.description} + +
+
+
+
+
+
+
+
+
    +
  • Рубашка: Common Blue
  • +
  • Прическа: Classic Brown
  • +
  • Аксессуар: Нет
  • +
  • Звук: Нет
  • +
  • Статус Героя: Нет
  • +
  • Уникальный URL: Нет
  • +
+
+
+ {data.character.description} +
-
- Сейчас управляет: Никто +
+ Сейчас управляет: Никто +
+
+
+

Пример поста 3

+
+
8 часов назад
+
+
-
-
-

Пример поста 3

-
-
8 часов назад
-
-
-
- -
-

Пример поста 2

-
-
2 дня назад
-
-
-
- -
-

Пример поста 1

-
-
6 дней назад
-
-
-
+ +
+

Пример поста 2

+
+
2 дня назад
+
+
+
+ +
+

Пример поста 1

+
+
6 дней назад
+
+
+
\ No newline at end of file diff --git a/src/routes/legacy.css b/src/routes/legacy.css new file mode 100644 index 00000000..92c30c87 --- /dev/null +++ b/src/routes/legacy.css @@ -0,0 +1,929 @@ +:root { + /* Resurrect 64 Palette */ + --color-coal-1: #2e222f; + --color-coal-2: #3e3546; + --color-coal-3: #625565; + --color-coal-4: #966c6c; + --color-coal-5: #ab947a; + + --color-silver-1: #694f62; + --color-silver-2: #7f708a; + --color-silver-3: #9babb2; + --color-silver-4: #c7dcd0; + --color-silver-5: #ffffff; + + --color-red-1: #6e2727; + --color-red-2: #b33831; + --color-red-3: #ea4f36; + --color-red-4: #f57d4a; + + --color-orange-1: #ae2334; + --color-orange-2: #e83b3b; + --color-orange-3: #fb6b1d; + --color-orange-4: #f79617; + --color-orange-5: #f9c22b; + + --color-brown-1: #7a3045; + --color-brown-2: #9e4539; + --color-brown-3: #cd683d; + --color-brown-4: #e6904e; + --color-brown-5: #fbb954; + + --color-toxic-1: #4c3e24; + --color-toxic-2: #676633; + --color-toxic-3: #a2a947; + --color-toxic-4: #d5e04b; + --color-toxic-5: #fbff86; + + --color-green-1: #165a4c; + --color-green-2: #239063; + --color-green-3: #1ebc73; + --color-green-4: #91db69; + --color-green-5: #cddf6c; + + --color-stone-1: #313638; + --color-stone-2: #374e4a; + --color-stone-3: #547e64; + --color-stone-4: #92a984; + --color-stone-5: #b2ba90; + + --color-teal-1: #0b5e65; + --color-teal-2: #0b8a8f; + --color-teal-3: #0eaf9b; + --color-teal-4: #30e1b9; + --color-teal-5: #8ff8e2; + + --color-blue-1: #323353; + --color-blue-2: #484a77; + --color-blue-3: #4d65b4; + --color-blue-4: #4d9be6; + --color-blue-5: #8fd3ff; + + --color-violet-1: #45293f; + --color-violet-2: #6b3e75; + --color-violet-3: #905ea9; + --color-violet-4: #a884f3; + --color-violet-5: #eaaded; + + --color-plume-1: #753c54; + --color-plume-2: #a24b6f; + --color-plume-3: #cf657f; + --color-plume-4: #ed8099; + + --color-rose-1: #831c5d; + --color-rose-2: #c32454; + --color-rose-3: #f04f78; + --color-rose-4: #f68181; + --color-rose-5: #fca790; + --color-rose-6: #fdcbb0; + + --color-sand-1: #f6d7b0; + --color-sand-2: #f2d2a9; + --color-sand-3: #eccca2; + --color-sand-4: #e7c496; + --color-sand-5: #e1bf92; +} + +body, html { + font-family: "Noto Serif", serif; + font-optical-sizing: auto; + font-weight: 500; + font-style: normal; + font-variation-settings: "wdth" 100; +} + +.bg-primary { + background-color: #FFE7B3; +} + +.bg-accent-violet { + background-color: #473876; +} + +.bg-progress-bar { + background-color: #DBB594; +} + +.bg-twitch-command { + background-image: linear-gradient(to right, #56468B 0%, #664282 100%); + border: 2px solid #7D66D9; +} + +.text-primary { + color: #38352E +} + +.text-accent-sand { + color: #FFE7B3 +} + +.text-secondary-sand { + color: #DBB594 +} + +.border-primary { + border-color: #978365 +} + +.border-secondary { + border-color: #CBB99F +} + +.bg-coal-1 { + background-color: var(--color-coal-1); +} + +.bg-coal-2 { + background-color: var(--color-coal-2); +} + +.bg-coal-3 { + background-color: var(--color-coal-3); +} + +.bg-coal-4 { + background-color: var(--color-coal-4); +} + +.bg-coal-5 { + background-color: var(--color-coal-5); +} + +.border-coal-1 { + border-color: var(--color-coal-1); +} + +.border-coal-2 { + border-color: var(--color-coal-2); +} + +.border-coal-3 { + border-color: var(--color-coal-3); +} + +.border-coal-4 { + border-color: var(--color-coal-4); +} + +.border-coal-5 { + border-color: var(--color-coal-5); +} + +.bg-silver-1 { + background-color: var(--color-silver-1); +} + +.bg-silver-2 { + background-color: var(--color-silver-2); +} + +.bg-silver-3 { + background-color: var(--color-silver-3); +} + +.bg-silver-4 { + background-color: var(--color-silver-4); +} + +.bg-silver-5 { + background-color: var(--color-silver-5); +} + +.border-silver-1 { + border-color: var(--color-silver-1); +} + +.border-silver-2 { + border-color: var(--color-silver-2); +} + +.border-silver-3 { + border-color: var(--color-silver-3); +} + +.border-silver-4 { + border-color: var(--color-silver-4); +} + +.border-silver-5 { + border-color: var(--color-silver-5); +} + +.text-silver-1 { + color: var(--color-silver-1); +} + +.text-silver-2 { + color: var(--color-silver-2); +} + +.text-silver-3 { + color: var(--color-silver-3); +} + +.text-silver-4 { + color: var(--color-silver-4); +} + +.text-silver-5 { + color: var(--color-silver-5); +} + +.bg-red-1 { + background-color: var(--color-red-1); +} + +.bg-red-2 { + background-color: var(--color-red-2); +} + +.bg-red-3 { + background-color: var(--color-red-3); +} + +.bg-red-4 { + background-color: var(--color-red-4); +} + +.border-red-1 { + border-color: var(--color-red-1); +} + +.border-red-2 { + border-color: var(--color-red-2); +} + +.border-red-3 { + border-color: var(--color-red-3); +} + +.border-red-4 { + border-color: var(--color-red-4); +} + +.text-red-1 { + color: var(--color-red-1); +} + +.text-red-2 { + color: var(--color-red-2); +} + +.text-red-3 { + color: var(--color-red-3); +} + +.text-red-4 { + color: var(--color-red-4); +} + +.bg-violet-1 { + background-color: var(--color-violet-1); +} + +.bg-violet-2 { + background-color: var(--color-violet-2); +} + +.bg-violet-3 { + background-color: var(--color-violet-3); +} + +.bg-violet-4 { + background-color: var(--color-violet-4); +} + +.bg-violet-5 { + background-color: var(--color-violet-5); +} + +.border-violet-1 { + border-color: var(--color-violet-1); +} + +.border-violet-2 { + border-color: var(--color-violet-2); +} + +.border-violet-3 { + border-color: var(--color-violet-3); +} + +.border-violet-4 { + border-color: var(--color-violet-4); +} + +.border-violet-5 { + border-color: var(--color-violet-5); +} + +.text-violet-1 { + color: var(--color-violet-1); +} + +.text-violet-2 { + color: var(--color-violet-2); +} + +.text-violet-3 { + color: var(--color-violet-3); +} + +.text-violet-4 { + color: var(--color-violet-4); +} + +.text-violet-5 { + color: var(--color-violet-5); +} + +.bg-orange-1 { + background-color: var(--color-orange-1); +} + +.bg-orange-2 { + background-color: var(--color-orange-2); +} + +.bg-orange-3 { + background-color: var(--color-orange-3); +} + +.bg-orange-4 { + background-color: var(--color-orange-4); +} + +.bg-orange-5 { + background-color: var(--color-orange-5); +} + +.border-orange-1 { + border-color: var(--color-orange-1); +} + +.border-orange-2 { + border-color: var(--color-orange-2); +} + +.border-orange-3 { + border-color: var(--color-orange-3); +} + +.border-orange-4 { + border-color: var(--color-orange-4); +} + +.border-orange-5 { + border-color: var(--color-orange-5); +} + +.text-orange-1 { + color: var(--color-orange-1); +} + +.text-orange-2 { + color: var(--color-orange-2); +} + +.text-orange-3 { + color: var(--color-orange-3); +} + +.text-orange-4 { + color: var(--color-orange-4); +} + +.text-orange-5 { + color: var(--color-orange-5); +} + +.bg-brown-1 { + background-color: var(--color-brown-1); +} + +.bg-brown-2 { + background-color: var(--color-brown-2); +} + +.bg-brown-3 { + background-color: var(--color-brown-3); +} + +.bg-brown-4 { + background-color: var(--color-brown-4); +} + +.bg-brown-5 { + background-color: var(--color-brown-5); +} + +.border-brown-1 { + border-color: var(--color-brown-1); +} + +.border-brown-2 { + border-color: var(--color-brown-2); +} + +.border-brown-3 { + border-color: var(--color-brown-3); +} + +.border-brown-4 { + border-color: var(--color-brown-4); +} + +.border-brown-5 { + border-color: var(--color-brown-5); +} + +.text-brown-1 { + color: var(--color-brown-1); +} + +.text-brown-2 { + color: var(--color-brown-2); +} + +.text-brown-3 { + color: var(--color-brown-3); +} + +.text-brown-4 { + color: var(--color-brown-4); +} + +.text-brown-5 { + color: var(--color-brown-5); +} + +.bg-blue-1 { + background-color: var(--color-blue-1); +} + +.bg-blue-2 { + background-color: var(--color-blue-2); +} + +.bg-blue-3 { + background-color: var(--color-blue-3); +} + +.bg-blue-4 { + background-color: var(--color-blue-4); +} + +.bg-blue-5 { + background-color: var(--color-blue-5); +} + +.border-blue-1 { + border-color: var(--color-blue-1); +} + +.border-blue-2 { + border-color: var(--color-blue-2); +} + +.border-blue-3 { + border-color: var(--color-blue-3); +} + +.border-blue-4 { + border-color: var(--color-blue-4); +} + +.border-blue-5 { + border-color: var(--color-blue-5); +} + +.text-blue-1 { + color: var(--color-blue-1); +} + +.text-blue-2 { + color: var(--color-blue-2); +} + +.text-blue-3 { + color: var(--color-blue-3); +} + +.text-blue-4 { + color: var(--color-blue-4); +} + +.text-blue-5 { + color: var(--color-blue-5); +} + +.bg-teal-1 { + background-color: var(--color-teal-1); +} + +.bg-teal-2 { + background-color: var(--color-teal-2); +} + +.bg-teal-3 { + background-color: var(--color-teal-3); +} + +.bg-teal-4 { + background-color: var(--color-teal-4); +} + +.bg-teal-5 { + background-color: var(--color-teal-5); +} + +.border-teal-1 { + border-color: var(--color-teal-1); +} + +.border-teal-2 { + border-color: var(--color-teal-2); +} + +.border-teal-3 { + border-color: var(--color-teal-3); +} + +.border-teal-4 { + border-color: var(--color-teal-4); +} + +.border-teal-5 { + border-color: var(--color-teal-5); +} + +.text-teal-1 { + color: var(--color-teal-1); +} + +.text-teal-2 { + color: var(--color-teal-2); +} + +.text-teal-3 { + color: var(--color-teal-3); +} + +.text-teal-4 { + color: var(--color-teal-4); +} + +.text-teal-5 { + color: var(--color-teal-5); +} + +.bg-green-1 { + background-color: var(--color-green-1); +} + +.bg-green-2 { + background-color: var(--color-green-2); +} + +.bg-green-3 { + background-color: var(--color-green-3); +} + +.bg-green-4 { + background-color: var(--color-green-4); +} + +.bg-green-5 { + background-color: var(--color-green-5); +} + +.border-green-1 { + border-color: var(--color-green-1); +} + +.border-green-2 { + border-color: var(--color-green-2); +} + +.border-green-3 { + border-color: var(--color-green-3); +} + +.border-green-4 { + border-color: var(--color-green-4); +} + +.border-green-5 { + border-color: var(--color-green-5); +} + +.text-green-1 { + color: var(--color-green-1); +} + +.text-green-2 { + color: var(--color-green-2); +} + +.text-green-3 { + color: var(--color-green-3); +} + +.text-green-4 { + color: var(--color-green-4); +} + +.text-green-5 { + color: var(--color-green-5); +} + +.bg-stone-1 { + background-color: var(--color-stone-1); +} + +.bg-stone-2 { + background-color: var(--color-stone-2); +} + +.bg-stone-3 { + background-color: var(--color-stone-3); +} + +.bg-stone-4 { + background-color: var(--color-stone-4); +} + +.bg-stone-5 { + background-color: var(--color-stone-5); +} + +.border-stone-1 { + border-color: var(--color-stone-1); +} + +.border-stone-2 { + border-color: var(--color-stone-2); +} + +.border-stone-3 { + border-color: var(--color-stone-3); +} + +.border-stone-4 { + border-color: var(--color-stone-4); +} + +.border-stone-5 { + border-color: var(--color-stone-5); +} + +.text-stone-1 { + color: var(--color-stone-1); +} + +.text-stone-2 { + color: var(--color-stone-2); +} + +.text-stone-3 { + color: var(--color-stone-3); +} + +.text-stone-4 { + color: var(--color-stone-4); +} + +.text-stone-5 { + color: var(--color-stone-5); +} + +@keyframes animation-tree-shake { + 0% { + transform: skewX(0deg); + } + /* Chop */ + 10% { + transform: skewX(-5deg); + } + 12% { + transform: skewX(5deg); + } + 15% { + transform: skewX(0deg); + } + /* Chop */ + 30% { + transform: skewX(-5deg); + } + 32% { + transform: skewX(5deg); + } + 35% { + transform: skewX(0deg); + } + + 50% { + transform: skewX(0deg); + } + 60% { + transform: skewX(0deg); + } + + /* Chop */ + 65% { + transform: skewX(-5deg); + } + 67% { + transform: skewX(5deg); + } + 70% { + transform: skewX(0deg); + } + 100% { + transform: skewX(0deg); + } +} + +.animation-tree-shake { + animation: animation-tree-shake 2.6s infinite; +} + +@keyframes animation-tree-wind-shake { + 0% { + transform: skewX(0deg); + } + 10% { + transform: skewX(-5deg); + } + 15% { + transform: skewX(0); + } + 50% { + transform: skewX(0); + } + 57% { + transform: skewX(2deg); + } + 65% { + transform: skewX(-4deg); + } + 73% { + transform: skewX(0); + } + 100% { + transform: skewX(0deg); + } +} + +.animation-tree-wind-shake { + animation: animation-tree-wind-shake 10s infinite; +} + +@keyframes animation-tree-chopping { + 0% { + transform: translate(0, 0) rotate(0deg); + } + /* Chop */ + 10% { + transform: translate(0, 0) rotate(0deg); + } + 12% { + transform: translate(-5px, 8px) rotate(-45deg); + } + 15% { + transform: translate(0, 0) rotate(0deg); + } + /* Chop */ + 30% { + transform: translate(0, 0) rotate(0deg); + } + 32% { + transform: translate(-5px, 8px) rotate(-45deg); + } + 35% { + transform: translate(0, 0) rotate(0deg); + } + + 50% { + transform: translate(0, 0) rotate(0deg); + } + 60% { + transform: translate(0, 0) rotate(0deg); + } + + /* Chop */ + 65% { + transform: translate(0, 0) rotate(0deg); + } + 67% { + transform: translate(-5px, 8px) rotate(-45deg); + } + 70% { + transform: translate(0, 0) rotate(0deg); + } + + 100% { + transform: translate(0, 0) rotate(0deg); + } +} + +.animation-tree-chopping { + animation: animation-tree-chopping 2.6s infinite; +} + +@keyframes animation-stone-little-shake { + 0% { + transform: skewY(0deg); + } + 10% { + transform: skewY(-1deg); + } + 15% { + transform: skewY(0); + } + 50% { + transform: skewY(0); + } + 57% { + transform: skewY(1deg); + } + 65% { + transform: skewY(-1deg); + } + 73% { + transform: skewY(0); + } + 100% { + transform: skewY(0deg); + } +} + +.animation-stone-little-shake { + animation: animation-stone-little-shake 10s infinite; +} + +@keyframes animation-rabbit-hop { + 0% { + transform: translate(0, 0) rotate(0deg); + } + 70% { + transform: translate(0, 1px) rotate(0deg); + } + 80% { + transform: translate(0, -6px) rotate(-8deg) scale(0.7); + } + 90% { + transform: translate(0, 2px) rotate(2deg); + } + 100% { + transform: translate(0, 0) rotate(0deg); + } +} + +.animation-rabbit-hop { + animation: animation-rabbit-hop 0.7s infinite; +} + +@keyframes animation-wolf-move { + 0% { + transform: translate(0, 0) rotate(0deg); + } + 70% { + transform: translate(0, 1px) rotate(0deg); + } + 80% { + transform: translate(0, -1px) rotate(-4deg) scale(0.88); + } + 90% { + transform: translate(0, 1px) rotate(2deg); + } + 100% { + transform: translate(0, 0) rotate(0deg); + } +} + +.animation-wolf-move { + animation: animation-wolf-move 0.8s infinite; +} + +@keyframes animation-player-move { + 0% { + transform: translate(0, 0) rotate(0deg); + } + 70% { + transform: translate(0, 1px) rotate(0deg); + } + 80% { + transform: translate(0, -1px) rotate(-4deg) scale(0.88); + } + 90% { + transform: translate(0, 1px) rotate(2deg); + } + 100% { + transform: translate(0, 0) rotate(0deg); + } +} + +.animation-player-move { + animation: animation-player-move 0.6s infinite; +} diff --git a/src/routes/styles.css b/src/routes/styles.css index ef4e81e1..2b12d1cf 100644 --- a/src/routes/styles.css +++ b/src/routes/styles.css @@ -13,6 +13,7 @@ --color-rare: #0090FF; --color-epic: #7D66D9; --color-legendary: #F76B15; + --color-bg-loader: #7D66D9; } html {