forked from mico/idle_moloch
95 lines
3.2 KiB
TypeScript
95 lines
3.2 KiB
TypeScript
import { formatUnits } from "viem"
|
|
import { BossLevel, usePlayer } from "../providers/PlayerProvider"
|
|
import styles from "../styles/Info.module.css"
|
|
import { useEffect, useReducer, useRef } from "react"
|
|
import { calculateBalance, toReadable } from "./Counter"
|
|
|
|
export const bossLevelToClass: Record<BossLevel, string> = {
|
|
0: styles.boss0,
|
|
1: styles.boss1,
|
|
2: styles.boss2,
|
|
3: styles.boss3,
|
|
4: styles.boss4,
|
|
5: styles.boss5,
|
|
6: styles.boss6,
|
|
}
|
|
|
|
export const bossToName: Record<BossLevel, string> = {
|
|
0: "Gluttonous",
|
|
1: "Slothful",
|
|
2: "Lusty",
|
|
3: "Wrathful",
|
|
4: "Envious",
|
|
5: "Prideful",
|
|
6: "Greedy",
|
|
}
|
|
|
|
export const bossToReward: Record<BossLevel, bigint> = {
|
|
0: BigInt("129600000000000000"),
|
|
1: BigInt("18321824160000000000"),
|
|
2: BigInt("112876175462400000000"),
|
|
3: BigInt("332589044376576000000"),
|
|
4: BigInt("624347914175155814400"),
|
|
5: BigInt("923147774241822027325"),
|
|
6: BigInt("1139287879845155524372"),
|
|
}
|
|
|
|
// for boss chances (percent) [99, 89, 80, 70, 62, 51, 40]
|
|
const bossToChance: Record<BossLevel, number> = {
|
|
0: 0.99,
|
|
1: 0.89,
|
|
2: 0.8,
|
|
3: 0.7,
|
|
4: 0.62,
|
|
5: 0.51,
|
|
6: 0.40
|
|
}
|
|
|
|
const bossToBossPower: Record<BossLevel, bigint> = {
|
|
0: BigInt("3000000"),
|
|
1: BigInt("30000000"),
|
|
2: BigInt("300000000"),
|
|
3: BigInt("3000000000"),
|
|
4: BigInt("30000000000"),
|
|
5: BigInt("300000000000"),
|
|
6: BigInt("3000000000000"),
|
|
}
|
|
|
|
const getBossChanceToDefeat = (bossLevel: BossLevel, geld_balance: bigint) => {
|
|
const bossPower = bossToBossPower[bossLevel]
|
|
const geldBurnt = geld_balance >= bossPower ? bossPower : geld_balance;
|
|
const relativePower = (geldBurnt * geldBurnt * BigInt("100")) / (bossPower * bossPower);
|
|
return bossToChance[bossLevel] * Number(relativePower) / 100
|
|
}
|
|
|
|
const BossInfo = () => {
|
|
const { boss, balance, player, army } = usePlayer();
|
|
const variant = boss?.variants[boss.level] || 0;
|
|
const maxChance = bossToChance[boss?.level || 0];
|
|
const chanceToDefeat = useRef(getBossChanceToDefeat(boss?.level || 0, balance ?? BigInt(0)));
|
|
const [, render] = useReducer(p => !p, false);
|
|
useEffect(() => {
|
|
const tickInterval = setInterval(() => {
|
|
const _balance = calculateBalance(
|
|
balance ?? BigInt(0),
|
|
army?.profit_per_second ?? BigInt(0),
|
|
player?.last_raided_at ?? BigInt(0)
|
|
);
|
|
chanceToDefeat.current = getBossChanceToDefeat(boss?.level ?? 0, _balance)
|
|
render();
|
|
}, 100);
|
|
return () => clearInterval(tickInterval)
|
|
}, [balance, army?.profit_per_second, player?.last_raided_at, boss?.level])
|
|
return <div className={styles.bossInfo}>
|
|
<p><strong className={bossLevelToClass[variant]}>{bossToName[variant]}</strong> Moloch <small>(lvl {boss ? boss.level + 1 : 0})</small></p>
|
|
<p><strong className={styles.reward}>{parseFloat(parseFloat(formatUnits(bossToReward[boss?.level || 0], 18).toString()).toFixed(4))} RGCVII</strong> <small>reward</small></p>
|
|
<p>
|
|
<strong>{parseFloat((chanceToDefeat.current * 100).toFixed(2))} % to slay</strong>{" "}
|
|
{chanceToDefeat.current == maxChance ? <small className={styles.maxed}>(MAXED)</small> : <small>(Max {maxChance * 100}%)</small>}
|
|
</p>
|
|
<p><small>{toReadable(bossToBossPower[boss?.level ?? 0])} GELD = max chance</small></p>
|
|
</div>
|
|
}
|
|
|
|
export default BossInfo
|