Better UX: player now can add units wven if funds are not yet minted

This commit is contained in:
mic0 2024-10-26 13:49:29 +02:00
parent fefa2641e4
commit 84c0aeff03
Signed by: mico
GPG Key ID: A3F8023524CF1C8D
3 changed files with 26 additions and 14 deletions

View File

@ -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<Record<UnitType, boolean>>(defaultAvailabilityMap);
const [isShrouded, setIsShrouded] = useState<Record<UnitType, boolean>>(defaultAvailabilityMap);
const [canKnowAbout, setCanKnowAbout] = useState<Record<UnitType, boolean>>(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<UnitType, number> = {
@ -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 <>
<div className={`${styles.tavern_keeper} ${styles.person} ${styles.static}`} />
<div className={styles.armyUnits}>

View File

@ -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;

View File

@ -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