1
0
forked from mico/idle_moloch

Towers goes on cooldown during raiding

This commit is contained in:
mic0 2024-10-23 13:17:28 +02:00
parent 56e4b5ce26
commit cabfc5e758
Signed by: mico
GPG Key ID: A3F8023524CF1C8D
7 changed files with 98 additions and 23 deletions

View File

@ -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

View File

@ -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

View File

@ -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` :

View File

@ -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

View File

@ -117,8 +117,6 @@ const PlayerProvider = ({ children }: { children: ReactNode }) => {
})
}, [writeContract])
console.log(player, army)
return (
<PlayerContext.Provider value={{
isRegistered: isRegistered as boolean,

View File

@ -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;

View File

@ -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;