diff --git a/contracts/src/components/playable.cairo b/contracts/src/components/playable.cairo index 97a19917..978c8ca0 100644 --- a/contracts/src/components/playable.cairo +++ b/contracts/src/components/playable.cairo @@ -181,7 +181,16 @@ mod PlayableComponent { tournament.score(player.id, game.id, game.score); store.set_tournament(tournament); game.score_in_tournament = game.score; - game.combo_counter_in_tournament = game.combo_counter; + + // Put this for patching the u8 combo_counter_in_tournament to u16 + // this is the case where the game has been started before the patch + // the game_counter_2 (u16 is up to date because _handle_score_for_tournament + // is called after move or apply_bonus) + // if combo_counter_in_tournament is not 0 we set the combo_counter_in_tournament_2 + if (game.combo_counter_in_tournament != 0) { + game.combo_counter_in_tournament_2 = game.combo_counter_in_tournament.into(); + } + game.combo_counter_in_tournament_2 = game.combo_counter_2; game.max_combo_in_tournament = game.max_combo; } } @@ -244,7 +253,7 @@ mod PlayableComponent { }; // [Trophy] Update Mastering tasks progression - let value = game.combo_counter.into(); + let value = game.combo_counter_2.into(); let time = get_block_timestamp(); let store = BushidoStoreTrait::new(world); if Trophy::ComboInitiator.assess(value) { diff --git a/contracts/src/elements/bonuses/hammer.cairo b/contracts/src/elements/bonuses/hammer.cairo index a87c3c2f..c29ecc8e 100644 --- a/contracts/src/elements/bonuses/hammer.cairo +++ b/contracts/src/elements/bonuses/hammer.cairo @@ -38,7 +38,7 @@ impl BonusImpl of BonusTrait { } #[inline(always)] - fn get_count(score: u32, combo_count: u8, max_combo: u8) -> u8 { + fn get_count(score: u32, combo_count: u16, max_combo: u8) -> u8 { if score >= 120 { return 3; } diff --git a/contracts/src/elements/bonuses/interface.cairo b/contracts/src/elements/bonuses/interface.cairo index 04f37cc4..2683cced 100644 --- a/contracts/src/elements/bonuses/interface.cairo +++ b/contracts/src/elements/bonuses/interface.cairo @@ -6,5 +6,5 @@ use zkube::types::bonus::Bonus; #[derive(Drop, Copy)] trait BonusTrait { fn apply(blocks: felt252, row_index: u8, index: u8) -> felt252; - fn get_count(score: u32, combo_count: u8, max_combo: u8) -> u8; + fn get_count(score: u32, combo_count: u16, max_combo: u8) -> u8; } diff --git a/contracts/src/elements/bonuses/totem.cairo b/contracts/src/elements/bonuses/totem.cairo index e5f6a71d..bf6e3d3f 100644 --- a/contracts/src/elements/bonuses/totem.cairo +++ b/contracts/src/elements/bonuses/totem.cairo @@ -51,7 +51,7 @@ impl BonusImpl of BonusTrait { } #[inline(always)] - fn get_count(score: u32, combo_count: u8, max_combo: u8) -> u8 { + fn get_count(score: u32, combo_count: u16, max_combo: u8) -> u8 { if max_combo >= 6 { return 3; } diff --git a/contracts/src/elements/bonuses/wave.cairo b/contracts/src/elements/bonuses/wave.cairo index 6dfaf4d7..a8eb8b3b 100644 --- a/contracts/src/elements/bonuses/wave.cairo +++ b/contracts/src/elements/bonuses/wave.cairo @@ -25,7 +25,7 @@ impl BonusImpl of BonusTrait { } #[inline(always)] - fn get_count(score: u32, combo_count: u8, max_combo: u8) -> u8 { + fn get_count(score: u32, combo_count: u16, max_combo: u8) -> u8 { if combo_count >= 64 { return 3; } diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index eaed7d16..e52de4b8 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -109,6 +109,7 @@ mod tests { mod test_minter; mod test_erc721; mod test_pause; + mod test_patch_u16; mod mocks { mod erc20; diff --git a/contracts/src/models/game.cairo b/contracts/src/models/game.cairo index e0e29077..186e50a7 100644 --- a/contracts/src/models/game.cairo +++ b/contracts/src/models/game.cairo @@ -61,6 +61,8 @@ impl GameImpl of GameTrait { combo_counter_in_tournament: 0, max_combo_in_tournament: 0, pending_chest_prize: 0, + combo_counter_2: 0, + combo_counter_in_tournament_2: 0, } } @@ -118,9 +120,18 @@ impl GameImpl of GameTrait { #[inline(always)] fn assess_bonuses(self: Game) -> (u8, u8, u8) { - let hammer = Bonus::Hammer.get_count(self.score, self.combo_counter, self.max_combo); - let totem = Bonus::Totem.get_count(self.score, self.combo_counter, self.max_combo); - let wave = Bonus::Wave.get_count(self.score, self.combo_counter, self.max_combo); + // Put this for patching the u8 combo_counter to u16 + // this is the case where the game has been started before the patch + // in this case we get the highest value from the u8 and u16 + // the u16 will be updated later (in move and apply_bonus) + let combo_counter: u16 = if (self.combo_counter.into() > self.combo_counter_2) { + self.combo_counter.into() + } else { + self.combo_counter_2 + }; + let hammer = Bonus::Hammer.get_count(self.score, combo_counter, self.max_combo); + let totem = Bonus::Totem.get_count(self.score, combo_counter, self.max_combo); + let wave = Bonus::Wave.get_count(self.score, combo_counter, self.max_combo); (hammer, totem, wave) } @@ -184,7 +195,13 @@ impl GameImpl of GameTrait { // [Effect] Assess game self.score += self.assess_game(ref counter); if (counter > 1) { - self.combo_counter += counter; + // Put this for patching the u8 combo_counter to u16 + // this is the case where the game has been started before the patch + // in this case we write the value from the u8 to the u16 + if (self.combo_counter != 0) { + self.combo_counter_2 = self.combo_counter.into(); + } + self.combo_counter_2 += counter.into(); self.max_combo = Math::max(self.max_combo, counter); } self.moves += 1; @@ -237,7 +254,13 @@ impl GameImpl of GameTrait { let mut counter = 0; self.score += self.assess_game(ref counter); if (counter > 1) { - self.combo_counter += counter; + // Put this for patching the u8 combo_counter to u16 + // this is the case where the game has been started before the patch + // in this case we write the value from the u8 to the u16 + if (self.combo_counter != 0) { + self.combo_counter_2 = self.combo_counter.into(); + } + self.combo_counter_2 += counter.into(); self.max_combo = Math::max(self.max_combo, counter); } @@ -282,6 +305,8 @@ impl ZeroableGame of core::Zeroable { combo_counter_in_tournament: 0, max_combo_in_tournament: 0, pending_chest_prize: 0, + combo_counter_2: 0, + combo_counter_in_tournament_2: 0, } } diff --git a/contracts/src/models/index.cairo b/contracts/src/models/index.cairo index 27afa425..9dea683e 100644 --- a/contracts/src/models/index.cairo +++ b/contracts/src/models/index.cairo @@ -48,8 +48,13 @@ pub struct Game { pub max_combo_in_tournament: u8, // ------------------------ pub pending_chest_prize: u128, // prize to be added to the right chest -// the right chest is the one that is not complete and has the highest point_target -// only known after the game is over + // the right chest is the one that is not complete and has the highest point_target + // only known after the game is over + + // ------------------------ + // added to patch the max combo u8 limit + pub combo_counter_2: u16, + pub combo_counter_in_tournament_2: u16, } #[derive(Copy, Drop, Serde, IntrospectPacked, Debug)] diff --git a/contracts/src/tests/test_bonus_totem.cairo b/contracts/src/tests/test_bonus_totem.cairo index db960c97..6c31de5f 100644 --- a/contracts/src/tests/test_bonus_totem.cairo +++ b/contracts/src/tests/test_bonus_totem.cairo @@ -25,13 +25,13 @@ fn update_combo_and_check( store: @Store, mut world: WorldStorage, game_id: u32, - combo_count: u8, + combo_count: u16, max_combo: u8, expected_available_totem: u8 ) { // Update combo count and max combo let mut game = (*store).game(game_id); - game.combo_counter = combo_count; + game.combo_counter_2 = combo_count; game.max_combo = max_combo; // Check bonuses let (hammer, totem, wave) = game.assess_bonuses(); diff --git a/contracts/src/tests/test_bonus_wave.cairo b/contracts/src/tests/test_bonus_wave.cairo index 5dcdff61..3404b94d 100644 --- a/contracts/src/tests/test_bonus_wave.cairo +++ b/contracts/src/tests/test_bonus_wave.cairo @@ -26,12 +26,12 @@ fn update_combo_and_check( store: @Store, mut world: WorldStorage, game_id: u32, - combo_count: u8, + combo_count: u16, expected_available_wave: u8 ) { // Update combo count let mut game = (*store).game(game_id); - game.combo_counter = combo_count; + game.combo_counter_2 = combo_count; // Check bonuses let (hammer, totem, wave) = game.assess_bonuses(); game.hammer_bonus = hammer; diff --git a/contracts/src/tests/test_patch_u16.cairo b/contracts/src/tests/test_patch_u16.cairo new file mode 100644 index 00000000..4fe9f47c --- /dev/null +++ b/contracts/src/tests/test_patch_u16.cairo @@ -0,0 +1,67 @@ +// Core imports + +use core::debug::PrintTrait; + +// Starknet imports + +use starknet::testing::{ + set_contract_address, set_account_contract_address, set_transaction_hash, set_block_timestamp +}; + +// Dojo imports + +use dojo::world::{WorldStorage, IWorldDispatcherTrait, WorldStorageTrait}; +use dojo::model::{ModelStorage, ModelValueStorage, ModelStorageTest}; +use dojo::model::Model; + +// Internal imports + +use zkube::constants; +use zkube::store::{Store, StoreTrait}; +use zkube::models::game::{Game, GameTrait}; +use zkube::models::player::{Player, PlayerTrait}; +use zkube::systems::play::IPlayDispatcherTrait; +use zkube::types::mode::Mode; + +// Test imports + +use zkube::tests::setup::{ + setup, + setup::{ + Systems, PLAYER1, PLAYER2, PLAYER3, PLAYER4, IERC20DispatcherTrait, verify_system_allowance, + user_mint_token, admin_mint_token, impersonate + } +}; + +#[test] +fn test_patch_u16() { + // [Setup] + let (mut world, systems, context) = setup::create_accounts(); + let erc721_addr = context.erc721.contract_address; + let erc20_addr = context.erc20.contract_address; + let store = StoreTrait::new(world); + + // [Set] Game + impersonate(PLAYER1()); + let token_id = user_mint_token(context.play_address, erc721_addr, erc20_addr, PLAYER1().into()); + let game_id = systems + .play + .create(token_id, Mode::Daily, context.proof.clone(), context.seed, context.beta); + + let mut game = store.game(game_id); + game.blocks = 0b010010000000000000000000000001001001001001001001000001001001001001001001; + game.combo_counter = 15; + game.combo_counter_2 = 0; + game.combo_counter_in_tournament = 15; + game.combo_counter_in_tournament_2 = 0; + world.write_model_test(@game); + + // [Move] + systems.play.move(1, 6, 7); + + let mut game = store.game(game_id); + + // [Check] Game + assert_eq!(game.combo_counter_2, 17); + assert_eq!(game.combo_counter_in_tournament_2, 17); +} diff --git a/contracts/src/types/bonus.cairo b/contracts/src/types/bonus.cairo index 9804198a..1185655e 100644 --- a/contracts/src/types/bonus.cairo +++ b/contracts/src/types/bonus.cairo @@ -26,7 +26,7 @@ impl BonusImpl of BonusTrait { } #[inline(always)] - fn get_count(self: Bonus, score: u32, combo_count: u8, max_combo: u8) -> u8 { + fn get_count(self: Bonus, score: u32, combo_count: u16, max_combo: u8) -> u8 { match self { Bonus::None => 0, Bonus::Hammer => hammer::BonusImpl::get_count(score, combo_count, max_combo),