From 84c0aeff033b459ce804d39bc90e391aa4307e72 Mon Sep 17 00:00:00 2001 From: Mitja Belak Date: Sat, 26 Oct 2024 13:49:29 +0200 Subject: [PATCH] Better UX: player now can add units wven if funds are not yet minted --- app/src/components/Army.tsx | 30 ++++++++++++++++++++---------- app/src/components/Counter.tsx | 2 +- src/RaidGeld.sol | 8 +++++--- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/app/src/components/Army.tsx b/app/src/components/Army.tsx index 4d7b0d0..dd0e572 100644 --- a/app/src/components/Army.tsx +++ b/app/src/components/Army.tsx @@ -1,7 +1,7 @@ -import { useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { UnitType, usePlayer } from '../providers/PlayerProvider'; import styles from '../styles/Army.module.css'; -import { toReadable } from './Counter'; +import { calculateBalance, toReadable } from './Counter'; const PRECISION = BigInt(10000); const BASE_PRICE = BigInt(380000); @@ -102,10 +102,9 @@ const Army = () => { const [canPurchase, setCanPurchase] = useState>(defaultAvailabilityMap); const [isShrouded, setIsShrouded] = useState>(defaultAvailabilityMap); const [canKnowAbout, setCanKnowAbout] = useState>(defaultAvailabilityMap); + const balanceCount = useRef(BigInt(balance ?? 0)) - console.log(canPurchase, "\nshroud", isShrouded, "\ncanknowabout", canKnowAbout) - - useEffect(() => { + const setAvailabilities = useCallback(() => { if (isRegistered) { const totalMinted = player?.total_minted ?? BigInt(0); const n_units: Record = { @@ -127,10 +126,10 @@ const Army = () => { 3: totalMinted >= unitAvailableToDiscoverAt[3], } const canActuallyBuy = { - 0: balance >= calculateUnitPrice(0, n_units[0], 1) && isKnown[0] && !inShroud[0], - 1: balance >= calculateUnitPrice(1, n_units[1], 1) && isKnown[1] && !inShroud[1], - 2: balance >= calculateUnitPrice(2, n_units[2], 1) && isKnown[2] && !inShroud[2], - 3: balance >= calculateUnitPrice(3, n_units[3], 1) && isKnown[3] && !inShroud[3], + 0: balanceCount.current >= calculateUnitPrice(0, n_units[0], 1) && isKnown[0] && !inShroud[0], + 1: balanceCount.current >= calculateUnitPrice(1, n_units[1], 1) && isKnown[1] && !inShroud[1], + 2: balanceCount.current >= calculateUnitPrice(2, n_units[2], 1) && isKnown[2] && !inShroud[2], + 3: balanceCount.current >= calculateUnitPrice(3, n_units[3], 1) && isKnown[3] && !inShroud[3], }; setCanPurchase(canActuallyBuy) setIsShrouded(inShroud) @@ -141,12 +140,23 @@ const Army = () => { setCanKnowAbout(defaultAvailabilityMap) } }, [ - balance, army, isRegistered, player?.total_minted ]) + useEffect(() => { + const tickInterval = setInterval(() => { + balanceCount.current = calculateBalance( + balance ?? BigInt(0), + army?.profit_per_second ?? BigInt(0), + player?.last_raided_at ?? BigInt(0) + ); + setAvailabilities() + }, 100); + return () => clearInterval(tickInterval) + }, [balance, army?.profit_per_second, player?.last_raided_at, setAvailabilities]) + return <>
diff --git a/app/src/components/Counter.tsx b/app/src/components/Counter.tsx index 82850dc..d188dcf 100644 --- a/app/src/components/Counter.tsx +++ b/app/src/components/Counter.tsx @@ -2,7 +2,7 @@ import { useEffect, useReducer, useRef } from "react"; import { usePlayer } from "../providers/PlayerProvider" import styles from "../styles/Header.module.css" -const calculateBalance = (balance: bigint, perSecond: bigint, lastRaidedAt: bigint) => { +export const calculateBalance = (balance: bigint, perSecond: bigint, lastRaidedAt: bigint) => { // convert to milliseconds trick so we get a more smooth counter const millisecondsSinceLastRaid = (new Date()).getTime() - parseInt(lastRaidedAt.toString()) * 1000; diff --git a/src/RaidGeld.sol b/src/RaidGeld.sol index f9f707f..047f185 100644 --- a/src/RaidGeld.sol +++ b/src/RaidGeld.sol @@ -61,14 +61,13 @@ contract RaidGeld is ERC20, Ownable { // Helper so we can use it when buying units too function performRaid(address player) private { uint256 time_past = block.timestamp - players[player].last_raided_at; - uint256 new_geld = armies[player].profit_per_second * time_past; // TODO: Pink noise, make it so sometimes its better than expected _mint(player, new_geld); players[player].last_raided_at = block.timestamp; - players[player].total_minted = new_geld; + players[player].total_minted += new_geld; } // Function to get Player struct @@ -108,8 +107,11 @@ contract RaidGeld is ERC20, Ownable { uint256 cost = RaidGeldUtils.calculateUnitPrice(unit, currentLevel, n_units); // First trigger a raid so player receives what he is due at to this moment + + uint256 time_past = block.timestamp - players[msg.sender].last_raided_at; + uint256 new_geld = armies[msg.sender].profit_per_second * time_past; + require(balanceOf(msg.sender) + new_geld > cost, "Not enough GELD to add this unit"); performRaid(msg.sender); - require(balanceOf(msg.sender) > cost, "Not enough GELD to add this much"); // TODO: Since we are first minting then burning the token, this could be simplified // by first calculating the difference and then minting / burning in just one operation