83 lines
3.6 KiB
TypeScript
83 lines
3.6 KiB
TypeScript
import { useEffect, useReducer, useRef } from "react";
|
|
import { usePlayer } from "../providers/PlayerProvider"
|
|
import styles from "../styles/Header.module.css"
|
|
import { formatUnits } from "viem";
|
|
|
|
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;
|
|
return (
|
|
balance +
|
|
(BigInt(millisecondsSinceLastRaid) * perSecond
|
|
/ BigInt(1000) /* deduct milliseconds*/))
|
|
}
|
|
|
|
export const toReadable = (rawValue: bigint) => {
|
|
const value = rawValue / BigInt(10000);
|
|
const suffixes = [
|
|
{ value: BigInt('1000'), suffix: 'k' }, // Thousand
|
|
{ value: BigInt('1000000'), suffix: 'M' }, // Million
|
|
{ value: BigInt('1000000000'), suffix: 'B' }, // Billion
|
|
{ value: BigInt('1000000000000'), suffix: 'T' }, // Trillion
|
|
{ value: BigInt('1000000000000000'), suffix: 'Qd' }, // Quadrillion
|
|
{ value: BigInt('1000000000000000000'), suffix: 'Qi' }, // Quintillion
|
|
{ value: BigInt('1000000000000000000000'), suffix: 'Sx' }, // Sextillion
|
|
{ value: BigInt('1000000000000000000000000'), suffix: 'Sp' }, // Septillion
|
|
{ value: BigInt('1000000000000000000000000000'), suffix: 'Oc' }, // Octillion
|
|
{ value: BigInt('1000000000000000000000000000000'), suffix: 'No' }, // Nonillion
|
|
{ value: BigInt('1000000000000000000000000000000000'), suffix: 'Dc' }, // Decillion
|
|
{ value: BigInt('1000000000000000000000000000000000000'), suffix: 'Ud' }, // Undecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000'), suffix: 'Dd' }, // Duodecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000000'), suffix: 'Td' }, // Tredecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000'), suffix: 'Qt' }, // Quattuordecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000'), suffix: 'Qn' }, // Quindecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000'), suffix: 'Sd' }, // Sexdecillion
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000000'), suffix: 'St' }, // Septendecillion
|
|
];
|
|
|
|
|
|
for (let i = 0; i < suffixes.length; i++) {
|
|
if (value < suffixes[i].value) {
|
|
if (i == 0) {
|
|
return formatUnits(rawValue, 4);
|
|
} else {
|
|
const divided = value / suffixes[i - 1].value;
|
|
const numStr = (value % suffixes[i - 1].value).toString().slice(0, 3);
|
|
const remainder = numStr == "0" ? "" : "." + parseInt(numStr.replace(/0+$/, ''), 10);
|
|
return `${divided.toString()}${remainder.toString()} ${suffixes[i - 1].suffix}`;
|
|
}
|
|
}
|
|
}
|
|
|
|
return value.toString();
|
|
}
|
|
|
|
const Counter = () => {
|
|
const { balance, army, player } = usePlayer();
|
|
const [, render] = useReducer(p => !p, false);
|
|
const balanceCount = useRef(balance ? balance.toString() : "0")
|
|
const availableBalance = useRef(balance ? balance.toString() : "0")
|
|
useEffect(() => {
|
|
const tickInterval = setInterval(() => {
|
|
balanceCount.current = toReadable(calculateBalance(
|
|
balance,
|
|
army?.profit_per_second ?? BigInt(0),
|
|
player?.last_raided_at ?? BigInt(0)
|
|
));
|
|
availableBalance.current = toReadable(balance);
|
|
render();
|
|
}, 100);
|
|
return () => clearInterval(tickInterval)
|
|
}, [balance, army?.profit_per_second, player?.last_raided_at])
|
|
|
|
return <>
|
|
<p className={styles.counter}>
|
|
{balanceCount.current} GELD
|
|
</p>
|
|
<p className={styles.counter_available}>in wallet: {availableBalance.current} GELD</p>
|
|
</>
|
|
}
|
|
|
|
export default Counter
|