forked from mico/idle_moloch
Towers goes on cooldown during raiding
This commit is contained in:
parent
56e4b5ce26
commit
cabfc5e758
@ -2,7 +2,7 @@
|
||||
|
||||
Idle game & shitcoin advanture dedicated to cohort VII of Raid Guild.
|
||||
|
||||
## Set up
|
||||
## Set up for local DEV
|
||||
|
||||
### 1. Run `anvil` to setup local RPC
|
||||
|
||||
@ -14,7 +14,11 @@ Either use `./deploy_contract.sh` script (!! change contract values and set priv
|
||||
|
||||
Move to `app` dir, install deps via `npm install` and run `npm run dev` to start the dev server.
|
||||
|
||||
#### 3. 1. Point Metamask to Anvil network for local dev
|
||||
#### 3. 1. Run `cast rpc anvil_mine`
|
||||
|
||||
This is so time gets set on the local chain, otherwise you will start at 0 time and first mint will give you bajillion GELD.
|
||||
|
||||
#### 3. 2. Point Metamask to Anvil network for local dev
|
||||
|
||||
### 4. Local development requires mining blocks by hand
|
||||
|
||||
|
||||
@ -6,29 +6,70 @@ const calculateBalance = (balance: bigint, perSecond: bigint, lastRaidedAt: bigi
|
||||
// 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)))
|
||||
return (
|
||||
balance +
|
||||
(BigInt(millisecondsSinceLastRaid) * (perSecond * BigInt(10000) /* decimals */)
|
||||
/ BigInt(1000) /* deduct milliseconds*/))
|
||||
}
|
||||
|
||||
const formatToGeld = (balance: bigint) => balance / BigInt(10000);
|
||||
const toReadable = (value: bigint) => {
|
||||
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' },
|
||||
];
|
||||
|
||||
for (let i = 0; i < suffixes.length; i++) {
|
||||
if (value < suffixes[i].value) {
|
||||
if (i == 0) {
|
||||
return value;
|
||||
} else {
|
||||
const divided = value / suffixes[i - 1].value;
|
||||
const remainder = value % suffixes[i - 1].value;
|
||||
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 ?? BigInt(0))
|
||||
const balanceCount = useRef(balance.toString() ?? "0")
|
||||
|
||||
useEffect(() => {
|
||||
const tickInterval = setInterval(() => {
|
||||
balanceCount.current = formatToGeld(calculateBalance(
|
||||
balanceCount.current = toReadable(calculateBalance(
|
||||
balance,
|
||||
army?.profit_per_second ?? BigInt(0),
|
||||
player?.last_raided_at ?? BigInt(0)
|
||||
));
|
||||
)).toString();
|
||||
render();
|
||||
}, 20);
|
||||
}, 100);
|
||||
return () => clearInterval(tickInterval)
|
||||
}, [balance, army?.profit_per_second, player?.last_raided_at])
|
||||
|
||||
return <p className={styles.counter}>{balanceCount.current.toString()} GELD</p>
|
||||
return <p className={styles.counter}>
|
||||
{balanceCount.current} GELD
|
||||
</p>
|
||||
}
|
||||
|
||||
export default Counter
|
||||
|
||||
@ -1,21 +1,13 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from "react"
|
||||
import React, { useCallback, useMemo } from "react"
|
||||
import styles from "../styles/Header.module.css"
|
||||
import { usePlayer } from "../providers/PlayerProvider";
|
||||
import { useAccount } from 'wagmi';
|
||||
import dynamic from "next/dynamic";
|
||||
import { formatUnits } from "viem";
|
||||
import Counter from "./Counter";
|
||||
|
||||
const Header = () => {
|
||||
const { isConnected } = useAccount();
|
||||
const { isRegistered, register, balance, army } = usePlayer();
|
||||
const [count, setCount] = useState("0")
|
||||
|
||||
useEffect(() => {
|
||||
if (balance != null) {
|
||||
setCount(formatUnits(balance, 4))
|
||||
}
|
||||
}, [balance])
|
||||
const { isRegistered, register, army } = usePlayer();
|
||||
|
||||
const title = useMemo(() => {
|
||||
return isRegistered ? `SLAY THE MOLOCH` :
|
||||
|
||||
@ -1,9 +1,33 @@
|
||||
import { useEffect, useReducer, useRef } from 'react';
|
||||
import { usePlayer } from '../providers/PlayerProvider';
|
||||
import styles from '../styles/Background.module.css';
|
||||
|
||||
const onCooldown = (lastRaidedAt: bigint) => (
|
||||
((new Date()).getTime()
|
||||
- (parseInt(lastRaidedAt.toString()) * 1000 /* convert block time to seconds */))
|
||||
/ 1000 /* convert milliseconds back to seconds*/
|
||||
) <= 15
|
||||
|
||||
const emptyFn = () => { }
|
||||
|
||||
const Tower = () => {
|
||||
const { raid } = usePlayer();
|
||||
return <div onClick={raid} className={`${styles.tower} ${styles.background_asset}`} />
|
||||
const { raid, player } = usePlayer();
|
||||
const isOnCooldown = useRef(false);
|
||||
const [, render] = useReducer(p => !p, false);
|
||||
|
||||
useEffect(() => {
|
||||
const checkCooldownInterval = setInterval(() => {
|
||||
isOnCooldown.current = onCooldown(player?.last_raided_at ?? BigInt(0))
|
||||
render()
|
||||
}, 1000);
|
||||
return () => clearInterval(checkCooldownInterval)
|
||||
}, [player?.last_raided_at])
|
||||
|
||||
return <div onClick={isOnCooldown.current ? emptyFn : raid} className={`
|
||||
${styles.tower}
|
||||
${styles.background_asset}
|
||||
${isOnCooldown.current ? styles.cooldown : ""}
|
||||
`} />
|
||||
}
|
||||
|
||||
export default Tower
|
||||
|
||||
@ -117,8 +117,6 @@ const PlayerProvider = ({ children }: { children: ReactNode }) => {
|
||||
})
|
||||
}, [writeContract])
|
||||
|
||||
console.log(player, army)
|
||||
|
||||
return (
|
||||
<PlayerContext.Provider value={{
|
||||
isRegistered: isRegistered as boolean,
|
||||
|
||||
@ -64,6 +64,21 @@
|
||||
&:active {
|
||||
transform: scale(1.1, 1.22);
|
||||
}
|
||||
&.cooldown {
|
||||
transition: all 1s cubic-bezier(0.265, 1.4, 0.68, 1.65);
|
||||
transform: scale(1.1, 1.22);
|
||||
&::after {
|
||||
content: "RAID IN PROGRESS";
|
||||
color: var(--hover-color);
|
||||
top: calc(50% - 15px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
font-size: 0.9rem;
|
||||
text-align: center;
|
||||
animation: excited 0.5s infinite linear;
|
||||
text-shadow: #000 1px 1px 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tower::after {
|
||||
position: absolute;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
font-weight: 600;
|
||||
margin: 0.5rem 0 0.2rem;
|
||||
line-height: 2rem;
|
||||
color: var(--hover-color);
|
||||
}
|
||||
.counter_per_seconds {
|
||||
font-size: 1.2rem;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user