diff --git a/src/models/data/events.cairo b/src/models/data/events.cairo index 4b61748..444dd5c 100644 --- a/src/models/data/events.cairo +++ b/src/models/data/events.cairo @@ -292,3 +292,11 @@ struct PlayerHealed { current_hp: u32, } +#[derive(Copy, Drop, Serde)] +#[dojo::event] +#[dojo::model] +struct ObstacleAttack { + #[key] + player: ContractAddress, + attack: u32 +} diff --git a/src/models/status/game/game.cairo b/src/models/status/game/game.cairo index 06169cd..d744209 100644 --- a/src/models/status/game/game.cairo +++ b/src/models/status/game/game.cairo @@ -12,7 +12,8 @@ enum GameSubState { DRAFT_SPECIALS, DRAFT_DECK, DRAFT_ADVENTURER, - DRAFT_ADVENTURER_CARDS + DRAFT_ADVENTURER_CARDS, + UNPASSED_OBSTACLE } #[derive(Serde, Copy, Drop, IntrospectPacked, PartialEq)] diff --git a/src/models/status/round/challenge.cairo b/src/models/status/round/challenge.cairo index 31b138d..6d0636f 100644 --- a/src/models/status/round/challenge.cairo +++ b/src/models/status/round/challenge.cairo @@ -19,7 +19,7 @@ use jokers_of_neon::{ game_deck::{GameDeckStore, GameDeckImpl}, events::{ ChallengeCompleted, ItemChallengeCompleted, PlayGameOverEvent, ModifierCardSuitEvent, - SpecialModifierSuitEvent + SpecialModifierSuitEvent, ObstacleAttack }, poker_hand::PokerHand }, @@ -96,12 +96,13 @@ impl ChallengeImpl of ChallengeTrait { emit!(world, (challenge_player)); ChallengePlayerStore::set(@challenge_player, world); if challenge_player.plays.is_zero() { + let challenge_attack = 5 * game.level; game .current_player_hp = - if game.current_player_hp <= 5 * game.level { + if game.current_player_hp <= challenge_attack { 0 } else { - game.current_player_hp - 5 * game.level + game.current_player_hp - challenge_attack }; if game.current_player_hp.is_zero() { @@ -110,12 +111,11 @@ impl ChallengeImpl of ChallengeTrait { game.state = GameState::FINISHED; return; } - challenge_player.discards = game.max_discard; - challenge_player.plays = game.max_hands; - ChallengePlayerStore::set(@challenge_player, world); - emit!(world, (challenge_player)); + emit!(world, ObstacleAttack { player: game.owner, attack: challenge_attack }); + game.substate = GameSubState::UNPASSED_OBSTACLE; GameStore::set(@game, world); + return; } let mut cards = array![]; @@ -144,10 +144,26 @@ impl ChallengeImpl of ChallengeTrait { let game_deck = GameDeckStore::get(world, game_id); if game_deck.round_len.is_zero() && _player_has_empty_hand(ref store, @game) { - let play_game_over_event = PlayGameOverEvent { player: get_caller_address(), game_id: game.id }; - emit!(world, (play_game_over_event)); - game.state = GameState::FINISHED; + let challenge_attack = 5 * game.level; + game + .current_player_hp = + if game.current_player_hp <= challenge_attack { + 0 + } else { + game.current_player_hp - challenge_attack + }; + + if game.current_player_hp.is_zero() { + let play_game_over_event = PlayGameOverEvent { player: get_caller_address(), game_id: game.id }; + emit!(world, (play_game_over_event)); + game.state = GameState::FINISHED; + return; + } + + emit!(world, ObstacleAttack { player: game.owner, attack: challenge_attack }); + game.substate = GameSubState::UNPASSED_OBSTACLE; GameStore::set(@game, world); + return; } } } diff --git a/src/systems/game_system.cairo b/src/systems/game_system.cairo index 5de7d14..bdc7645 100644 --- a/src/systems/game_system.cairo +++ b/src/systems/game_system.cairo @@ -19,6 +19,7 @@ trait IGameSystem { fn use_adventurer(ref world: IWorldDispatcher, game_id: u32, adventurer_id: u32); fn skip_adventurer(ref world: IWorldDispatcher, game_id: u32); fn select_aventurer_cards(ref world: IWorldDispatcher, game_id: u32, cards_index: Array); + fn skip_unpassed_obstacle(ref world: IWorldDispatcher, game_id: u32); } mod errors { @@ -43,6 +44,7 @@ mod errors { const WRONG_SUBSTATE_SELECT_REWARD: felt252 = 'Wrong substate SELECT_REWARD'; const WRONG_SUBSTATE_DRAFT_ADVENTURER: felt252 = 'Wrong substate SELECT_ADVENTURE'; const WRONG_SUBSTATE_ADVENTURER_CARDS: felt252 = 'Wrong substate SELECT_ADV_CARDS'; + const WRONG_SUBSTATE_UNPASSED_OBSTABLE: felt252 = 'Wrong substate UNPASSED_OBST'; } #[dojo::contract] @@ -157,6 +159,7 @@ mod game_system { let mut game = store.get_game(game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert(game.state == GameState::IN_GAME, errors::GAME_NOT_IN_GAME); assert(game.substate == GameSubState::CREATE_LEVEL, errors::WRONG_SUBSTATE_CREATE_LEVEL); @@ -175,6 +178,7 @@ mod game_system { let game = store.get_game(game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert(game.state == GameState::IN_GAME, errors::GAME_NOT_IN_GAME); match game.substate { @@ -189,6 +193,7 @@ mod game_system { let game = store.get_game(game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert(game.state == GameState::IN_GAME, errors::GAME_NOT_IN_GAME); match game.substate { @@ -203,6 +208,7 @@ mod game_system { let game = store.get_game(game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert(game.substate == GameSubState::BEAST, errors::WRONG_SUBSTATE_BEAST); BeastTrait::end_turn(world, game_id); @@ -211,6 +217,7 @@ mod game_system { fn create_reward(ref world: IWorldDispatcher, game_id: u32, reward_index: u8) { let mut game = GameStore::get(world, game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert(game.substate == GameSubState::CREATE_REWARD, errors::WRONG_SUBSTATE_REWARD); let reward: RewardType = (*RewardStore::get(world, game_id).rewards_ids.at(reward_index.into())).into(); @@ -255,6 +262,7 @@ mod game_system { fn select_reward(ref world: IWorldDispatcher, game_id: u32, cards_index: Array) { let mut game = GameStore::get(world, game_id); assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); assert( game.substate == GameSubState::REWARD_SPECIALS || game.substate == GameSubState::REWARD_CARDS_PACK, errors::WRONG_SUBSTATE_SELECT_REWARD @@ -414,6 +422,20 @@ mod game_system { store.set_game(game); } + fn skip_unpassed_obstacle(ref world: IWorldDispatcher, game_id: u32) { + let mut game = GameStore::get(world, game_id); + assert(game.owner.is_non_zero(), errors::GAME_NOT_FOUND); + assert(game.owner == get_caller_address(), errors::CALLER_NOT_OWNER); + assert( + game.substate == GameSubState::UNPASSED_OBSTACLE, + errors::WRONG_SUBSTATE_UNPASSED_OBSTABLE + ); + let mut store = StoreTrait::new(world); + game.substate = GameSubState::CREATE_LEVEL; + store.set_game(game); + self.create_level(game_id) + } + fn discard_effect_card(ref world: IWorldDispatcher, game_id: u32, card_index: u32) { let mut store: Store = StoreTrait::new(world); let game = store.get_game(game_id);