diff --git a/scripts/default_auth.sh b/scripts/default_auth.sh index 5729198c5..c5aeb3d81 100755 --- a/scripts/default_auth.sh +++ b/scripts/default_auth.sh @@ -4,6 +4,7 @@ pushd $(dirname "$0")/.. #export RPC_URL="http://localhost:5050"; export RPC_URL="https://api.cartridge.gg/x/rollyourown/katana"; + export WORLD_ADDRESS="0x3c3dfeb374720dfd73554dc2b9e0583cb9668efb3055d07d1533afa5d219fd5"; # enable system -> component authorizations diff --git a/src/constants.cairo b/src/constants.cairo index 814ea58f7..832c3aa98 100644 --- a/src/constants.cairo +++ b/src/constants.cairo @@ -3,7 +3,8 @@ const SCALING_FACTOR: u128 = 10_000; const TRAVEL_RISK: u8 = 30; // 30% chance of mugged const RUN_CHANCE: u8 = 50; // 50% chance of successfully getting away -const BASE_PAYMENT: u128 = 500_0000; // base payment is $500 + +const BASE_PAYMENT: u128 = 400_0000; // base payment is $400 // starting stats const STARTING_CASH: u128 = 4000_0000; // $4000 diff --git a/web/public/images/landing/step1.png b/web/public/images/landing/step1.png index 03dfb8623..682d5cf51 100644 Binary files a/web/public/images/landing/step1.png and b/web/public/images/landing/step1.png differ diff --git a/web/public/images/landing/step2.png b/web/public/images/landing/step2.png index 474c56442..8551240dd 100644 Binary files a/web/public/images/landing/step2.png and b/web/public/images/landing/step2.png differ diff --git a/web/public/images/landing/step3.png b/web/public/images/landing/step3.png index 746d51ec0..55bdb7ef3 100644 Binary files a/web/public/images/landing/step3.png and b/web/public/images/landing/step3.png differ diff --git a/web/public/images/landing/step4.png b/web/public/images/landing/step4.png index bfd14394e..d6b710290 100644 Binary files a/web/public/images/landing/step4.png and b/web/public/images/landing/step4.png differ diff --git a/web/public/images/tutorial/tuto1.png b/web/public/images/tutorial/tuto1.png new file mode 100644 index 000000000..6a1b96a4b Binary files /dev/null and b/web/public/images/tutorial/tuto1.png differ diff --git a/web/public/images/tutorial/tuto2.png b/web/public/images/tutorial/tuto2.png new file mode 100644 index 000000000..70e4854fa Binary files /dev/null and b/web/public/images/tutorial/tuto2.png differ diff --git a/web/public/images/tutorial/tuto3.png b/web/public/images/tutorial/tuto3.png new file mode 100644 index 000000000..4eff2492d Binary files /dev/null and b/web/public/images/tutorial/tuto3.png differ diff --git a/web/public/images/tutorial/tuto4.png b/web/public/images/tutorial/tuto4.png new file mode 100644 index 000000000..d042df4ad Binary files /dev/null and b/web/public/images/tutorial/tuto4.png differ diff --git a/web/public/sounds/Gang.mp3 b/web/public/sounds/Gang.mp3 new file mode 100644 index 000000000..22e30395f Binary files /dev/null and b/web/public/sounds/Gang.mp3 differ diff --git a/web/public/sounds/Police.mp3 b/web/public/sounds/Police.mp3 new file mode 100644 index 000000000..cfc002603 Binary files /dev/null and b/web/public/sounds/Police.mp3 differ diff --git a/web/src/components/Button.tsx b/web/src/components/Button.tsx index d48925859..7e40bae8f 100644 --- a/web/src/components/Button.tsx +++ b/web/src/components/Button.tsx @@ -11,8 +11,8 @@ import { playSound, Sounds } from "@/hooks/sound"; // so we do it here on text... const Button = ({ children, - hoverSound = Sounds.HoverClick, - clickSound = undefined, + hoverSound = undefined, + clickSound = Sounds.HoverClick, ...props }: { children: ReactNode } & { hoverSound?: Sounds | undefined } & { clickSound?: Sounds | undefined; diff --git a/web/src/components/Dot.tsx b/web/src/components/Dot.tsx new file mode 100644 index 000000000..c7f5d68f1 --- /dev/null +++ b/web/src/components/Dot.tsx @@ -0,0 +1,33 @@ +import { StyleProps, Box } from "@chakra-ui/react"; + +const Dot = ({ + active, + onClick, + ...props +}: { active: boolean; onClick: () => void } & StyleProps) => ( + + + {active ? ( + + ) : ( + + )} + + +); + +export default Dot; diff --git a/web/src/components/Header.tsx b/web/src/components/Header.tsx index 4152acce0..744f0f951 100644 --- a/web/src/components/Header.tsx +++ b/web/src/components/Header.tsx @@ -73,7 +73,7 @@ const Header = ({ back }: HeaderProps) => { { {!isMobile && ( <> - )} + {(!isMobile || (!account && isMobile)) && ( + + )} {isMobile && } diff --git a/web/src/components/HomeLeftPanel.tsx b/web/src/components/HomeLeftPanel.tsx new file mode 100644 index 000000000..1d1a91d8f --- /dev/null +++ b/web/src/components/HomeLeftPanel.tsx @@ -0,0 +1,233 @@ +import { + Text, + VStack, + HStack, + Divider, + Card, + Heading, + Image, + Box, + Link as ChakraLink, + keyframes, +} from "@chakra-ui/react"; +import Layout from "@/components/Layout"; +import Button from "@/components/Button"; +import { ScrollDown } from "@/components/icons/ScrollDown"; +import { Cartridge } from "@/components/icons/branding/Cartridge"; +import { Dojo } from "@/components/icons/branding/Dojo"; + +const floatAnim = keyframes` + 0% {transform: translateY(0%);} + 25% {transform: translateY(-6px);} + 50% {transform: translateY(0%);} + 70% {transform: translateY(8px);} +`; + +const steps = [ + { + step: 1, + title: "Buy Low", + desc: "A short description of this step, maybe one to two sentences. Here is one.", + }, + { + step: 2, + title: "Sell High", + desc: "A short description of this step, maybe one to two sentences. Here is one.", + }, + { + step: 3, + title: "???", + desc: "A short description of this step, maybe one to two sentences. Here is one.", + }, + { + step: 4, + title: "Profit", + desc: "A short description of this step, maybe one to two sentences. Here is one.", + }, +]; + +const HomeStep = ({ + step, +}: { + step: { step: number; title: string; desc: string }; +}) => { + return ( + <> + + {`step${step.step}`} + + + + {`step${step.step}`} + + + Step {step.step} + + + {step.title} + + + + {/* {step.desc} */} + + + + ); +}; + +const onScrollDown = () => { + let steps = document.getElementById("steps"); + + setTimeout(() => { + steps && + steps.scrollIntoView({ + behavior: "smooth", + block: "start", + inline: "nearest", + }); + }, 10); +}; + +const HomeLeftPanel = () => { + return ( + <> + + + + DOPE WARS + + + Roll your Own + + + + + context + + onScrollDown()} + animation={`${floatAnim} infinite 3s linear`} + cursor={"pointer"} + > + + + + + {steps.map((step) => { + return ; + })} + + + + + + BUILT BY + + + + | + + + BUILT WITH + + + + + + + + + + + ); +}; + +export default HomeLeftPanel; diff --git a/web/src/components/Toast.tsx b/web/src/components/Toast.tsx index 7b95f9883..145c3d79c 100644 --- a/web/src/components/Toast.tsx +++ b/web/src/components/Toast.tsx @@ -1,7 +1,7 @@ import { cardPixelatedStyle } from "@/theme/styles"; import { HStack, Link, Text } from "@chakra-ui/react"; import { ReactNode } from "react"; -import { Alert, ExternalLink } from "./icons"; +import { Alert, Close, ExternalLink } from "./icons"; export const Toast = ({ message, @@ -32,11 +32,12 @@ export const Toast = ({ {message} - {link && ( + + {/* {link && ( - )} + )} */} ); }; diff --git a/web/src/components/Tutorial.tsx b/web/src/components/Tutorial.tsx new file mode 100644 index 000000000..35291fe14 --- /dev/null +++ b/web/src/components/Tutorial.tsx @@ -0,0 +1,140 @@ +import { + Text, + VStack, + HStack, + Divider, + Card, + Heading, + Image, + Box, + Link as ChakraLink, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalFooter, +} from "@chakra-ui/react"; +import Layout from "@/components/Layout"; +import Button from "@/components/Button"; +import { useState, useEffect } from "react"; +import { playSound, Sounds } from "@/hooks/sound"; +import Dot from "./Dot"; + +const steps = [ + { + step: 1, + title: "GAME STATE", + desc: "Displays important details about the game", + }, + { + step: 2, + title: "BUYING PRODUCT", + desc: "Buy the ones you can flip for profit", + }, + { + step: 3, + title: "KEEP IT MOVING", + desc: "Different locations will offer different prices", + }, + { + step: 4, + title: "A WORD OF ADVICE", + desc: "The streets can be mean, Watch your back.", + }, +]; + + +const TutorialStep = ({ + step, +}: { + step: { step: number; title: string; desc: string }; +}) => { + return ( + <> + + + + {step.title} + + {step.desc} + + {`step${step.step}`} + + + ); +}; + +const Tutorial = ({ + isOpen, + close, +}: { + isOpen: boolean; + close: () => void; +}) => { + const [currentStep, setCurrentStep] = useState(1); + + const onNext = () => { + if (currentStep == steps.length) { + close(); + } else { + setCurrentStep(currentStep + 1); + } + }; + + useEffect(() => { + setCurrentStep(1); + }, [isOpen]); + + return ( + + + + + + {steps.map((step) => { + if (step.step !== currentStep) return null; + return ; + })} + + + + + + {steps.map((step) => { + return ( + setCurrentStep(step.step)} + /> + ); + })} + + + + + + + + ); +}; + +export default Tutorial; \ No newline at end of file diff --git a/web/src/hooks/sound.tsx b/web/src/hooks/sound.tsx index 91038935d..11ef341a0 100644 --- a/web/src/hooks/sound.tsx +++ b/web/src/hooks/sound.tsx @@ -16,6 +16,8 @@ export enum Sounds { HoverClick = "HoverClick.wav", Magnum357 = "Magnum357.mp3", Trade = "Trade.mp3", + Police = "Police.mp3", + Gang = "Gang.mp3", } export interface SoundState { diff --git a/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx b/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx index 6d50d2f75..e71b0230b 100644 --- a/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx +++ b/web/src/pages/[gameId]/[locationSlug]/[drugSlug]/[tradeDirection].tsx @@ -85,6 +85,9 @@ export default function Market() { const onTrade = useCallback(async () => { setIsSubmitting(true); playSound(Sounds.Trade); + + router.push(`/${gameId}/${location.slug}`); + let toastMessage = "", hash = "", quantity; @@ -106,7 +109,6 @@ export default function Market() { quantity, } as TradeType); - router.push(`/${gameId}/${location.slug}`); }, [ tradeDirection, quantityBuy, diff --git a/web/src/pages/[gameId]/end.tsx b/web/src/pages/[gameId]/end.tsx index 84453924b..c45eba20a 100644 --- a/web/src/pages/[gameId]/end.tsx +++ b/web/src/pages/[gameId]/end.tsx @@ -14,7 +14,17 @@ import { Image, Divider, Spacer, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalFooter, + UnorderedList, + ListItem, + Link, } from "@chakra-ui/react"; + import { motion } from "framer-motion"; import { useRouter } from "next/router"; import Button from "@/components/Button"; @@ -25,6 +35,7 @@ export default function End() { const gameId = router.query.gameId as string; const { setName: submitSetName, isPending } = useSystems(); const [name, setName] = useState(""); + const [isCreditOpen, setIsCreditOpen] = useState(false); const onSubmitName = useCallback(async () => { if (!name) return; @@ -32,6 +43,10 @@ export default function End() { router.push("/"); }, [name, gameId, router, submitSetName]); + const onCreditClose = useCallback(() => { + setIsCreditOpen(false); + }, [setIsCreditOpen]); + return ( <> - + + + ); diff --git a/web/src/pages/[gameId]/event/decision.tsx b/web/src/pages/[gameId]/event/decision.tsx index 2a20e1df5..d31afd196 100644 --- a/web/src/pages/[gameId]/event/decision.tsx +++ b/web/src/pages/[gameId]/event/decision.tsx @@ -12,6 +12,8 @@ import { useCallback, useEffect, useState } from "react"; import Layout from "@/components/Layout"; import { Footer } from "@/components/Footer"; import Button from "@/components/Button"; +import { playSound, Sounds } from "@/hooks/sound"; + const BASE_PAYMENT = 400; @@ -36,6 +38,15 @@ export default function Decision() { } }, [playerEntity]); + useEffect(() => { + if (status == PlayerStatus.BeingArrested) { + playSound(Sounds.Police); + } + if (status == PlayerStatus.BeingMugged) { + playSound(Sounds.Gang,0.69); + } + }, [status]); + const onDecision = useCallback( async (action: Action) => { setIsSubmitting(true); diff --git a/web/src/pages/[gameId]/travel.tsx b/web/src/pages/[gameId]/travel.tsx index 39f4b3e1a..441b318bf 100644 --- a/web/src/pages/[gameId]/travel.tsx +++ b/web/src/pages/[gameId]/travel.tsx @@ -9,6 +9,7 @@ import { Divider, useEventListener, Spacer, + Image, } from "@chakra-ui/react"; import { useRouter } from "next/router"; import React, { useCallback, useEffect, useMemo, useState } from "react"; @@ -112,83 +113,85 @@ export default function Travel() { showMap={true} showBack={true} > - - - {locations.map((location, index) => ( - setTargetId(location.id)} - /> - ))} - - - - - - - + + + {locations.map((location, index) => ( + setTargetId(location.id)} + /> + ))} + + - + + + + {getLocationById(targetId).name} + + + + + + ); } diff --git a/web/src/pages/index.tsx b/web/src/pages/index.tsx index f7a23f5d4..56ea5d805 100644 --- a/web/src/pages/index.tsx +++ b/web/src/pages/index.tsx @@ -24,9 +24,8 @@ import { useDojo } from "@/dojo"; import { JoinedEventData } from "@/dojo/events"; import { getLocationById } from "@/dojo/helpers"; import { usePlayerStore } from "@/hooks/state"; -import { Cartridge } from "@/components/icons/branding/Cartridge"; -import { Dojo } from "@/components/icons/branding/Dojo"; -import { ScrollDown } from "@/components/icons/ScrollDown"; +import HomeLeftPanel from "@/components/HomeLeftPanel"; +import Tutorial from "@/components/Tutorial"; import { useEffect, useState } from "react"; // hardcode game params for now @@ -34,13 +33,6 @@ const START_TIME = 0; const MAX_PLAYERS = 1; const NUM_TURNS = 14; -const floatAnim = keyframes` - 0% {transform: translateY(0%);} - 25% {transform: translateY(-6px);} - 50% {transform: translateY(0%);} - 70% {transform: translateY(8px);} -`; - export default function Home() { const router = useRouter(); const { account, isBurnerDeploying, createBurner } = useDojo(); @@ -57,11 +49,16 @@ export default function Home() { [], ); + const [isTutorialOpen, setIsTutorialOpen] = useState(false); + const isLocal = true; + + return ( + {isGated ? ( @@ -72,32 +69,40 @@ export default function Home() { Get ready hustlers... Season II starts in September - ) : ( - + ) : ( + <> + + + )} @@ -120,6 +125,11 @@ export default function Home() { )} + + setIsTutorialOpen(false)} + /> ); } @@ -169,209 +179,3 @@ const Game = ({ ); -const steps = [ - { - step: 1, - title: "Buy Low", - desc: "A short description of this step, maybe one to two sentences. Here is one.", - }, - { - step: 2, - title: "Sell High", - desc: "A short description of this step, maybe one to two sentences. Here is one.", - }, - { - step: 3, - title: "Get rekt", - desc: "A short description of this step, maybe one to two sentences. Here is one.", - }, - { - step: 4, - title: "Profit", - desc: "A short description of this step, maybe one to two sentences. Here is one.", - }, -]; - -const HomeStep = ({ - step, -}: { - step: { step: number; title: string; desc: string }; -}) => { - return ( - <> - - {`step${step.step}`} - - - - {`step${step.step}`} - - - Step {step.step} - - - {step.title} - - - - {step.desc} - - - - ); -}; - -const onScrollDown = () => { - let steps = document.getElementById("steps"); - - setTimeout(() => { - steps && - steps.scrollIntoView({ - behavior: "smooth", - block: "start", - inline: "nearest", - }); - }, 10); -}; - -const HomeLeftPanel = () => { - return ( - <> - - - - DOPE WARS - - - Roll your Own - - - - - context - - onScrollDown()} - animation={`${floatAnim} infinite 3s linear`} - cursor={"pointer"} - > - - - - - {steps.map((step) => { - return ; - })} - - - - - - BUILT BY - - - - | - - - BUILT WITH - - - - - - - - - - - ); -}; diff --git a/web/src/theme/colors.ts b/web/src/theme/colors.ts index c352b7fae..a08bde2ec 100644 --- a/web/src/theme/colors.ts +++ b/web/src/theme/colors.ts @@ -12,6 +12,7 @@ const colors: ColorsType = { 800: "#1C291C", 900: "#172217", }, + neon900Alpha: "#424b42DD", yellow: { 400: "#FBCB4A", }, diff --git a/web/src/theme/components/modal.tsx b/web/src/theme/components/modal.tsx index 30a4dd4e4..f34735e87 100644 --- a/web/src/theme/components/modal.tsx +++ b/web/src/theme/components/modal.tsx @@ -1,4 +1,5 @@ import type { ComponentMultiStyleConfig } from "@chakra-ui/theme"; +import { cardStyle, cardPixelatedStyle } from "../styles"; export const Modal: ComponentMultiStyleConfig = { parts: [ @@ -12,9 +13,13 @@ export const Modal: ComponentMultiStyleConfig = { ], baseStyle: { dialog: { + mx: "16px", bgColor: "neon.900", + ...cardPixelatedStyle({}), }, - overlay: {}, footer: {}, + header: { + fontWeight: "normal", + }, }, };