diff --git a/client/src/dojo/modelManager/TileManager.ts b/client/src/dojo/modelManager/TileManager.ts index ed2c24c02..e2889608a 100644 --- a/client/src/dojo/modelManager/TileManager.ts +++ b/client/src/dojo/modelManager/TileManager.ts @@ -8,6 +8,7 @@ import { getDirectionBetweenAdjacentHexes, getNeighborHexes, ID, + Position, RealmLevels, ResourcesIds, StructureType, @@ -296,15 +297,12 @@ export class TileManager { }); }; - placeStructure = async (entityId: ID, structureType: StructureType, hexCoords: HexPosition) => { + placeStructure = async (entityId: ID, structureType: StructureType, coords: Position) => { if (structureType == StructureType.Hyperstructure) { await this.setup.systemCalls.create_hyperstructure({ signer: this.setup.network.burnerManager.account!, creator_entity_id: entityId, - coords: { - x: hexCoords.col, - y: hexCoords.row, - }, + coords, }); } }; diff --git a/client/src/three/scenes/Worldmap.ts b/client/src/three/scenes/Worldmap.ts index 5e852162f..7d7e07166 100644 --- a/client/src/three/scenes/Worldmap.ts +++ b/client/src/three/scenes/Worldmap.ts @@ -9,6 +9,7 @@ import { HexPosition, SceneName } from "@/types"; import { Position } from "@/types/Position"; import { FELT_CENTER } from "@/ui/config"; import { UNDEFINED_STRUCTURE_ENTITY_ID } from "@/ui/constants"; +import { View } from "@/ui/modules/navigation/LeftNavigationModule"; import { getWorldPositionForHex } from "@/ui/utils/utils"; import { BiomeType, getNeighborOffsets, ID } from "@bibliothecadao/eternum"; import { throttle } from "lodash"; @@ -21,7 +22,6 @@ import Minimap from "../components/Minimap"; import { SelectedHexManager } from "../components/SelectedHexManager"; import { StructureManager } from "../components/StructureManager"; import { StructurePreview } from "../components/StructurePreview"; -import { LocationManager } from "../helpers/LocationManager"; import { ArmySystemUpdate, TileSystemUpdate } from "../systems/types"; import { HexagonScene } from "./HexagonScene"; import { HEX_SIZE, PREVIEW_BUILD_COLOR_INVALID } from "./constants"; @@ -240,31 +240,40 @@ export default class WorldmapScene extends HexagonScene { return !isStructure && isExplored && !isOcean; } - protected onHexagonDoubleClick(hexCoords: HexPosition) { - const position = new Position({ x: hexCoords.col, y: hexCoords.row }); - const isBattle = this.battleManager.battles.hasByPosition(position); - if (isBattle) return; - const url = position.toHexLocationUrl(); - LocationManager.updateUrl(url); - } + protected onHexagonDoubleClick(hexCoords: HexPosition) {} protected onHexagonClick(hexCoords: HexPosition | null) { - if (!hexCoords) { - return; - } + if (!hexCoords) return; + const buildingType = this.structurePreview?.getPreviewStructure(); if (buildingType && this._canBuildStructure(hexCoords)) { - const normalizedHexCoords = { col: hexCoords.col + FELT_CENTER, row: hexCoords.row + FELT_CENTER }; - this.tileManager.placeStructure(this.structureEntityId, buildingType.type, normalizedHexCoords); - this.clearEntitySelection(); + this.handleStructurePlacement(hexCoords); } else { - const position = getWorldPositionForHex(hexCoords); + this.handleHexSelection(hexCoords); + } + } + + protected handleStructurePlacement(hexCoords: HexPosition) { + const buildingType = this.structurePreview?.getPreviewStructure(); + if (!buildingType) return; + + const contractHexPosition = new Position({ x: hexCoords.col, y: hexCoords.row }).getContract(); + this.tileManager.placeStructure(this.structureEntityId, buildingType.type, contractHexPosition); + this.clearEntitySelection(); + } + + protected handleHexSelection(hexCoords: HexPosition) { + const contractHexPosition = new Position({ x: hexCoords.col, y: hexCoords.row }).getContract(); + const position = getWorldPositionForHex(hexCoords); + if (contractHexPosition.x !== this.state.selectedHex?.col || contractHexPosition.y !== this.state.selectedHex.row) { this.selectedHexManager.setPosition(position.x, position.z); this.state.setSelectedHex({ - col: hexCoords.col + FELT_CENTER, - row: hexCoords.row + FELT_CENTER, + col: contractHexPosition.x, + row: contractHexPosition.y, }); + } else { + this.state.setLeftNavigationView(View.EntityView); } } diff --git a/client/src/ui/components/structures/worldmap/StructureCard.tsx b/client/src/ui/components/structures/worldmap/StructureCard.tsx index ed4f6a0bf..a8a2266e0 100644 --- a/client/src/ui/components/structures/worldmap/StructureCard.tsx +++ b/client/src/ui/components/structures/worldmap/StructureCard.tsx @@ -1,6 +1,7 @@ import { configManager } from "@/dojo/setup"; import { useDojo } from "@/hooks/context/DojoContext"; import { ArmyInfo, getArmyByEntityId } from "@/hooks/helpers/useArmies"; +import { useQuery } from "@/hooks/helpers/useQuery"; import { useStructureAtPosition } from "@/hooks/helpers/useStructures"; import useUIStore from "@/hooks/store/useUIStore"; import { Position } from "@/types/Position"; @@ -10,9 +11,10 @@ import { ResourceIcon } from "@/ui/elements/ResourceIcon"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui/elements/Tabs"; import { getTotalTroops } from "@/ui/modules/military/battle-view/BattleHistory"; import { currencyFormat, formatNumber } from "@/ui/utils/utils"; -import { EternumGlobalConfig, ID, ResourcesIds } from "@bibliothecadao/eternum"; +import { ID, ResourcesIds } from "@bibliothecadao/eternum"; import { useComponentValue } from "@dojoengine/react"; import { getEntityIdFromKeys } from "@dojoengine/utils"; +import clsx from "clsx"; import { ArrowRight } from "lucide-react"; import { useMemo, useState } from "react"; import { ResourceExchange } from "../../hyperstructures/ResourceExchange"; @@ -30,10 +32,31 @@ export const StructureCard = ({ const [showMergeTroopsPopup, setShowMergeTroopsPopup] = useState(false); const structure = useStructureAtPosition(position.getContract()); + const { handleUrlChange } = useQuery(); + + const goToHexView = () => { + const url = position.toHexLocationUrl(); + handleUrlChange(url); + }; + return ( Boolean(structure) && (
- Structure +
+ Structure +
+ +
+
{!showMergeTroopsPopup && ( { return ( BigInt(Object.values(attackerArmyTroops || {}).reduce((a, b) => Number(a) + Number(b), 0)) / - BigInt(EternumGlobalConfig.resources.resourcePrecision) + BigInt(configManager.getResourcePrecision()) ); }, [attackerArmyTroops]); @@ -213,10 +236,9 @@ const TroopExchange = ({ const fromArmy = transferDirection === "to" ? getArmy(giverArmyEntityId) : takerArmy || getArmy(protector!.army_id); const toArmy = transferDirection === "to" ? takerArmy || getArmy(protector!.army_id) : getArmy(giverArmyEntityId); const transferedTroops = { - knight_count: troopsGiven[ResourcesIds.Knight] * BigInt(EternumGlobalConfig.resources.resourceMultiplier), - paladin_count: troopsGiven[ResourcesIds.Paladin] * BigInt(EternumGlobalConfig.resources.resourceMultiplier), - crossbowman_count: - troopsGiven[ResourcesIds.Crossbowman] * BigInt(EternumGlobalConfig.resources.resourceMultiplier), + knight_count: troopsGiven[ResourcesIds.Knight] * BigInt(configManager.getResourcePrecision()), + paladin_count: troopsGiven[ResourcesIds.Paladin] * BigInt(configManager.getResourcePrecision()), + crossbowman_count: troopsGiven[ResourcesIds.Crossbowman] * BigInt(configManager.getResourcePrecision()), }; await army_merge_troops({ signer: account, @@ -270,7 +292,7 @@ const TroopExchange = ({

{ + const sizeClasses = { + sm: "w-4 h-4 text-xxs", + md: "w-5 h-5 text-xs", + lg: "w-6 h-6 text-sm", + }; + + return ( + + {keyName.toUpperCase()} + + ); +}; diff --git a/client/src/ui/modules/navigation/LeftNavigationModule.tsx b/client/src/ui/modules/navigation/LeftNavigationModule.tsx index 2418fc6ae..78a212968 100644 --- a/client/src/ui/modules/navigation/LeftNavigationModule.tsx +++ b/client/src/ui/modules/navigation/LeftNavigationModule.tsx @@ -10,9 +10,10 @@ import { useEntitiesUtils } from "@/hooks/helpers/useEntities"; import { MarketModal } from "@/ui/components/trading/MarketModal"; import { BuildingThumbs, MenuEnum } from "@/ui/config"; import { BaseContainer } from "@/ui/containers/BaseContainer"; +import { KeyBoardKey } from "@/ui/elements/KeyBoardKey"; import clsx from "clsx"; import { motion } from "framer-motion"; -import { Suspense, lazy, useMemo, useState } from "react"; +import { Suspense, lazy, useEffect, useMemo, useState } from "react"; import { construction, military, @@ -93,19 +94,38 @@ export const LeftNavigationModule = () => { [structureInfo], ); + useEffect(() => { + const handleKeyPress = (event: KeyboardEvent) => { + switch (event.key.toLowerCase()) { + case "e": + setView(view === View.EntityView ? View.None : View.EntityView); + break; + } + }; + + window.addEventListener("keydown", handleKeyPress); + + return () => { + window.removeEventListener("keydown", handleKeyPress); + }; + }, [view, setView, toggleModal]); + const navigation = useMemo(() => { const baseNavigation = [ { name: MenuEnum.entityDetails, button: ( - setView(view === View.EntityView ? View.None : View.EntityView)} - /> +

+ setView(view === View.EntityView ? View.None : View.EntityView)} + /> + +
), }, {