forked from mico/idle_moloch
mobile css and small display fixes
This commit is contained in:
parent
7ccc036b2d
commit
8e547576e0
@ -80,7 +80,7 @@ const unitAvailableToDiscoverAt: Record<UnitType, bigint> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface UnitProps {
|
interface UnitProps {
|
||||||
addUnit: (unitType: UnitType) => void;
|
addUnit: (unitType: UnitType, amount?: number) => void;
|
||||||
unitType: UnitType;
|
unitType: UnitType;
|
||||||
canPurchase: boolean;
|
canPurchase: boolean;
|
||||||
isShrouded: boolean;
|
isShrouded: boolean;
|
||||||
@ -92,19 +92,20 @@ const Unit = ({
|
|||||||
unitType,
|
unitType,
|
||||||
canPurchase,
|
canPurchase,
|
||||||
isShrouded,
|
isShrouded,
|
||||||
n_units,
|
n_units: unitLevel,
|
||||||
}: UnitProps) => {
|
}: UnitProps) => {
|
||||||
const [unitPrice, unitProfit] = useMemo(() => {
|
const [unitPrice, unitProfit] = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
toReadable(calculateUnitPrice(unitType, n_units, 1)),
|
toReadable(calculateUnitPrice(unitType, unitLevel, 1)),
|
||||||
toReadable(calculateProfitPerSecond(unitType, n_units)),
|
toReadable(calculateProfitPerSecond(unitType, unitLevel)),
|
||||||
];
|
];
|
||||||
}, [n_units, unitType]);
|
}, [unitLevel, unitType]);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={() => addUnit(unitType)}
|
onClick={() => addUnit(unitType, 10)}
|
||||||
className={`${styles.armyUnit} ${canPurchase ? "" : styles.isUnavailable
|
className={`${styles.armyUnit} ${
|
||||||
}`}
|
canPurchase ? "" : styles.isUnavailable
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`
|
className={`
|
||||||
@ -122,12 +123,12 @@ const Unit = ({
|
|||||||
{unitPrice} <small>GELD</small>
|
{unitPrice} <small>GELD</small>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{n_units > 0 ? (
|
{unitLevel > 0 ? (
|
||||||
<span className={`${styles.unitSupply} ${styles.uiElement}`}>
|
<span className={`${styles.unitSupply} ${styles.uiElement}`}>
|
||||||
{n_units}
|
{`lvl ${unitLevel}`}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
{n_units > 0 ? (
|
{unitLevel > 0 ? (
|
||||||
<span className={`${styles.unitProfit} ${styles.uiElement}`}>
|
<span className={`${styles.unitProfit} ${styles.uiElement}`}>
|
||||||
{unitProfit} <small>per sec</small>
|
{unitProfit} <small>per sec</small>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -16,25 +16,26 @@ export const calculateBalance = (balance: bigint, perSecond: bigint, lastRaidedA
|
|||||||
export const toReadable = (rawValue: bigint) => {
|
export const toReadable = (rawValue: bigint) => {
|
||||||
const value = rawValue / BigInt(10000);
|
const value = rawValue / BigInt(10000);
|
||||||
const suffixes = [
|
const suffixes = [
|
||||||
{ value: BigInt('1000'), suffix: 'thousand' },
|
{ value: BigInt('1000'), suffix: 'k' }, // Thousand
|
||||||
{ value: BigInt('1000000'), suffix: 'million' },
|
{ value: BigInt('1000000'), suffix: 'M' }, // Million
|
||||||
{ value: BigInt('1000000000'), suffix: 'billion' },
|
{ value: BigInt('1000000000'), suffix: 'B' }, // Billion
|
||||||
{ value: BigInt('1000000000000'), suffix: 'trillion' },
|
{ value: BigInt('1000000000000'), suffix: 'T' }, // Trillion
|
||||||
{ value: BigInt('1000000000000000'), suffix: 'quadrillion' },
|
{ value: BigInt('1000000000000000'), suffix: 'Qd' }, // Quadrillion
|
||||||
{ value: BigInt('1000000000000000000'), suffix: 'quintillion' },
|
{ value: BigInt('1000000000000000000'), suffix: 'Qi' }, // Quintillion
|
||||||
{ value: BigInt('1000000000000000000000'), suffix: 'sextillion' },
|
{ value: BigInt('1000000000000000000000'), suffix: 'Sx' }, // Sextillion
|
||||||
{ value: BigInt('1000000000000000000000000'), suffix: 'septillion' },
|
{ value: BigInt('1000000000000000000000000'), suffix: 'Sp' }, // Septillion
|
||||||
{ value: BigInt('1000000000000000000000000000'), suffix: 'octillion' },
|
{ value: BigInt('1000000000000000000000000000'), suffix: 'Oc' }, // Octillion
|
||||||
{ value: BigInt('1000000000000000000000000000000'), suffix: 'nonillion' },
|
{ value: BigInt('1000000000000000000000000000000'), suffix: 'No' }, // Nonillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000'), suffix: 'decillion' },
|
{ value: BigInt('1000000000000000000000000000000000'), suffix: 'Dc' }, // Decillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000'), suffix: 'undecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000'), suffix: 'Ud' }, // Undecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000'), suffix: 'duodecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000'), suffix: 'Dd' }, // Duodecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000000'), suffix: 'tredecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000000'), suffix: 'Td' }, // Tredecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000000000'), suffix: 'quattuordecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000000000'), suffix: 'Qt' }, // Quattuordecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000000000000'), suffix: 'quindecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000000000000'), suffix: 'Qn' }, // Quindecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000000000000000'), suffix: 'sexdecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000'), suffix: 'Sd' }, // Sexdecillion
|
||||||
{ value: BigInt('1000000000000000000000000000000000000000000000000000000'), suffix: 'septendecillion' },
|
{ value: BigInt('1000000000000000000000000000000000000000000000000000000'), suffix: 'St' }, // Septendecillion
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
for (let i = 0; i < suffixes.length; i++) {
|
for (let i = 0; i < suffixes.length; i++) {
|
||||||
if (value < suffixes[i].value) {
|
if (value < suffixes[i].value) {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import React, { useCallback, useMemo } from "react"
|
import React, { useCallback, useMemo } from "react";
|
||||||
import styles from "../styles/Header.module.css"
|
import styles from "../styles/Header.module.css";
|
||||||
import bgStyles from "../styles/Background.module.css"
|
import bgStyles from "../styles/Background.module.css";
|
||||||
import { usePlayer } from "../providers/PlayerProvider";
|
import { usePlayer } from "../providers/PlayerProvider";
|
||||||
import { useAccount } from 'wagmi';
|
import { useAccount } from "wagmi";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import Counter, { toReadable } from "./Counter";
|
import Counter, { toReadable } from "./Counter";
|
||||||
import { useModal } from "../providers/ModalProvider";
|
import { useModal } from "../providers/ModalProvider";
|
||||||
@ -13,38 +13,56 @@ const Header = () => {
|
|||||||
const { openRegistrationModal } = useModal();
|
const { openRegistrationModal } = useModal();
|
||||||
|
|
||||||
const title = useMemo(() => {
|
const title = useMemo(() => {
|
||||||
return isRegistered && !player?.has_active_session ? `You died 😇 Click here to start again and ...` :
|
return isRegistered && !player?.has_active_session
|
||||||
isRegistered ? `SLAY THE MOLOCH` :
|
? `You died 😇 Click here to start again and ...`
|
||||||
!isConnected ? "Connect your wallet traveler ☝️ and then ..." :
|
: isRegistered
|
||||||
"Click here to start 😈"
|
? `SLAY THE MOLOCH`
|
||||||
}, [isConnected, isRegistered, player?.has_active_session])
|
: !isConnected
|
||||||
|
? "Connect your wallet traveler ☝️ and then ..."
|
||||||
|
: "Click here to start 😈";
|
||||||
|
}, [isConnected, isRegistered, player?.has_active_session]);
|
||||||
|
|
||||||
const subtitle = useMemo(() => {
|
const subtitle = useMemo(() => {
|
||||||
if (isRegistered && player?.has_active_session) {
|
if (isRegistered && player?.has_active_session) {
|
||||||
return <Counter />
|
return <Counter />;
|
||||||
} else {
|
} else {
|
||||||
return <p className={`${styles.counter} ${isConnected && !player?.has_active_session ? bgStyles.excited : ""}`}>SLAY THE MOLOCH</p>
|
return (
|
||||||
|
<p
|
||||||
|
className={`${styles.counter} ${
|
||||||
|
isConnected && !player?.has_active_session ? bgStyles.excited : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
SLAY THE MOLOCH
|
||||||
|
</p>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [isRegistered, player?.has_active_session, isConnected])
|
}, [isRegistered, player?.has_active_session, isConnected]);
|
||||||
|
|
||||||
const perSecondParagraph = useMemo(() => {
|
const perSecondParagraph = useMemo(() => {
|
||||||
const perSecond = toReadable(army?.profit_per_second ?? BigInt(0))
|
const perSecond = toReadable(army?.profit_per_second ?? BigInt(0));
|
||||||
return (isRegistered && player?.has_active_session) ?
|
return isRegistered && player?.has_active_session ? (
|
||||||
<p className={styles.counter_per_seconds}>per second: {perSecond}</p>
|
<p className={styles.counter_per_seconds}>per second: {perSecond}</p>
|
||||||
: null
|
) : null;
|
||||||
}, [isRegistered, army?.profit_per_second, player?.has_active_session])
|
}, [isRegistered, army?.profit_per_second, player?.has_active_session]);
|
||||||
|
|
||||||
const onRegister = useCallback(() => {
|
const onRegister = useCallback(() => {
|
||||||
if (player?.has_active_session) return
|
if (player?.has_active_session) return;
|
||||||
openRegistrationModal()
|
openRegistrationModal();
|
||||||
}, [player?.has_active_session, openRegistrationModal])
|
}, [player?.has_active_session, openRegistrationModal]);
|
||||||
|
|
||||||
return <header onClick={onRegister} className={`${styles.header} ${isConnected && !player?.has_active_session ? styles.clickable : ""}`}>
|
return (
|
||||||
<h1 className={`${styles.title}`}>{title}</h1>
|
<header
|
||||||
{subtitle}
|
onClick={onRegister}
|
||||||
{perSecondParagraph}
|
className={`${styles.header} ${
|
||||||
</header>
|
isConnected && !player?.has_active_session ? styles.clickable : ""
|
||||||
}
|
}`}
|
||||||
|
>
|
||||||
|
<h1 className={`${styles.title}`}>{title}</h1>
|
||||||
|
{subtitle}
|
||||||
|
{perSecondParagraph}
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// export default Header
|
// export default Header
|
||||||
|
|
||||||
|
|||||||
@ -151,7 +151,9 @@ const EARLY_GAME_QUOTES = [
|
|||||||
function PixelatedQuote() {
|
function PixelatedQuote() {
|
||||||
const { player } = usePlayer();
|
const { player } = usePlayer();
|
||||||
const [isShown, setIsShown] = useState(true);
|
const [isShown, setIsShown] = useState(true);
|
||||||
const [currentQuote, setCurrentQuote] = useState("Welcome to the Dark Forest!");
|
const [currentQuote, setCurrentQuote] = useState(
|
||||||
|
"Welcome to the Dark Forest!"
|
||||||
|
);
|
||||||
const intervalIdRef = useRef<NodeJS.Timeout | null>(null);
|
const intervalIdRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
const hasShownWelcome = useRef(false);
|
const hasShownWelcome = useRef(false);
|
||||||
|
|
||||||
@ -185,7 +187,9 @@ function PixelatedQuote() {
|
|||||||
} else if (totalMinted < PROGRESSION_TIERS.BEGINNER) {
|
} else if (totalMinted < PROGRESSION_TIERS.BEGINNER) {
|
||||||
// Show early game quotes until player reaches beginner level
|
// Show early game quotes until player reaches beginner level
|
||||||
setCurrentQuote(
|
setCurrentQuote(
|
||||||
EARLY_GAME_QUOTES[Math.floor(Math.random() * EARLY_GAME_QUOTES.length)]
|
EARLY_GAME_QUOTES[
|
||||||
|
Math.floor(Math.random() * EARLY_GAME_QUOTES.length)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const tier = getQuoteTier(totalMinted);
|
const tier = getQuoteTier(totalMinted);
|
||||||
@ -198,8 +202,8 @@ function PixelatedQuote() {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setIsShown(false);
|
setIsShown(false);
|
||||||
}, 4000);
|
}, 5000);
|
||||||
}, 6000);
|
}, 10000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (intervalIdRef.current !== null) {
|
if (intervalIdRef.current !== null) {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useState } from "react"
|
import React, { useCallback, useState } from "react";
|
||||||
import styles from '../styles/Background.module.css';
|
import styles from "../styles/Background.module.css";
|
||||||
import Tower from "./Tower";
|
import Tower from "./Tower";
|
||||||
import Army from "./Army";
|
import Army from "./Army";
|
||||||
import MarchingBand from "./MarchingBand";
|
import MarchingBand from "./MarchingBand";
|
||||||
@ -17,53 +17,60 @@ const bossToMountainsClass = {
|
|||||||
4: styles.mountains4,
|
4: styles.mountains4,
|
||||||
5: styles.mountains5,
|
5: styles.mountains5,
|
||||||
6: styles.mountains6,
|
6: styles.mountains6,
|
||||||
}
|
};
|
||||||
|
|
||||||
const Scene = () => {
|
const Scene = () => {
|
||||||
const { isRegistered, boss, player } = usePlayer();
|
const { isRegistered, boss, player } = usePlayer();
|
||||||
const [isLeaderboardOpen, setIsLeaderboardOpen] = useState(false);
|
const [isLeaderboardOpen, setIsLeaderboardOpen] = useState(false);
|
||||||
|
|
||||||
const handleMusicReady = useCallback((unmute: () => void) => {
|
const handleMusicReady = useCallback(
|
||||||
if (isRegistered) {
|
(unmute: () => void) => {
|
||||||
unmute();
|
if (isRegistered) {
|
||||||
}
|
unmute();
|
||||||
}, [isRegistered]);
|
}
|
||||||
|
},
|
||||||
|
[isRegistered]
|
||||||
|
);
|
||||||
const variant = boss?.variants[boss.level] || 0;
|
const variant = boss?.variants[boss.level] || 0;
|
||||||
|
|
||||||
return <div className={styles.frame}>
|
return (
|
||||||
<div className={`${styles.air} ${styles.background_asset}`} />
|
<div className={styles.frame}>
|
||||||
<div className={`${styles.clouds_large} ${styles.background_asset}`} />
|
<div className={`${styles.air} ${styles.background_asset}`} />
|
||||||
<Boss />
|
<div className={`${styles.clouds_large} ${styles.background_asset}`} />
|
||||||
<Tower />
|
<Boss />
|
||||||
<div className={`${styles.clouds_small} ${styles.background_asset}`} />
|
<Tower />
|
||||||
<div className={`${styles.mountains} ${styles.background_asset} ${bossToMountainsClass[variant]}`} />
|
<div className={`${styles.clouds_small} ${styles.background_asset}`} />
|
||||||
<div className={`${styles.village} ${styles.background_asset}`} />
|
<div
|
||||||
{isRegistered && player?.has_active_session && <BossInfo />}
|
className={`${styles.mountains} ${styles.background_asset} ${bossToMountainsClass[variant]}`}
|
||||||
<MarchingBand />
|
/>
|
||||||
<div className={`${styles.bonfire} ${styles.background_asset}`} />
|
<div className={`${styles.village} ${styles.background_asset}`} />
|
||||||
<Army />
|
{isRegistered && player?.has_active_session && <BossInfo />}
|
||||||
<MusicPlayer onReady={handleMusicReady} />
|
<MarchingBand />
|
||||||
<button
|
<div className={`${styles.bonfire} ${styles.background_asset}`} />
|
||||||
onClick={() => setIsLeaderboardOpen(true)}
|
<Army />
|
||||||
className={styles.leaderboardButton}
|
<MusicPlayer onReady={handleMusicReady} />
|
||||||
title="Leaderboard"
|
<button
|
||||||
>
|
onClick={() => setIsLeaderboardOpen(true)}
|
||||||
📜
|
className={styles.leaderboardButton}
|
||||||
</button>
|
title="Leaderboard"
|
||||||
{isLeaderboardOpen && (
|
>
|
||||||
<div className={styles.leaderboardOverlay}>
|
🏆
|
||||||
<div className={styles.leaderboardContent}>
|
</button>
|
||||||
<button
|
{isLeaderboardOpen && (
|
||||||
className={styles.closeButton}
|
<div className={styles.leaderboardOverlay}>
|
||||||
onClick={() => setIsLeaderboardOpen(false)}
|
<div className={styles.leaderboardContent}>
|
||||||
>
|
<button
|
||||||
×
|
className={styles.closeButton}
|
||||||
</button>
|
onClick={() => setIsLeaderboardOpen(false)}
|
||||||
<Leaderboard />
|
>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<Leaderboard />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Scene
|
export default Scene;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { ConnectButton } from '@rainbow-me/rainbowkit';
|
import { ConnectButton } from "@rainbow-me/rainbowkit";
|
||||||
import type { NextPage } from 'next';
|
import type { NextPage } from "next";
|
||||||
import Head from 'next/head';
|
import Head from "next/head";
|
||||||
import styles from '../styles/Home.module.css';
|
import styles from "../styles/Home.module.css";
|
||||||
import Header from '../components/Header';
|
import Header from "../components/Header";
|
||||||
import Scene from '../components/Scene';
|
import Scene from "../components/Scene";
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
return (
|
return (
|
||||||
@ -26,7 +26,10 @@ const Home: NextPage = () => {
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer className={styles.footer}>
|
<footer className={styles.footer}>
|
||||||
Made with ❤️ by your frens at 😈 Slay the Moloch team for Cohort VII of <a href="https://www.raidguild.org/" target="blank">RaidGuild</a>
|
Made with ❤️ by your frens at 😈 Slay the Moloch team for Cohort VII of{" "}
|
||||||
|
<a href="https://www.raidguild.org/" target="blank">
|
||||||
|
RaidGuild
|
||||||
|
</a>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,48 +1,63 @@
|
|||||||
import React, { createContext, ReactNode, useCallback, useContext, useEffect, useState } from 'react'
|
import React, {
|
||||||
import { useAccount, useReadContract, useWriteContract } from 'wagmi'
|
createContext,
|
||||||
import contractAbi from "../../../out/RaidGeld.sol/RaidGeld.json"
|
ReactNode,
|
||||||
import { Hash, parseEther } from 'viem'
|
useCallback,
|
||||||
import contracts from '../../contract_address'
|
useContext,
|
||||||
import WaitingForTxModal from '../components/WaitingForTxModal'
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import { useAccount, useReadContract, useWriteContract } from "wagmi";
|
||||||
|
import contractAbi from "../../../out/RaidGeld.sol/RaidGeld.json";
|
||||||
|
import { Hash, parseEther } from "viem";
|
||||||
|
import contracts from "../../contract_address";
|
||||||
|
import WaitingForTxModal from "../components/WaitingForTxModal";
|
||||||
|
|
||||||
const { contractAddress, daoTokenAddress } = contracts
|
const { contractAddress, daoTokenAddress } = contracts;
|
||||||
const abi = contractAbi.abi
|
const abi = contractAbi.abi;
|
||||||
|
|
||||||
export type UnitType = 0 | 1 | 2 | 3
|
export type UnitType = 0 | 1 | 2 | 3;
|
||||||
export type BossLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6
|
export type BossLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||||
|
|
||||||
export interface Player {
|
export interface Player {
|
||||||
created_at: bigint,
|
created_at: bigint;
|
||||||
last_raided_at: bigint,
|
last_raided_at: bigint;
|
||||||
total_minted: bigint
|
total_minted: bigint;
|
||||||
total_rewards: bigint,
|
total_rewards: bigint;
|
||||||
n_runs: number,
|
n_runs: number;
|
||||||
prestige_level: number,
|
prestige_level: number;
|
||||||
is_registered: boolean,
|
is_registered: boolean;
|
||||||
has_active_session: boolean,
|
has_active_session: boolean;
|
||||||
}
|
}
|
||||||
export interface Army {
|
export interface Army {
|
||||||
anointed: { level: number }
|
anointed: { level: number };
|
||||||
apprentice: { level: number }
|
apprentice: { level: number };
|
||||||
champion: { level: number }
|
champion: { level: number };
|
||||||
moloch_denier: { level: number }
|
moloch_denier: { level: number };
|
||||||
profit_per_second: bigint
|
profit_per_second: bigint;
|
||||||
}
|
}
|
||||||
export interface Boss {
|
export interface Boss {
|
||||||
level: BossLevel;
|
level: BossLevel;
|
||||||
variants: [BossLevel, BossLevel, BossLevel, BossLevel, BossLevel, BossLevel, BossLevel]
|
variants: [
|
||||||
|
BossLevel,
|
||||||
|
BossLevel,
|
||||||
|
BossLevel,
|
||||||
|
BossLevel,
|
||||||
|
BossLevel,
|
||||||
|
BossLevel,
|
||||||
|
BossLevel
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PlayerContextType {
|
export interface PlayerContextType {
|
||||||
isRegistered: boolean,
|
isRegistered: boolean;
|
||||||
player: null | Player,
|
player: null | Player;
|
||||||
army: null | Army,
|
army: null | Army;
|
||||||
boss: null | Boss,
|
boss: null | Boss;
|
||||||
balance: bigint,
|
balance: bigint;
|
||||||
register: (arg: "ETH" | "RGCVII") => void,
|
register: (arg: "ETH" | "RGCVII") => void;
|
||||||
raid: () => void,
|
raid: () => void;
|
||||||
battleWithBoss: () => void;
|
battleWithBoss: () => void;
|
||||||
addUnit: (unit: UnitType) => void
|
addUnit: (unit: UnitType, amount?: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlayerContext = createContext<PlayerContextType>({
|
const PlayerContext = createContext<PlayerContextType>({
|
||||||
@ -51,169 +66,191 @@ const PlayerContext = createContext<PlayerContextType>({
|
|||||||
army: null,
|
army: null,
|
||||||
boss: null,
|
boss: null,
|
||||||
balance: BigInt(0),
|
balance: BigInt(0),
|
||||||
register: () => { },
|
register: () => {},
|
||||||
raid: () => { },
|
raid: () => {},
|
||||||
battleWithBoss: () => { },
|
battleWithBoss: () => {},
|
||||||
addUnit: () => { }
|
addUnit: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const PlayerProvider = ({ children }: { children: ReactNode }) => {
|
const PlayerProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const { address, isConnected } = useAccount();
|
const { address, isConnected } = useAccount();
|
||||||
const { writeContract, error } = useWriteContract();
|
const { writeContract, error } = useWriteContract();
|
||||||
const [[txHash, callbackFn], setHashAndCallback] = useState<[Hash | null, () => void]>([null, () => { }])
|
const [[txHash, callbackFn], setHashAndCallback] = useState<
|
||||||
|
[Hash | null, () => void]
|
||||||
|
>([null, () => {}]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.warn(error)
|
console.error(error?.message);
|
||||||
}, [error])
|
}, [error]);
|
||||||
|
|
||||||
const resetHashAndCallback = useCallback(() => {
|
const resetHashAndCallback = useCallback(() => {
|
||||||
setHashAndCallback([null, () => { }])
|
setHashAndCallback([null, () => {}]);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const { data: isRegistered } = useReadContract({
|
const { data: isRegistered } = useReadContract({
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
abi,
|
abi,
|
||||||
functionName: 'isRegistered',
|
functionName: "isRegistered",
|
||||||
args: [address],
|
args: [address],
|
||||||
query: {
|
query: {
|
||||||
enabled: isConnected,
|
enabled: isConnected,
|
||||||
refetchInterval: 15,
|
refetchInterval: 15,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: balance, } = useReadContract({
|
const { data: balance } = useReadContract({
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
abi,
|
abi,
|
||||||
functionName: 'balanceOf',
|
functionName: "balanceOf",
|
||||||
args: [address],
|
args: [address],
|
||||||
query: {
|
query: {
|
||||||
refetchInterval: 15,
|
refetchInterval: 15,
|
||||||
enabled: isConnected
|
enabled: isConnected,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: player } = useReadContract({
|
const { data: player } = useReadContract({
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
abi,
|
abi,
|
||||||
functionName: 'getPlayer',
|
functionName: "getPlayer",
|
||||||
args: [address],
|
args: [address],
|
||||||
query: {
|
query: {
|
||||||
enabled: isConnected,
|
enabled: isConnected,
|
||||||
refetchInterval: 15
|
refetchInterval: 15,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: army } = useReadContract({
|
const { data: army } = useReadContract({
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
abi,
|
abi,
|
||||||
functionName: 'getArmy',
|
functionName: "getArmy",
|
||||||
args: [address],
|
args: [address],
|
||||||
query: {
|
query: {
|
||||||
enabled: isConnected,
|
enabled: isConnected,
|
||||||
refetchInterval: 15
|
refetchInterval: 15,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: boss } = useReadContract({
|
const { data: boss } = useReadContract({
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
abi,
|
abi,
|
||||||
functionName: 'getBoss',
|
functionName: "getBoss",
|
||||||
args: [address],
|
args: [address],
|
||||||
query: {
|
query: {
|
||||||
enabled: isConnected,
|
enabled: isConnected,
|
||||||
refetchInterval: 15
|
refetchInterval: 15,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(balance, player, army, boss)
|
console.log(balance, player, army, boss);
|
||||||
|
|
||||||
const register = useCallback((arg: "RGCVII" | "ETH") => {
|
const register = useCallback(
|
||||||
if (arg === 'ETH') {
|
(arg: "RGCVII" | "ETH") => {
|
||||||
|
if (arg === "ETH") {
|
||||||
|
writeContract(
|
||||||
|
{
|
||||||
|
abi,
|
||||||
|
address: contractAddress,
|
||||||
|
functionName: "register_eth",
|
||||||
|
value: parseEther("0.0005"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (hash) => {
|
||||||
|
setHashAndCallback([hash, resetHashAndCallback]);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else if (arg === "RGCVII") {
|
||||||
|
writeContract(
|
||||||
|
{
|
||||||
|
abi,
|
||||||
|
address: daoTokenAddress,
|
||||||
|
functionName: "approve",
|
||||||
|
args: [contractAddress, parseEther("500")],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (hash) => {
|
||||||
|
setHashAndCallback([
|
||||||
|
hash,
|
||||||
|
() =>
|
||||||
|
writeContract(
|
||||||
|
{
|
||||||
|
abi,
|
||||||
|
address: contractAddress,
|
||||||
|
functionName: "register_dao",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (hash) => {
|
||||||
|
setHashAndCallback([hash, resetHashAndCallback]);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[writeContract, resetHashAndCallback]
|
||||||
|
);
|
||||||
|
|
||||||
|
const raid = useCallback(() => {
|
||||||
|
writeContract(
|
||||||
|
{
|
||||||
|
abi,
|
||||||
|
address: contractAddress,
|
||||||
|
functionName: "raid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onSuccess: (hash) => {
|
||||||
|
setHashAndCallback([hash, resetHashAndCallback]);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [writeContract, resetHashAndCallback]);
|
||||||
|
|
||||||
|
const addUnit = useCallback(
|
||||||
|
(unit: UnitType, amount: number = 1) => {
|
||||||
writeContract({
|
writeContract({
|
||||||
abi,
|
abi,
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
functionName: 'register_eth',
|
functionName: "addUnit",
|
||||||
value: parseEther("0.0005"),
|
args: [unit, amount],
|
||||||
}, {
|
|
||||||
onSuccess: (hash) => {
|
|
||||||
setHashAndCallback([hash, resetHashAndCallback])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (arg === "RGCVII") {
|
|
||||||
writeContract({
|
|
||||||
abi,
|
|
||||||
address: daoTokenAddress,
|
|
||||||
functionName: 'approve',
|
|
||||||
args: [contractAddress, parseEther("500")],
|
|
||||||
}, {
|
|
||||||
onSuccess: (hash) => {
|
|
||||||
setHashAndCallback([
|
|
||||||
hash,
|
|
||||||
() => writeContract({
|
|
||||||
abi,
|
|
||||||
address: contractAddress,
|
|
||||||
functionName: 'register_dao',
|
|
||||||
}, {
|
|
||||||
onSuccess: (hash) => {
|
|
||||||
setHashAndCallback([hash, resetHashAndCallback])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
])
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}, [writeContract, resetHashAndCallback])
|
[writeContract]
|
||||||
|
);
|
||||||
const raid = useCallback(() => {
|
|
||||||
writeContract({
|
|
||||||
abi,
|
|
||||||
address: contractAddress,
|
|
||||||
functionName: 'raid',
|
|
||||||
}, {
|
|
||||||
onSuccess: (hash) => {
|
|
||||||
setHashAndCallback([hash, resetHashAndCallback])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [writeContract, resetHashAndCallback])
|
|
||||||
|
|
||||||
const addUnit = useCallback((unit: UnitType) => {
|
|
||||||
writeContract({
|
|
||||||
abi,
|
|
||||||
address: contractAddress,
|
|
||||||
functionName: 'addUnit',
|
|
||||||
args: [unit, 1]
|
|
||||||
})
|
|
||||||
}, [writeContract])
|
|
||||||
|
|
||||||
const battleWithBoss = useCallback(() => {
|
const battleWithBoss = useCallback(() => {
|
||||||
writeContract({
|
writeContract({
|
||||||
abi,
|
abi,
|
||||||
address: contractAddress,
|
address: contractAddress,
|
||||||
functionName: 'battle_with_boss',
|
functionName: "battle_with_boss",
|
||||||
})
|
});
|
||||||
}, [writeContract])
|
}, [writeContract]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PlayerContext.Provider value={{
|
<PlayerContext.Provider
|
||||||
isRegistered: isRegistered as boolean,
|
value={{
|
||||||
player: player as Player,
|
isRegistered: isRegistered as boolean,
|
||||||
army: army as Army,
|
player: player as Player,
|
||||||
boss: boss as Boss,
|
army: army as Army,
|
||||||
balance: balance as bigint,
|
boss: boss as Boss,
|
||||||
register,
|
balance: balance as bigint,
|
||||||
raid,
|
register,
|
||||||
addUnit,
|
raid,
|
||||||
battleWithBoss
|
addUnit,
|
||||||
}}>
|
battleWithBoss,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
{txHash && <WaitingForTxModal hash={txHash} callbackFn={callbackFn} />}
|
{txHash && <WaitingForTxModal hash={txHash} callbackFn={callbackFn} />}
|
||||||
</PlayerContext.Provider>
|
</PlayerContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const usePlayer = () => {
|
export const usePlayer = () => {
|
||||||
return useContext(PlayerContext);
|
return useContext(PlayerContext);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default PlayerProvider
|
|
||||||
|
|
||||||
|
export default PlayerProvider;
|
||||||
|
|||||||
@ -130,8 +130,17 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
left: 10px;
|
||||||
|
bottom: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.armyUnit {
|
.armyUnit {
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
transform: scale(0.75);
|
||||||
|
}
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 120px;
|
width: 120px;
|
||||||
@ -152,6 +161,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.uiElement {
|
.uiElement {
|
||||||
|
width: fit-content;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: rgba(0, 0, 0, 0.89);
|
background: rgba(0, 0, 0, 0.89);
|
||||||
@ -161,18 +171,22 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.unitSupply {
|
.unitSupply {
|
||||||
top: 0;
|
top: -30px;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
left: 2rem;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.unitName {
|
.unitName {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 45px;
|
bottom: 45px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.unitPrice {
|
.unitPrice {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 25px;
|
bottom: 25px;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.unitProfit {
|
.unitProfit {
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -201,18 +215,24 @@
|
|||||||
height: 90px;
|
height: 90px;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
.pixelQuote {
|
.pixelQuote {
|
||||||
min-width: 150px;
|
min-width: 200px;
|
||||||
|
width: fit-content;
|
||||||
|
max-width: 300px;
|
||||||
color: black;
|
color: black;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
|
line-height: 0.9rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5.5rem;
|
bottom: 5.5rem;
|
||||||
left: -20px;
|
left: -70px;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 0.7rem;
|
padding: 0.7rem;
|
||||||
line-height: 0.8rem;
|
|
||||||
transition: opacity 1s ease-in-out;
|
transition: opacity 1s ease-in-out;
|
||||||
box-shadow: 0px 5px 10px 5px rgba(0, 0, 0, 0.4);
|
box-shadow: 0px 5px 10px 5px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
right: 60px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.static.moloch_denier {
|
.static.moloch_denier {
|
||||||
background-image: url("/roles/scribe2.png");
|
background-image: url("/roles/scribe2.png");
|
||||||
@ -257,6 +277,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
@keyframes marching {
|
||||||
|
0% {
|
||||||
|
transform: translate(-54px, -59px); /* -100px scaled to ~-54px */
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
/* approaches fire */
|
||||||
|
transform: translate(15px, -100px); /* 72px scaled to ~39px */
|
||||||
|
}
|
||||||
|
15% {
|
||||||
|
/* approaches road */
|
||||||
|
transform: translate(82px, -123px); /* 152px scaled to ~82px */
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
/* first road turn */
|
||||||
|
transform: translate(66px, -200px); /* 122px scaled to ~66px */
|
||||||
|
}
|
||||||
|
45% {
|
||||||
|
/* second road turn */
|
||||||
|
transform: translate(138px, -264px); /* 256px scaled to ~138px */
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
/* third road turn */
|
||||||
|
transform: translate(86px, -293px); /* 159px scaled to ~86px */
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
/* vanishes into distance */
|
||||||
|
transform: translate(97px, -300px); /* 180px scaled to ~97px */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@keyframes marchingPerson {
|
@keyframes marchingPerson {
|
||||||
0% {
|
0% {
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
|
|||||||
@ -6,6 +6,12 @@
|
|||||||
border-image: url("/background/frame.png") 22 fill / auto space;
|
border-image: url("/background/frame.png") 22 fill / auto space;
|
||||||
width: 720px;
|
width: 720px;
|
||||||
height: 960px;
|
height: 960px;
|
||||||
|
|
||||||
|
max-height: 90vh;
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
max-width: 100vw;
|
||||||
|
max-height: 90vh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.background_asset {
|
.background_asset {
|
||||||
@ -34,7 +40,7 @@
|
|||||||
height: 150px;
|
height: 150px;
|
||||||
background-image: url("/background/clouds_large.png");
|
background-image: url("/background/clouds_large.png");
|
||||||
animation:
|
animation:
|
||||||
scrollBackground 80s linear infinite,
|
scrollBackground 280s linear infinite,
|
||||||
thunder 4s linear infinite;
|
thunder 4s linear infinite;
|
||||||
}
|
}
|
||||||
.clouds_small {
|
.clouds_small {
|
||||||
@ -42,7 +48,7 @@
|
|||||||
height: 82px;
|
height: 82px;
|
||||||
background-image: url("/background/clouds_small.png");
|
background-image: url("/background/clouds_small.png");
|
||||||
animation:
|
animation:
|
||||||
scrollBackground 20s linear infinite,
|
scrollBackground 200s linear infinite,
|
||||||
thunder 12s linear infinite;
|
thunder 12s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,6 +221,11 @@
|
|||||||
background-image: url("/background/village.png");
|
background-image: url("/background/village.png");
|
||||||
height: 540px;
|
height: 540px;
|
||||||
bottom: 22px;
|
bottom: 22px;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
height: 300px;
|
||||||
|
bottom: 80px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.bonfire {
|
.bonfire {
|
||||||
background-image: url("/background/bonfire.png");
|
background-image: url("/background/bonfire.png");
|
||||||
@ -226,6 +237,12 @@
|
|||||||
animation:
|
animation:
|
||||||
bonfire 12s linear infinite,
|
bonfire 12s linear infinite,
|
||||||
bonfire_skew 5s infinite linear;
|
bonfire_skew 5s infinite linear;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
left: 80px;
|
||||||
|
bottom: 105px;
|
||||||
|
scale: .7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.musicButton {
|
.musicButton {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@ -5,10 +5,18 @@
|
|||||||
&.clickable {
|
&.clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.counter {
|
.counter {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
|
|||||||
@ -16,14 +16,14 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 720px;
|
max-width: 720px;
|
||||||
height: 100vh;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
|
||||||
|
height: 90vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 2rem;
|
padding: 0;
|
||||||
padding: 2rem 0;
|
margin-top: 10px;
|
||||||
border-top: 1px solid #eaeaea;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 3291252c866ad698f6a55ec660259e49a67eb3d0
|
Subproject commit 448efeea6640bbbc09373f03fbc9c88e280147ba
|
||||||
Loading…
Reference in New Issue
Block a user