Better UX: player now can add units wven if funds are not yet minted
This commit is contained in:
parent
fefa2641e4
commit
84c0aeff03
@ -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 { UnitType, usePlayer } from '../providers/PlayerProvider';
|
||||||
import styles from '../styles/Army.module.css';
|
import styles from '../styles/Army.module.css';
|
||||||
import { toReadable } from './Counter';
|
import { calculateBalance, toReadable } from './Counter';
|
||||||
|
|
||||||
const PRECISION = BigInt(10000);
|
const PRECISION = BigInt(10000);
|
||||||
const BASE_PRICE = BigInt(380000);
|
const BASE_PRICE = BigInt(380000);
|
||||||
@ -102,10 +102,9 @@ const Army = () => {
|
|||||||
const [canPurchase, setCanPurchase] = useState<Record<UnitType, boolean>>(defaultAvailabilityMap);
|
const [canPurchase, setCanPurchase] = useState<Record<UnitType, boolean>>(defaultAvailabilityMap);
|
||||||
const [isShrouded, setIsShrouded] = useState<Record<UnitType, boolean>>(defaultAvailabilityMap);
|
const [isShrouded, setIsShrouded] = useState<Record<UnitType, boolean>>(defaultAvailabilityMap);
|
||||||
const [canKnowAbout, setCanKnowAbout] = 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)
|
const setAvailabilities = useCallback(() => {
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isRegistered) {
|
if (isRegistered) {
|
||||||
const totalMinted = player?.total_minted ?? BigInt(0);
|
const totalMinted = player?.total_minted ?? BigInt(0);
|
||||||
const n_units: Record<UnitType, number> = {
|
const n_units: Record<UnitType, number> = {
|
||||||
@ -127,10 +126,10 @@ const Army = () => {
|
|||||||
3: totalMinted >= unitAvailableToDiscoverAt[3],
|
3: totalMinted >= unitAvailableToDiscoverAt[3],
|
||||||
}
|
}
|
||||||
const canActuallyBuy = {
|
const canActuallyBuy = {
|
||||||
0: balance >= calculateUnitPrice(0, n_units[0], 1) && isKnown[0] && !inShroud[0],
|
0: balanceCount.current >= calculateUnitPrice(0, n_units[0], 1) && isKnown[0] && !inShroud[0],
|
||||||
1: balance >= calculateUnitPrice(1, n_units[1], 1) && isKnown[1] && !inShroud[1],
|
1: balanceCount.current >= calculateUnitPrice(1, n_units[1], 1) && isKnown[1] && !inShroud[1],
|
||||||
2: balance >= calculateUnitPrice(2, n_units[2], 1) && isKnown[2] && !inShroud[2],
|
2: balanceCount.current >= calculateUnitPrice(2, n_units[2], 1) && isKnown[2] && !inShroud[2],
|
||||||
3: balance >= calculateUnitPrice(3, n_units[3], 1) && isKnown[3] && !inShroud[3],
|
3: balanceCount.current >= calculateUnitPrice(3, n_units[3], 1) && isKnown[3] && !inShroud[3],
|
||||||
};
|
};
|
||||||
setCanPurchase(canActuallyBuy)
|
setCanPurchase(canActuallyBuy)
|
||||||
setIsShrouded(inShroud)
|
setIsShrouded(inShroud)
|
||||||
@ -141,12 +140,23 @@ const Army = () => {
|
|||||||
setCanKnowAbout(defaultAvailabilityMap)
|
setCanKnowAbout(defaultAvailabilityMap)
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
balance,
|
|
||||||
army,
|
army,
|
||||||
isRegistered,
|
isRegistered,
|
||||||
player?.total_minted
|
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 <>
|
return <>
|
||||||
<div className={`${styles.tavern_keeper} ${styles.person} ${styles.static}`} />
|
<div className={`${styles.tavern_keeper} ${styles.person} ${styles.static}`} />
|
||||||
<div className={styles.armyUnits}>
|
<div className={styles.armyUnits}>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useEffect, useReducer, useRef } from "react";
|
|||||||
import { usePlayer } from "../providers/PlayerProvider"
|
import { usePlayer } from "../providers/PlayerProvider"
|
||||||
import styles from "../styles/Header.module.css"
|
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
|
// convert to milliseconds trick so we get a more smooth counter
|
||||||
const millisecondsSinceLastRaid =
|
const millisecondsSinceLastRaid =
|
||||||
(new Date()).getTime() - parseInt(lastRaidedAt.toString()) * 1000;
|
(new Date()).getTime() - parseInt(lastRaidedAt.toString()) * 1000;
|
||||||
|
|||||||
@ -61,14 +61,13 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
// Helper so we can use it when buying units too
|
// Helper so we can use it when buying units too
|
||||||
function performRaid(address player) private {
|
function performRaid(address player) private {
|
||||||
uint256 time_past = block.timestamp - players[player].last_raided_at;
|
uint256 time_past = block.timestamp - players[player].last_raided_at;
|
||||||
|
|
||||||
uint256 new_geld = armies[player].profit_per_second * time_past;
|
uint256 new_geld = armies[player].profit_per_second * time_past;
|
||||||
|
|
||||||
// TODO: Pink noise, make it so sometimes its better than expected
|
// TODO: Pink noise, make it so sometimes its better than expected
|
||||||
|
|
||||||
_mint(player, new_geld);
|
_mint(player, new_geld);
|
||||||
players[player].last_raided_at = block.timestamp;
|
players[player].last_raided_at = block.timestamp;
|
||||||
players[player].total_minted = new_geld;
|
players[player].total_minted += new_geld;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to get Player struct
|
// Function to get Player struct
|
||||||
@ -108,8 +107,11 @@ contract RaidGeld is ERC20, Ownable {
|
|||||||
|
|
||||||
uint256 cost = RaidGeldUtils.calculateUnitPrice(unit, currentLevel, n_units);
|
uint256 cost = RaidGeldUtils.calculateUnitPrice(unit, currentLevel, n_units);
|
||||||
// First trigger a raid so player receives what he is due at to this moment
|
// 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);
|
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
|
// 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
|
// by first calculating the difference and then minting / burning in just one operation
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user