85 lines
3.5 KiB
TypeScript
85 lines
3.5 KiB
TypeScript
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) => {
|
|
// 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(10000) /* decimals */)
|
|
/ BigInt(1000) /* deduct milliseconds*/))
|
|
}
|
|
|
|
export const toReadable = (value: bigint, applyTokenDivision?: boolean) => {
|
|
if (applyTokenDivision) {
|
|
value = value / BigInt(10000);
|
|
}
|
|
const suffixes = [
|
|
{ value: BigInt('1000'), suffix: 'thousand' },
|
|
{ value: BigInt('1000000'), suffix: 'million' },
|
|
{ value: BigInt('1000000000'), suffix: 'billion' },
|
|
{ value: BigInt('1000000000000'), suffix: 'trillion' },
|
|
{ value: BigInt('1000000000000000'), suffix: 'quadrillion' },
|
|
{ value: BigInt('1000000000000000000'), suffix: 'quintillion' },
|
|
{ value: BigInt('1000000000000000000000'), suffix: 'sextillion' },
|
|
{ value: BigInt('1000000000000000000000000'), suffix: 'septillion' },
|
|
{ value: BigInt('1000000000000000000000000000'), suffix: 'octillion' },
|
|
{ value: BigInt('1000000000000000000000000000000'), suffix: 'nonillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000'), suffix: 'decillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000'), suffix: 'undecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000'), suffix: 'duodecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000000'), suffix: 'tredecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000'), suffix: 'quattuordecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000'), suffix: 'quindecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000'), suffix: 'sexdecillion' },
|
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000000'), suffix: 'septendecillion' },
|
|
];
|
|
|
|
console.log(value)
|
|
|
|
for (let i = 0; i < suffixes.length; i++) {
|
|
if (value < suffixes[i].value) {
|
|
if (i == 0) {
|
|
return value.toString();
|
|
} else {
|
|
const divided = value / suffixes[i - 1].value;
|
|
const numStr = (value % suffixes[i - 0].value).toString().slice(0, 3);
|
|
const remainder = 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.toString() ?? "0")
|
|
const availableBalance = useRef(balance.toString() ?? "0")
|
|
useEffect(() => {
|
|
const tickInterval = setInterval(() => {
|
|
balanceCount.current = toReadable(calculateBalance(
|
|
balance,
|
|
army?.profit_per_second ?? BigInt(0),
|
|
player?.last_raided_at ?? BigInt(0)
|
|
), true);
|
|
availableBalance.current = toReadable(balance, true);
|
|
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}>available on chain: {availableBalance.current} GELD</p>
|
|
</>
|
|
}
|
|
|
|
export default Counter
|