diff --git a/Scarb.toml b/Scarb.toml index eba05234..f30cb9fb 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -7,7 +7,7 @@ cairo-version = "2.0.0-rc4" sierra-replace-ids = true [dependencies] -dojo = { git = "https://github.com/dojoengine/dojo.git"} +dojo = { git = "https://github.com/dojoengine/dojo.git", rev="b842d0a2c137fe232d4b9d8a4282a4c78771e3d8"} [[target.dojo]] diff --git a/src/components.cairo b/src/components.cairo index b5f3b68c..50b6d1b5 100644 --- a/src/components.cairo +++ b/src/components.cairo @@ -4,3 +4,4 @@ mod player; mod drug; mod location; mod risks; +mod name; diff --git a/src/components/drug.cairo b/src/components/drug.cairo index 12b91975..9134b2d8 100644 --- a/src/components/drug.cairo +++ b/src/components/drug.cairo @@ -3,8 +3,7 @@ use traits::{Into, TryInto}; #[derive(Component, Copy, Drop, Serde)] struct Drug { - name: felt252, - quantity: usize, + quantity: usize, } trait DrugTrait { diff --git a/src/components/name.cairo b/src/components/name.cairo new file mode 100644 index 00000000..ee0cac11 --- /dev/null +++ b/src/components/name.cairo @@ -0,0 +1,4 @@ +#[derive(Component, Copy, Drop, Serde)] +struct Name { + short_string: felt252, +} diff --git a/src/components/player.cairo b/src/components/player.cairo index 9f3a5b67..5e3975a5 100644 --- a/src/components/player.cairo +++ b/src/components/player.cairo @@ -1,6 +1,5 @@ #[derive(Component, Copy, Drop, Serde)] struct Player { - name: felt252, cash: u128, health: u8, arrested: bool, diff --git a/src/systems/create.cairo b/src/systems/create.cairo index 32ff1f10..29eb9a7c 100644 --- a/src/systems/create.cairo +++ b/src/systems/create.cairo @@ -7,6 +7,7 @@ mod create_game { use dojo::world::Context; use rollyourown::events::{emit, GameCreated, PlayerJoined}; + use rollyourown::components::name::Name; use rollyourown::components::game::Game; use rollyourown::components::player::Player; use rollyourown::components::risks::Risks; @@ -48,7 +49,6 @@ mod create_game { (game_id, player_id).into(), ( Player { - name: 0, // set at end of game cash: 100 * SCALING_FACTOR, // $100 health: 100, arrested: false, @@ -89,7 +89,13 @@ mod create_game { set !( ctx.world, (game_id, *location_name, *drug_name).into(), - (Market { cash: MARKET_CASH, quantity: MARKET_QUANTITY }) + ( + Name { + short_string: *drug_name + }, Market { + cash: MARKET_CASH, quantity: MARKET_QUANTITY + } + ) ); }, Option::None(()) => { diff --git a/src/systems/join.cairo b/src/systems/join.cairo index a3390e93..281a52ac 100644 --- a/src/systems/join.cairo +++ b/src/systems/join.cairo @@ -30,7 +30,6 @@ mod join_game { (game_id, player_id).into(), ( Player { - name: 0, // set at end of game cash: 100 * SCALING_FACTOR, // $100 health: 100, arrested: false, diff --git a/src/systems/player.cairo b/src/systems/player.cairo index 90c1766e..a9fe68df 100644 --- a/src/systems/player.cairo +++ b/src/systems/player.cairo @@ -5,23 +5,12 @@ mod set_name { use dojo::world::Context; use rollyourown::components::game::Game; - use rollyourown::components::player::Player; + use rollyourown::components::name::Name; fn execute(ctx: Context, game_id: u32, player_name: felt252) { let player_id: felt252 = ctx.origin.into(); let player_sk: Query = (game_id, player_id).into(); - let player = get !(ctx.world, player_sk, (Player)); - set !( - ctx.world, - player_sk, - (Player { - name: player_name, - cash: player.cash, - health: player.health, - arrested: player.arrested, - turns_remaining: player.turns_remaining, - }) - ) + set !(ctx.world, player_sk, (Name { short_string: player_name, })) } } diff --git a/src/systems/trade.cairo b/src/systems/trade.cairo index e57f9f87..9f19d8d7 100644 --- a/src/systems/trade.cairo +++ b/src/systems/trade.cairo @@ -47,7 +47,6 @@ mod buy { ctx.world, (game_id, player_id).into(), (Player { - name: player.name, cash: player.cash - cost, health: player.health, arrested: player.arrested, @@ -60,9 +59,7 @@ mod buy { Option::None(_) => quantity, }; set !( - ctx.world, - (game_id, player_id, drug_name).into(), - (Drug { name: drug_name, quantity: player_quantity }) + ctx.world, (game_id, player_id, drug_name).into(), (Drug { quantity: player_quantity }) ); Bought(game_id, player_id, drug_name, quantity, cost); @@ -121,7 +118,6 @@ mod sell { ctx.world, (game_id, player_id).into(), (Player { - name: player.name, cash: player.cash + payout, health: player.health, arrested: player.arrested, @@ -131,7 +127,7 @@ mod sell { set !( ctx.world, (game_id, player_id, drug_name).into(), - (Drug { name: drug_name, quantity: player_quantity - quantity }) + (Drug { quantity: player_quantity - quantity }) ); Sold(game_id, player_id, drug_name, quantity, payout); diff --git a/src/systems/travel.cairo b/src/systems/travel.cairo index 2571cd1e..9f25e18d 100644 --- a/src/systems/travel.cairo +++ b/src/systems/travel.cairo @@ -45,7 +45,6 @@ mod travel { Location { name: next_location_name }, Player { - name: player.name, cash: player.cash - result.money_loss, health: updated_health, arrested: result.arrested, diff --git a/src/tests/create.cairo b/src/tests/create.cairo index 955c187c..bdc17eae 100644 --- a/src/tests/create.cairo +++ b/src/tests/create.cairo @@ -23,6 +23,7 @@ use rollyourown::components::player::{player, Player}; use rollyourown::components::drug::{drug, Drug}; use rollyourown::components::location::{location, Location}; use rollyourown::components::risks::{risks, Risks}; +use rollyourown::components::name::{name, Name}; use rollyourown::systems::travel::travel; use rollyourown::systems::trade::{buy, sell}; use rollyourown::systems::join::join_game; @@ -46,6 +47,7 @@ fn spawn_game() -> (ContractAddress, u32, felt252) { components.append(risks::TEST_CLASS_HASH); components.append(market::TEST_CLASS_HASH); components.append(drug::TEST_CLASS_HASH); + components.append(name::TEST_CLASS_HASH); let mut systems = array::ArrayTrait::new(); systems.append(create_game::TEST_CLASS_HASH); diff --git a/src/tests/player.cairo b/src/tests/player.cairo index d2306b07..66d53129 100644 --- a/src/tests/player.cairo +++ b/src/tests/player.cairo @@ -9,7 +9,7 @@ use starknet::{ContractAddress, syscalls::deploy_syscall}; use starknet::class_hash::{ClassHash, Felt252TryIntoClassHash}; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; -use rollyourown::components::player::{player, Player}; +use rollyourown::components::name::{name, Name}; use rollyourown::tests::create::spawn_game; #[test] @@ -24,9 +24,9 @@ fn test_set_name() { world.execute('set_name'.into(), set_name_calldata.span()); - let mut res = world.entity('Player'.into(), (game_id, player_id).into(), 0, 0); + let mut res = world.entity('Name'.into(), (game_id, player_id).into(), 0, 0); assert(res.len() > 0, 'no player'); - let player = serde::Serde::::deserialize(ref res).expect('deserialization failed'); - assert(player.name == 'Rambo'.into(), 'incorrect name'); + let name = serde::Serde::::deserialize(ref res).expect('deserialization failed'); + assert(name.short_string == 'Rambo'.into(), 'incorrect name'); } diff --git a/web/src/components/Header.tsx b/web/src/components/Header.tsx index 2feead8a..68159f73 100644 --- a/web/src/components/Header.tsx +++ b/web/src/components/Header.tsx @@ -93,14 +93,6 @@ const Header = ({ back }: HeaderProps) => { {inventoryInfos.used}/{inventoryInfos.capacity} - - - {" "} - - {!IsMobile && "Day"} {game.maxTurns - player.turnsRemaining}/ - {game.maxTurns} - - )} diff --git a/web/src/constants.ts b/web/src/constants.ts index 6b6f527e..6b89300e 100644 --- a/web/src/constants.ts +++ b/web/src/constants.ts @@ -1,4 +1,4 @@ export const RYO_WORLD_ADDRESS = - "0x7d17bb24b59cb371c9ca36b79efca27fe53318e26340df3d8623dba5a7b9e5f"; + "0x26065106fa319c3981618e7567480a50132f23932226a51c219ffb8e47daa84"; export const ETH_CONTRACT_ADDRESS = "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; diff --git a/web/src/generated/graphql.ts b/web/src/generated/graphql.ts index f50efc27..b5da505c 100644 --- a/web/src/generated/graphql.ts +++ b/web/src/generated/graphql.ts @@ -1,4 +1,10 @@ -import { useQuery, UseQueryOptions } from "react-query"; +import { + useQuery, + useInfiniteQuery, + UseQueryOptions, + UseInfiniteQueryOptions, + QueryFunctionContext, +} from "react-query"; import { useFetchData } from "@/hooks/fetcher"; export type Maybe = T | null; export type InputMaybe = Maybe; @@ -29,11 +35,17 @@ export type Scalars = { usize: any; }; -export type ComponentUnion = Drug | Game | Location | Market | Player | Risks; +export type ComponentUnion = + | Drug + | Game + | Location + | Market + | Name + | Player + | Risks; export type Drug = { __typename?: "Drug"; - name: Scalars["felt252"]; quantity: Scalars["usize"]; }; @@ -79,12 +91,16 @@ export type Market = { quantity: Scalars["usize"]; }; +export type Name = { + __typename?: "Name"; + short_string: Scalars["felt252"]; +}; + export type Player = { __typename?: "Player"; arrested: Scalars["bool"]; cash: Scalars["u128"]; health: Scalars["u8"]; - name: Scalars["felt252"]; turns_remaining: Scalars["usize"]; }; @@ -98,6 +114,7 @@ export type Query = { gameComponents?: Maybe>>; locationComponents?: Maybe>>; marketComponents?: Maybe>>; + nameComponents?: Maybe>>; playerComponents?: Maybe>>; risksComponents?: Maybe>>; system: System; @@ -108,7 +125,6 @@ export type Query = { export type QueryDrugComponentsArgs = { limit?: InputMaybe; - name?: InputMaybe; quantity?: InputMaybe; }; @@ -151,12 +167,16 @@ export type QueryMarketComponentsArgs = { quantity?: InputMaybe; }; +export type QueryNameComponentsArgs = { + limit?: InputMaybe; + short_string?: InputMaybe; +}; + export type QueryPlayerComponentsArgs = { arrested?: InputMaybe; cash?: InputMaybe; health?: InputMaybe; limit?: InputMaybe; - name?: InputMaybe; turns_remaining?: InputMaybe; }; @@ -242,13 +262,13 @@ export type PlayerEntityQuery = { entity: { __typename?: "Entity"; components?: Array< - | { __typename: "Drug"; name: any; quantity: any } + | { __typename: "Drug"; quantity: any } | { __typename: "Game" } | { __typename: "Location"; name: any } | { __typename: "Market" } + | { __typename: "Name"; short_string: any } | { __typename: "Player"; - name: any; cash: any; health: any; arrested: any; @@ -282,6 +302,7 @@ export type GameEntityQuery = { } | { __typename: "Location" } | { __typename: "Market" } + | { __typename: "Name" } | { __typename: "Player" } | { __typename: "Risks" } | null @@ -299,13 +320,14 @@ export type LocationEntitiesQuery = { entities?: Array<{ __typename?: "Entity"; components?: Array< - | { __typename?: "Drug" } - | { __typename?: "Game" } - | { __typename?: "Location"; name: any } - | { __typename?: "Market"; cash: any; quantity: any } - | { __typename?: "Player" } + | { __typename: "Drug" } + | { __typename: "Game" } + | { __typename: "Location"; name: any } + | { __typename: "Market"; cash: any; quantity: any } + | { __typename: "Name"; short_string: any } + | { __typename: "Player" } | { - __typename?: "Risks"; + __typename: "Risks"; arrested: any; hurt: any; mugged: any; @@ -347,6 +369,31 @@ export const useAvailableGamesQuery = < useAvailableGamesQuery.getKey = (variables?: AvailableGamesQueryVariables) => variables === undefined ? ["AvailableGames"] : ["AvailableGames", variables]; +export const useInfiniteAvailableGamesQuery = < + TData = AvailableGamesQuery, + TError = unknown, +>( + variables?: AvailableGamesQueryVariables, + options?: UseInfiniteQueryOptions, +) => { + const query = useFetchData( + AvailableGamesDocument, + ); + return useInfiniteQuery( + variables === undefined + ? ["AvailableGames.infinite"] + : ["AvailableGames.infinite", variables], + (metaData) => query({ ...variables, ...(metaData.pageParam ?? {}) }), + options, + ); +}; + +useInfiniteAvailableGamesQuery.getKey = ( + variables?: AvailableGamesQueryVariables, +) => + variables === undefined + ? ["AvailableGames.infinite"] + : ["AvailableGames.infinite", variables]; export const UserGamesDocument = ` query UserGames($id: felt252!) { gameComponents(creator: $id) { @@ -370,23 +417,45 @@ useUserGamesQuery.getKey = (variables: UserGamesQueryVariables) => [ "UserGames", variables, ]; +export const useInfiniteUserGamesQuery = < + TData = UserGamesQuery, + TError = unknown, +>( + variables: UserGamesQueryVariables, + options?: UseInfiniteQueryOptions, +) => { + const query = useFetchData( + UserGamesDocument, + ); + return useInfiniteQuery( + ["UserGames.infinite", variables], + (metaData) => query({ ...variables, ...(metaData.pageParam ?? {}) }), + options, + ); +}; + +useInfiniteUserGamesQuery.getKey = (variables: UserGamesQueryVariables) => [ + "UserGames.infinite", + variables, +]; export const PlayerEntityDocument = ` query PlayerEntity($id: ID!) { entity(id: $id) { components { __typename ... on Player { - name cash health arrested turns_remaining } + ... on Name { + short_string + } ... on Location { name } ... on Drug { - name quantity } } @@ -412,6 +481,26 @@ usePlayerEntityQuery.getKey = (variables: PlayerEntityQueryVariables) => [ "PlayerEntity", variables, ]; +export const useInfinitePlayerEntityQuery = < + TData = PlayerEntityQuery, + TError = unknown, +>( + variables: PlayerEntityQueryVariables, + options?: UseInfiniteQueryOptions, +) => { + const query = useFetchData( + PlayerEntityDocument, + ); + return useInfiniteQuery( + ["PlayerEntity.infinite", variables], + (metaData) => query({ ...variables, ...(metaData.pageParam ?? {}) }), + options, + ); +}; + +useInfinitePlayerEntityQuery.getKey = ( + variables: PlayerEntityQueryVariables, +) => ["PlayerEntity.infinite", variables]; export const GameEntityDocument = ` query GameEntity($id: ID!) { entity(id: $id) { @@ -446,10 +535,35 @@ useGameEntityQuery.getKey = (variables: GameEntityQueryVariables) => [ "GameEntity", variables, ]; +export const useInfiniteGameEntityQuery = < + TData = GameEntityQuery, + TError = unknown, +>( + variables: GameEntityQueryVariables, + options?: UseInfiniteQueryOptions, +) => { + const query = useFetchData( + GameEntityDocument, + ); + return useInfiniteQuery( + ["GameEntity.infinite", variables], + (metaData) => query({ ...variables, ...(metaData.pageParam ?? {}) }), + options, + ); +}; + +useInfiniteGameEntityQuery.getKey = (variables: GameEntityQueryVariables) => [ + "GameEntity.infinite", + variables, +]; export const LocationEntitiesDocument = ` query LocationEntities($gameId: String!, $location: String!) { entities(keys: [$gameId, $location]) { components { + __typename + ... on Name { + short_string + } ... on Market { cash quantity @@ -485,3 +599,24 @@ export const useLocationEntitiesQuery = < useLocationEntitiesQuery.getKey = ( variables: LocationEntitiesQueryVariables, ) => ["LocationEntities", variables]; +export const useInfiniteLocationEntitiesQuery = < + TData = LocationEntitiesQuery, + TError = unknown, +>( + variables: LocationEntitiesQueryVariables, + options?: UseInfiniteQueryOptions, +) => { + const query = useFetchData< + LocationEntitiesQuery, + LocationEntitiesQueryVariables + >(LocationEntitiesDocument); + return useInfiniteQuery( + ["LocationEntities.infinite", variables], + (metaData) => query({ ...variables, ...(metaData.pageParam ?? {}) }), + options, + ); +}; + +useInfiniteLocationEntitiesQuery.getKey = ( + variables: LocationEntitiesQueryVariables, +) => ["LocationEntities.infinite", variables]; diff --git a/web/src/generated/introspection.ts b/web/src/generated/introspection.ts index 8339eba1..8db2760e 100644 --- a/web/src/generated/introspection.ts +++ b/web/src/generated/introspection.ts @@ -5,7 +5,15 @@ export interface PossibleTypesResultData { } const result: PossibleTypesResultData = { possibleTypes: { - ComponentUnion: ["Drug", "Game", "Location", "Market", "Player", "Risks"], + ComponentUnion: [ + "Drug", + "Game", + "Location", + "Market", + "Name", + "Player", + "Risks", + ], }, }; export default result; diff --git a/web/src/graphql/entities.graphql b/web/src/graphql/entities.graphql index 828af140..623eefb7 100644 --- a/web/src/graphql/entities.graphql +++ b/web/src/graphql/entities.graphql @@ -3,17 +3,18 @@ query PlayerEntity($id: ID!) { components { __typename ... on Player { - name cash health arrested turns_remaining } + ... on Name { + short_string + } ... on Location { name } ... on Drug { - name quantity } } @@ -40,6 +41,10 @@ query GameEntity($id: ID!) { query LocationEntities($gameId: String!, $location: String!) { entities(keys: [$gameId, $location]) { components { + __typename + ... on Name { + short_string + } ... on Market { cash quantity diff --git a/web/src/hooks/dojo/entities/usePlayerEntity.tsx b/web/src/hooks/dojo/entities/usePlayerEntity.tsx index 94d33a2f..06cda9ce 100644 --- a/web/src/hooks/dojo/entities/usePlayerEntity.tsx +++ b/web/src/hooks/dojo/entities/usePlayerEntity.tsx @@ -1,8 +1,7 @@ import { Player, Location, usePlayerEntityQuery } from "@/generated/graphql"; import { useEffect, useState } from "react"; import { ec, num, shortString } from "starknet"; - -const SCALING_FACTOR = 10000; +import { SCALING_FACTOR } from ".."; interface PlayerEntityData { entity: { @@ -11,7 +10,6 @@ interface PlayerEntityData { } export class PlayerEntity { - name: string; cash: number; health: number; arrested: boolean; @@ -19,7 +17,6 @@ export class PlayerEntity { location_name: string; constructor(player: Player, location: Location) { - this.name = player.name; this.cash = parseInt(player.cash, 16) / SCALING_FACTOR; this.health = player.health; this.arrested = player.arrested; diff --git a/web/src/hooks/dojo/index.tsx b/web/src/hooks/dojo/index.tsx index 440274cc..409147a5 100644 --- a/web/src/hooks/dojo/index.tsx +++ b/web/src/hooks/dojo/index.tsx @@ -8,6 +8,8 @@ import { TransactionStatus, } from "starknet"; +export const SCALING_FACTOR = 10000; + interface DojoInterface { account: Account; isPending: boolean; diff --git a/web/src/hooks/state.tsx b/web/src/hooks/state.tsx index 67900fff..e938ff11 100644 --- a/web/src/hooks/state.tsx +++ b/web/src/hooks/state.tsx @@ -137,7 +137,7 @@ export const initGameState = (turns: number, cash: number): GameState => { }; export const useGameStore = create(() => ({ - ...initGameState(20, 420), + ...initGameState(20, 100), })); export const updateLocation = (location: Locations) => diff --git a/web/src/pages/[gameId]/location/[locationSlug]/index.tsx b/web/src/pages/[gameId]/location/[locationSlug]/index.tsx index c7082e0c..497400f3 100644 --- a/web/src/pages/[gameId]/location/[locationSlug]/index.tsx +++ b/web/src/pages/[gameId]/location/[locationSlug]/index.tsx @@ -1,4 +1,4 @@ -import { ReactNode, useEffect, useState } from "react"; +import { useEffect, useState } from "react"; import { Box, Text, @@ -17,16 +17,7 @@ import Layout from "@/components/Layout"; import { useRouter } from "next/router"; import Content from "@/components/Content"; import { Footer } from "@/components/Footer"; -import { - Ludes, - Weed, - Acid, - Speed, - Heroin, - Cocaine, -} from "@/components/icons/drugs"; -import { Inventory } from "@/components/Inventory"; -import { LocationProps, useUiStore } from "@/hooks/ui"; +import { getLocationBySlug, LocationProps, useUiStore } from "@/hooks/ui"; import { useGameStore, travelTo, @@ -68,7 +59,6 @@ export default function Location() { headerImage={`/images/locations/${location?.slug}.png`} > - {/* */} {drugs.map((drug, index) => ( - Travel and end turn + Continue