diff --git a/client/src/Backend/GameLogic/GameManager.ts b/client/src/Backend/GameLogic/GameManager.ts index fe7be87e..d336b981 100644 --- a/client/src/Backend/GameLogic/GameManager.ts +++ b/client/src/Backend/GameLogic/GameManager.ts @@ -2442,9 +2442,6 @@ class GameManager extends EventEmitter { if (!planet) { throw new Error('tried to withdraw silver from an unknown planet'); } - if (planet.planetType !== PlanetType.TRADING_POST) { - throw new Error('can only withdraw silver from spacetime rips'); - } if (planet.owner !== this.account) { throw new Error('can only withdraw silver from a planet you own'); } diff --git a/client/src/Backend/GameLogic/GameUIManager.ts b/client/src/Backend/GameLogic/GameUIManager.ts index d9a50e28..50cc9c61 100644 --- a/client/src/Backend/GameLogic/GameUIManager.ts +++ b/client/src/Backend/GameLogic/GameUIManager.ts @@ -398,16 +398,6 @@ class GameUIManager extends EventEmitter { } public withdrawSilver(locationId: LocationId, amount: number) { - const dontShowWarningStorageKey = `${this.getAccount()?.toLowerCase()}-withdrawnWarningAcked`; - - if (localStorage.getItem(dontShowWarningStorageKey) !== 'true') { - localStorage.setItem(dontShowWarningStorageKey, 'true'); - const confirmationText = - `Are you sure you want withdraw this silver? Once you withdraw it, you ` + - `cannot deposit it again. Your withdrawn silver amount will be added to your score. You'll only see this warning once!`; - if (!confirm(confirmationText)) return; - } - this.gameManager.withdrawSilver(locationId, amount); } diff --git a/client/src/Frontend/Components/CapturePlanetButton.tsx b/client/src/Frontend/Components/CapturePlanetButton.tsx index a3ca1535..f39917cf 100644 --- a/client/src/Frontend/Components/CapturePlanetButton.tsx +++ b/client/src/Frontend/Components/CapturePlanetButton.tsx @@ -117,68 +117,67 @@ export function CapturePlanetButton({ gameManager.capturePlanet(planetWrapper.value.locationId); }, [gameManager, planetWrapper]); + if (!shouldShow) return <>; return ( - - {shouldShow && ( - <> - {shouldShowInvade && ( - + {shouldShowInvade && ( + + Invade this planet. } > - Invade this planet. } - > - {invading ? : 'Invade'} - - - )} - - {shouldShowCapture && ( - : 'Invade'} + + + )} + + {shouldShowCapture && ( + + + + Capture this planet for score!{' '} + {!!blocksLeft && blocksLeft >= 0 && ( + <> + You must wait {blocksLeft} blocks until you can capture this + planet. + + )} + {!planetHasEnoughEnergy && ( + The planet requires above 80% energy before you can capture it. + )} + + + } > - - - Capture this planet for score!{' '} - {!!blocksLeft && blocksLeft >= 0 && ( - <> - You must wait {blocksLeft} blocks until you can capture - this planet. - - )} - {!planetHasEnoughEnergy && ( - The planet requires above 80% energy before you can capture it. - )} - - - } - > - {capturing ? : 'Capture!'} - - - )} - - )} - + {capturing ? : 'Capture!'} + + + )} + + ) ); } diff --git a/client/src/Frontend/Components/OpenPaneButtons.tsx b/client/src/Frontend/Components/OpenPaneButtons.tsx index 2e3bae31..15431e5a 100644 --- a/client/src/Frontend/Components/OpenPaneButtons.tsx +++ b/client/src/Frontend/Components/OpenPaneButtons.tsx @@ -133,7 +133,7 @@ export function OpenPlanetInfoButton({ return ( } helpContent={PlanetInfoHelpContent()} diff --git a/client/src/Frontend/Panes/PlanetContextPane.tsx b/client/src/Frontend/Panes/PlanetContextPane.tsx index ca079330..e8000190 100644 --- a/client/src/Frontend/Panes/PlanetContextPane.tsx +++ b/client/src/Frontend/Panes/PlanetContextPane.tsx @@ -6,8 +6,6 @@ import { CapturePlanetButton } from '../Components/CapturePlanetButton'; import { VerticalSplit } from '../Components/CoreUI'; import { MineArtifactButton } from '../Components/MineArtifactButton'; import { - OpenBroadcastPaneButton, - OpenHatPaneButton, OpenManagePlanetInventoryButton, OpenPlanetInfoButton, OpenUpgradeDetailsPaneButton, @@ -53,15 +51,10 @@ function PlanetContextPaneContent({ } let upgradeRow = null; - if (!p?.destroyed && owned) { + if (!p?.destroyed && owned && p?.planetType == PlanetType.PLANET) { upgradeRow = ; } - let hatRow = null; - if (!p?.destroyed && owned) { - hatRow = ; - } - let withdrawRow = null; if (!p?.destroyed && owned && p?.planetType === PlanetType.TRADING_POST) { withdrawRow = ; @@ -86,12 +79,10 @@ function PlanetContextPaneContent({ <> {upgradeRow} - <> - {hatRow} {withdrawRow} diff --git a/client/src/Frontend/Utils/ShortcutConstants.ts b/client/src/Frontend/Utils/ShortcutConstants.ts index ec8b6961..f810f7fb 100644 --- a/client/src/Frontend/Utils/ShortcutConstants.ts +++ b/client/src/Frontend/Utils/ShortcutConstants.ts @@ -14,6 +14,7 @@ export const TOGGLE_TRANSACTIONS_PANE = "'"; export const TOGGLE_PLANET_INVENTORY_PANE = 's'; export const TOGGLE_HAT_PANE = 'x'; export const TOGGLE_ABANDON = 'r'; +export const TOGGLE_WITHDRAW = ']'; export const INVADE = 'y'; export const MINE_ARTIFACT = 'f'; export const TOGGLE_BROADCAST_PANE = 'z'; diff --git a/client/src/Frontend/Views/ArtifactRow.tsx b/client/src/Frontend/Views/ArtifactRow.tsx index f142392b..24a800b6 100644 --- a/client/src/Frontend/Views/ArtifactRow.tsx +++ b/client/src/Frontend/Views/ArtifactRow.tsx @@ -104,18 +104,25 @@ export function SelectArtifactRow({ artifacts: Artifact[]; }) { return ( - - {artifacts.length > 0 && - artifacts.map((a) => ( - - - - - ))} - +
+ + {artifacts.length > 0 && + artifacts.map((a) => ( + + + + + ))} + +
); } diff --git a/client/src/Frontend/Views/SendResources.tsx b/client/src/Frontend/Views/SendResources.tsx index 28b9e36e..37e3f31a 100644 --- a/client/src/Frontend/Views/SendResources.tsx +++ b/client/src/Frontend/Views/SendResources.tsx @@ -1,6 +1,10 @@ import { formatNumber } from '@dfdao/gamelogic'; import { nameOfArtifact, nameOfSpaceship } from '@dfdao/procedural'; -import { isUnconfirmedMoveTx, isUnconfirmedReleaseTx } from '@dfdao/serde'; +import { + isUnconfirmedMoveTx, + isUnconfirmedReleaseTx, + isUnconfirmedWithdrawSilverTx, +} from '@dfdao/serde'; import { Artifact, Planet, Spaceship, TooltipName } from '@dfdao/types'; import React, { useCallback } from 'react'; import styled from 'styled-components'; @@ -18,23 +22,24 @@ import dfstyles from '../Styles/dfstyles'; import { useAccount, usePlanetInactiveArtifacts, useUIManager } from '../Utils/AppHooks'; import { useEmitterValue } from '../Utils/EmitterHooks'; import { useOnUp } from '../Utils/KeyEmitters'; -import { TOGGLE_ABANDON, TOGGLE_SEND } from '../Utils/ShortcutConstants'; +import { TOGGLE_ABANDON, TOGGLE_SEND, TOGGLE_WITHDRAW } from '../Utils/ShortcutConstants'; import { SelectArtifactRow } from './ArtifactRow'; import { SelectSpaceshipRow } from './SpaceshipRow'; const StyledSendResources = styled.div` display: flex; flex-direction: column; - gap: 8px; + gap: 4px; `; const StyledShowPercent = styled.div` display: inline-block; + min-width: 35px; & > span:first-child { width: 3em; text-align: right; - margin-right: 1em; + margin-right: 0.5em; } & > span:last-child { @@ -54,8 +59,8 @@ const StyledShowPercent = styled.div` function ShowPercent({ value, setValue }: { value: number; setValue: (x: number) => void }) { return ( - {value}% - + {/* {value}% */} + setValue(value - 1)}> @@ -68,6 +73,7 @@ function ShowPercent({ value, setValue }: { value: number; setValue: (x: number) const ResourceRowDetails = styled.div` display: inline-flex; align-items: center; + justify-content: space-between; gap: 4px; `; @@ -95,26 +101,38 @@ function ResourceBar({ return ( <> - - - - {getResource(value)} - {isSilver ? 'silver' : 'energy'} - - - - ) => { - setValue(parseInt(e.target.value, 10)); - }} - /> + {isSilver ? ( + + Extract {getResource(value)} silver + + ) : ( +
+ +
+ + {getResource(value)} + + {' '} + ({value}%) {isSilver ? 'silver' : 'energy'} + +
+ +
+ + ) => { + setValue(parseInt(e.target.value, 10)); + }} + /> +
+ )} ); } @@ -153,6 +171,37 @@ function AbandonButton({ ); } +function ExtractButton({ + planet, + extracting, + disabled, +}: { + planet?: Planet; + extracting: boolean; + disabled?: boolean; +}) { + const uiManager = useUIManager(); + + if (!planet) return null; + + let silver = planet.silver; + + return ( + uiManager.withdrawSilver(planet.locationId, planet.silver)} + shortcutKey={TOGGLE_WITHDRAW} + shortcutText={TOGGLE_WITHDRAW} + disabled={planet.isHomePlanet || disabled} + > + {/* */} + {extracting ? 'Extracting' : `Extract all (${Math.floor(silver)}) silver`} + {/* */} + + ); +} + function SendRow({ toggleSending, artifact, @@ -215,9 +264,11 @@ export function SendResources({ const isSendingShip = uiManager.isSendingShip(locationId); const isAbandoning = useEmitterValue(uiManager.isAbandoning$, false); + const isExtracting = false; + const isSendingForces = useEmitterValue(uiManager.isSending$, false); const energySending = uiManager.getForcesSending(locationId); - const silverSending = uiManager.getSilverSending(locationId); + const silverSending = 100; const artifactSending = uiManager.getArtifactSending(locationId); const spaceshipSending = uiManager.getSpaceshipSending(locationId); @@ -230,15 +281,6 @@ export function SendResources({ }, [uiManager, locationId] ); - - const updateSilverSending = useCallback( - (silverPercent) => { - if (!locationId) return; - uiManager.setSilverSending(locationId, silverPercent); - }, - [uiManager, locationId] - ); - const updateArtifactSending = useCallback( (sendArtifact) => { if (!locationId) return; @@ -259,16 +301,11 @@ export function SendResources({ // that key is const energyShortcuts = '1234567890'.split(''); - // same as above, except for silver - const silverShortcuts = '!@#$%^&*()'.split(''); - // for each of the above keys, we set up a listener that is triggered whenever that key is // pressed, and sets the corresponding resource sending amount for (let i = 0; i < energyShortcuts.length; i++) { // eslint-disable-next-line react-hooks/rules-of-hooks useOnUp(energyShortcuts[i], () => updateEnergySending((i + 1) * 10), [updateEnergySending]); - // eslint-disable-next-line react-hooks/rules-of-hooks - useOnUp(silverShortcuts[i], () => updateSilverSending((i + 1) * 10), [updateSilverSending]); } useOnUp( @@ -285,20 +322,6 @@ export function SendResources({ }, [uiManager, locationId, updateEnergySending] ); - useOnUp( - '_', - () => { - updateSilverSending(uiManager.getSilverSending(locationId) - 10); - }, - [uiManager, locationId, updateSilverSending] - ); - useOnUp( - '+', - () => { - updateSilverSending(uiManager.getSilverSending(locationId) + 10); - }, - [uiManager, locationId, updateSilverSending] - ); const artifacts = usePlanetInactiveArtifacts(p); @@ -340,6 +363,19 @@ export function SendResources({ ); } + let extractRow; + if (p.value && p.value.transactions?.hasTransaction(isUnconfirmedWithdrawSilverTx)) { + extractRow = ( + + + + ); + } else if (p.value && !p.value.destroyed) { + extractRow = ( + + ); + } + return ( {owned && !p.value?.destroyed && ( @@ -350,17 +386,9 @@ export function SendResources({ setValue={updateEnergySending} disabled={disableSliders} /> - {p.value && p.value.silver > 0 && ( - - )} )} + {p.value && artifacts.length > 0 && ( 0 && extractRow} + {uiManager.getSpaceJunkEnabled() && owned ? abandonRow : null} ); diff --git a/client/src/Frontend/Views/TopBar.tsx b/client/src/Frontend/Views/TopBar.tsx index f4340c61..48fd3e8d 100644 --- a/client/src/Frontend/Views/TopBar.tsx +++ b/client/src/Frontend/Views/TopBar.tsx @@ -5,6 +5,7 @@ import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { CaptureZonesGeneratedEvent } from '../../Backend/GameLogic/CaptureZoneGenerator'; import { Hook } from '../../_types/global/GlobalTypes'; +import { Btn } from '../Components/Btn'; import { AlignCenterHorizontally } from '../Components/CoreUI'; import { AccountLabel } from '../Components/Labels/Labels'; import { Gold, Red, Sub, Text, White } from '../Components/Text'; @@ -41,11 +42,14 @@ function BoardPlacement({ account }: { account: EthAddress | undefined }) { } content = ( - - - score: {formattedScore} - - +
+ + + stockpile: {formattedScore} + + + Extract all +
); } diff --git a/packages/gamelogic/src/artifact.ts b/packages/gamelogic/src/artifact.ts index 61a7a774..ef0346e0 100644 --- a/packages/gamelogic/src/artifact.ts +++ b/packages/gamelogic/src/artifact.ts @@ -9,6 +9,7 @@ import { ArtifactTypeNames, Biome, BiomeNames, + Planet, PlanetLevel, RenderedArtifact, } from '@dfdao/types'; @@ -105,6 +106,10 @@ export function setForceAncient(force: boolean): void { forceAncient = force; } +export function isActivated(artifact: Artifact | undefined, planet: Planet | undefined) { + return !!planet && !!artifact && planet.activeArtifact === artifact; +} + export function artifactFileName( videoMode: boolean, thumb: boolean,