Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
starknetdev committed Sep 19, 2023
2 parents 84c485d + 4df24cb commit cf09d9c
Show file tree
Hide file tree
Showing 9 changed files with 923 additions and 1,025 deletions.
76 changes: 39 additions & 37 deletions contracts/adventurer/src/adventurer.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::{
MAX_BLOCK_COUNT, STAT_UPGRADE_POINTS_PER_LEVEL, NECKLACE_G20_BONUS_STATS,
SILVER_RING_G20_LUCK_BONUS, BEAST_SPECIAL_NAME_LEVEL_UNLOCK, U128_MAX
},
discovery_constants::DiscoveryEnums::{ExploreResult, TreasureDiscovery}
discovery_constants::DiscoveryEnums::{ExploreResult, DiscoveryType}
}
};
use pack::{pack::{Packing, rshift_split}, constants::{MASK_16, pow, MASK_8, MASK_BOOL, mask}};
Expand Down Expand Up @@ -325,20 +325,20 @@ impl ImplAdventurer of IAdventurer {
// Possible discoveries include gold, XP, and health.
// @param self: Adventurer to discover treasure for
// @param entropy: Entropy for generating treasure
// @return TreasureDiscovery: The type of treasure discovered.
// @return DiscoveryType: The type of treasure discovered.
// @return u16: The amount of treasure discovered.
fn discover_treasure(self: Adventurer, entropy: u128) -> (TreasureDiscovery, u16) {
fn discover_treasure(self: Adventurer, entropy: u128) -> (DiscoveryType, u16) {
// generate random item discovery
let item_type = ExploreUtils::get_random_discovery(entropy);

match item_type {
TreasureDiscovery::Gold(()) => {
DiscoveryType::Gold(()) => {
// return discovery type and amount
(TreasureDiscovery::Gold(()), ExploreUtils::get_gold_discovery(self, entropy))
(DiscoveryType::Gold(()), ExploreUtils::get_gold_discovery(self, entropy))
},
TreasureDiscovery::Health(()) => {
DiscoveryType::Health(()) => {
// return discovery type and amount
(TreasureDiscovery::Health(()), ExploreUtils::get_health_discovery(self, entropy))
(DiscoveryType::Health(()), ExploreUtils::get_health_discovery(self, entropy))
}
}
}
Expand Down Expand Up @@ -477,7 +477,7 @@ impl ImplAdventurer of IAdventurer {
if (new_level > previous_level) {
// add stat upgrade points
let stat_upgrade_points = (new_level - previous_level) * STAT_UPGRADE_POINTS_PER_LEVEL;
self.stat_points_available.increase_stat_points_available(stat_upgrade_points);
self.increase_stat_points_available(stat_upgrade_points);
}

// return the previous and new levels
Expand All @@ -487,22 +487,23 @@ impl ImplAdventurer of IAdventurer {
// @notice Grants stat upgrades to the Adventurer.
// @dev The function will add the specified value to the stat_points_available up to the maximum limit of MAX_STAT_UPGRADES.
// @param value The amount of stat points to be added to the Adventurer.
fn increase_stat_points_available(ref self: u8, amount: u8) {
#[inline(always)]
fn increase_stat_points_available(ref self: Adventurer, amount: u8) {
// check for u8 overflow
if (u8_overflowing_add(self, amount).is_ok()) {
if (u8_overflowing_add(self.stat_points_available, amount).is_ok()) {
// if overflow is ok
// check if added amount is less than or equal to max upgrade points
if (self + amount <= MAX_STAT_UPGRADES) {
if (self.stat_points_available + amount <= MAX_STAT_UPGRADES) {
// if it is, add upgrade points to adventurer and return
self += amount;
self.stat_points_available += amount;
return;
}
}

// fall through is to return MAX_STAT_UPGRADES
// this will happen either in a u8 overflow case
// or if the upgrade points being added exceeds max upgrade points
self = MAX_STAT_UPGRADES
self.stat_points_available = MAX_STAT_UPGRADES
}

// @notice Increase the Adventurer's strength stat.
Expand Down Expand Up @@ -1271,8 +1272,8 @@ impl ImplAdventurer of IAdventurer {
// @param self A reference to the Adventurer instance.
// @param current_block The current block number.
#[inline(always)]
fn set_last_action(ref self: u16, current_block: u64) {
self = (current_block % MAX_BLOCK_COUNT).try_into().unwrap();
fn set_last_action(ref self: Adventurer, current_block: u64) {
self.last_action = (current_block % MAX_BLOCK_COUNT).try_into().unwrap();
}

// @notice gets a multplier bonus for discoveries based on the Adventurer
Expand Down Expand Up @@ -1431,8 +1432,8 @@ impl ImplAdventurer of IAdventurer {
equipped_items
}

fn get_randomness(self: Adventurer,
adventurer_entropy: u128, global_entropy: u128
fn get_randomness(
self: Adventurer, adventurer_entropy: u128, global_entropy: u128
) -> (u128, u128) {
let mut hash_span = ArrayTrait::<felt252>::new();
hash_span.append(self.xp.into());
Expand All @@ -1443,6 +1444,11 @@ impl ImplAdventurer of IAdventurer {
let (d, r) = rshift_split(poseidon.into(), U128_MAX.into());
return (r.try_into().unwrap(), d.try_into().unwrap());
}

#[inline(always)]
fn can_explore(self: Adventurer) -> bool {
self.health != 0 && self.beast_health == 0 && self.stat_points_available == 0
}
}

// ---------------------------
Expand Down Expand Up @@ -1475,7 +1481,7 @@ mod tests {
MAX_ADVENTURER_BLOCKS, ITEM_MAX_GREATNESS, ITEM_MAX_XP, MAX_ADVENTURER_HEALTH,
CHARISMA_ITEM_DISCOUNT, ClassStatBoosts, MAX_BLOCK_COUNT, SILVER_RING_G20_LUCK_BONUS
},
discovery_constants::DiscoveryEnums::{ExploreResult, TreasureDiscovery}
discovery_constants::DiscoveryEnums::{ExploreResult, DiscoveryType}
}
};
use pack::{pack::{Packing, rshift_split}, constants::{MASK_16, pow, MASK_8, MASK_BOOL, mask}};
Expand Down Expand Up @@ -2280,23 +2286,19 @@ mod tests {

// verify no armor bonus multplier at start
assert(
ImplAdventurer::armor_bonus_multiplier(adventurer) == 1,
'start with no armor bonus'
ImplAdventurer::armor_bonus_multiplier(adventurer) == 1, 'start with no armor bonus'
);

// equip a greatness 1 Amulet
adventurer.neck = ItemPrimitive { id: ItemId::Amulet, xp: 1, metadata: 1 };
// verify there is still no armor bonus
assert(
ImplAdventurer::armor_bonus_multiplier(adventurer) == 1, 'no amulet till g20'
);
assert(ImplAdventurer::armor_bonus_multiplier(adventurer) == 1, 'no amulet till g20');

// increase greatness of amulet to g20
adventurer.neck.xp = 400;
// verify there is now an armor bonus
assert(
ImplAdventurer::armor_bonus_multiplier(adventurer) == 2,
'amulet gives 20% armor bonus'
ImplAdventurer::armor_bonus_multiplier(adventurer) == 2, 'amulet gives 20% armor bonus'
);
}

Expand Down Expand Up @@ -2611,7 +2613,7 @@ mod tests {
}

#[test]
#[available_gas(55630)]
#[available_gas(70930)]
fn test_set_last_action() {
let mut adventurer = ImplAdventurer::new(
12,
Expand All @@ -2620,15 +2622,15 @@ mod tests {
strength: 0, dexterity: 0, vitality: 0, intelligence: 0, wisdom: 0, charisma: 0,
}
);
adventurer.last_action.set_last_action(0);
adventurer.set_last_action(0);
assert(adventurer.last_action == 0, 'last action should be 0');
adventurer.last_action.set_last_action(511);
adventurer.set_last_action(511);
assert(adventurer.last_action == 511, 'last action should be 511');
adventurer.last_action.set_last_action(512);
adventurer.set_last_action(512);
assert(adventurer.last_action == 0, 'last action should be 0');
adventurer.last_action.set_last_action(1023);
adventurer.set_last_action(1023);
assert(adventurer.last_action == 511, 'last action should be 511');
adventurer.last_action.set_last_action(1024);
adventurer.set_last_action(1024);
assert(adventurer.last_action == 0, 'last action should be 0');
}

Expand Down Expand Up @@ -2986,20 +2988,20 @@ mod tests {
let original_stat_points = adventurer.stat_points_available;

// zero case
adventurer.stat_points_available.increase_stat_points_available(0);
adventurer.increase_stat_points_available(0);
assert(
adventurer.stat_points_available == original_stat_points,
'stat points should not change'
);

// base case - adding 1 stat point (no need to pack and unpack this test case)
adventurer.stat_points_available.increase_stat_points_available(1);
adventurer.increase_stat_points_available(1);
assert(
adventurer.stat_points_available == 1 + original_stat_points, 'stat points should be +1'
);

// max stat upgrade value case
adventurer.stat_points_available.increase_stat_points_available(MAX_STAT_UPGRADES);
adventurer.increase_stat_points_available(MAX_STAT_UPGRADES);
assert(adventurer.stat_points_available == MAX_STAT_UPGRADES, 'stat points should be max');

// pack and unpack at max value to ensure our max values are correct for packing
Expand All @@ -3010,7 +3012,7 @@ mod tests {

// extreme/overflow case
adventurer.stat_points_available = 255;
adventurer.stat_points_available.increase_stat_points_available(255);
adventurer.increase_stat_points_available(255);
assert(adventurer.stat_points_available == MAX_STAT_UPGRADES, 'stat points should be max');
}

Expand Down Expand Up @@ -4279,12 +4281,12 @@ mod tests {

// disover gold
let (discovery_type, amount) = adventurer.discover_treasure(0);
assert(discovery_type == TreasureDiscovery::Gold(()), 'should have found gold');
assert(discovery_type == DiscoveryType::Gold(()), 'should have found gold');
assert(amount != 0, 'gold should be non-zero');

// discover health
let (discovery_type, amount) = adventurer.discover_treasure(1);
assert(discovery_type == TreasureDiscovery::Health(()), 'should have found health');
assert(discovery_type == DiscoveryType::Health(()), 'should have found health');
assert(amount != 0, 'health should be non-zero');
}

Expand Down
8 changes: 4 additions & 4 deletions contracts/adventurer/src/adventurer_utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::{
MAX_STAT_VALUE, U128_MAX, ClassStatBoosts, STARTING_HEALTH,
HEALTH_INCREASE_PER_VITALITY, MAX_ADVENTURER_HEALTH
},
discovery_constants::DiscoveryEnums::{ExploreResult, TreasureDiscovery}
discovery_constants::DiscoveryEnums::{ExploreResult, DiscoveryType}
},
adventurer_stats::Stats, adventurer::{Adventurer, ImplAdventurer, IAdventurer},
};
Expand Down Expand Up @@ -54,7 +54,7 @@ impl AdventurerUtils of IAdventurerUtils {
} else if (result == 1) {
ExploreResult::Obstacle(())
} else {
ExploreResult::Treasure(())
ExploreResult::Discovery(())
}
}

Expand Down Expand Up @@ -229,7 +229,7 @@ mod tests {
MAX_STAT_VALUE, U128_MAX, ClassStatBoosts, STARTING_HEALTH,
HEALTH_INCREASE_PER_VITALITY, MAX_ADVENTURER_HEALTH
},
discovery_constants::DiscoveryEnums::{ExploreResult, TreasureDiscovery}
discovery_constants::DiscoveryEnums::{ExploreResult, DiscoveryType}
},
adventurer_stats::Stats, adventurer::{Adventurer, ImplAdventurer, IAdventurer},
adventurer_utils::AdventurerUtils
Expand Down Expand Up @@ -349,7 +349,7 @@ mod tests {

let entropy = 2;
let discovery = AdventurerUtils::get_random_explore(entropy);
assert(discovery == ExploreResult::Treasure(()), 'adventurer should find treasure');
assert(discovery == ExploreResult::Discovery(()), 'adventurer should find treasure');

// rollover and verify beast discovery
let entropy = 3;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const MAX_XP: u16 = 8191; // 2^13 - 1
const MAX_ADVENTURER_BLOCKS: u16 = 512; // 2^9
const STAT_UPGRADE_POINTS_PER_LEVEL: u8 = 1;
const BEAST_SPECIAL_NAME_LEVEL_UNLOCK: u16 = 19;
const XP_FOR_HEALTH_AND_GOLD_DISCOVERIES: u16 = 1;
const XP_FOR_DISCOVERIES: u16 = 1;

// controls how much faster items level up compared to the player
const ITEM_XP_MULTIPLIER_BEASTS: u16 = 2;
Expand Down
4 changes: 2 additions & 2 deletions contracts/adventurer/src/constants/discovery_constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ mod DiscoveryEnums {
enum ExploreResult {
Beast: (),
Obstacle: (),
Treasure: (),
Discovery: (),
}

#[derive(Copy, Drop, PartialEq)]
enum TreasureDiscovery {
enum DiscoveryType {
Gold: (),
Health: (),
}
Expand Down
10 changes: 5 additions & 5 deletions contracts/adventurer/src/exploration.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::traits::{Into, TryInto};
use survivor::{
adventurer::{Adventurer, ImplAdventurer, ItemPrimitive},
constants::discovery_constants::{
DiscoveryEnums::TreasureDiscovery, DiscoveryEnums::ExploreResult
DiscoveryEnums::DiscoveryType, DiscoveryEnums::ExploreResult
}
};
use lootitems::constants::ItemId;
Expand All @@ -13,13 +13,13 @@ use lootitems::constants::ItemId;
impl ExploreUtils of Explore {
// @notice: generates a random discovery {Gold, Health, XP} based on provided entropy
// @param entropy: Entropy to use for random discovery
// @return TreasureDiscovery: The type of discovery
fn get_random_discovery(entropy: u128) -> TreasureDiscovery {
// @return DiscoveryType: The type of discovery
fn get_random_discovery(entropy: u128) -> DiscoveryType {
let discovery_type = entropy % 2;
if (discovery_type == 0) {
TreasureDiscovery::Gold(())
DiscoveryType::Gold(())
} else {
TreasureDiscovery::Health(())
DiscoveryType::Health(())
}
}

Expand Down
5 changes: 4 additions & 1 deletion contracts/game/src/game/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ mod messages {
const ZERO_DEXTERITY: felt252 = 'Cant flee, no dexterity';
const WRONG_STARTING_STATS: felt252 = 'Wrong starting stat count';
const MUST_USE_ALL_STATS: felt252 = 'Must use all stats';
const NO_ITEMS: felt252 = 'Must provide item ids';
}

const BLOCKS_IN_A_WEEK: u64 = 1;
const COST_TO_PLAY: u256 = 25;
const COST_TO_PLAY: u8 = 25;
const STARTING_STATS: u8 = 6;
const IDLE_DEATH_PENALTY_BLOCKS: u8 = 12;
const MIN_BLOCKS_FOR_GAME_ENTROPY_CHANGE: u8 = 25;

const U64_MAX: u64 = 18446744073709551615;
const U128_MAX: u128 = 340282366920938463463374607431768211455;
Expand Down
14 changes: 4 additions & 10 deletions contracts/game/src/game/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@ trait IGame<TContractState> {
ref self: TContractState,
adventurer_id: u256,
potions: u8,
strength: u8,
dexterity: u8,
vitality: u8,
intelligence: u8,
wisdom: u8,
charisma: u8,
stat_upgrades: Stats,
items: Array<ItemPurchase>,
);
fn slay_idle_adventurers(ref self: TContractState, adventurer_ids: Array<u256>);
fn rotate_global_entropy(ref self: TContractState);

// --------- view functions ---------

Expand Down Expand Up @@ -112,14 +108,12 @@ trait IGame<TContractState> {
fn get_beast_tier(self: @TContractState, beast_id: u8) -> u8;

// TODO: Game settings
fn next_global_entropy_rotation(self: @TContractState) -> felt252;

// contract details
fn get_dao_address(self: @TContractState) -> ContractAddress;
fn get_lords_address(self: @TContractState) -> ContractAddress;
fn get_entropy(self: @TContractState) -> u64;

// setters ---------------------------------------------------
fn set_entropy(ref self: TContractState);
fn get_entropy(self: @TContractState) -> u64;

// checks ----------------------------------------------------
fn owner_of(self: @TContractState, adventurer_id: u256) -> ContractAddress;
Expand Down
Loading

0 comments on commit cf09d9c

Please sign in to comment.