Skip to content

Commit

Permalink
Limit army (#1141)
Browse files Browse the repository at this point in the history
* contract: limit armies and enable deletion

* contracts: delete army if merging kills troop

* contracts: bug fixes from v1 branch

* update test
  • Loading branch information
credence0x authored Jul 26, 2024
1 parent a7ea0e1 commit 30b3da6
Show file tree
Hide file tree
Showing 16 changed files with 17,269 additions and 5,866 deletions.
5 changes: 5 additions & 0 deletions client/src/dojo/createSystemCalls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ export function createSystemCalls({ provider }: SetupNetworkResult) {
await provider.create_army(props);
};

const delete_army = async (props: SystemProps.ArmyDeleteProps) => {
await provider.delete_army(props);
};

const army_buy_troops = async (props: SystemProps.ArmyBuyTroopsProps) => {
await provider.army_buy_troops(props);
};
Expand Down Expand Up @@ -288,6 +292,7 @@ export function createSystemCalls({ provider }: SetupNetworkResult) {
destroy_building,
create_building,
create_army,
delete_army,
uuid,
create_hyperstructure,
contribute_to_construction,
Expand Down
56 changes: 47 additions & 9 deletions contracts/manifests/dev/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@
],
"address": "0x161b08e252b353008665e85ab5dcb0044a61186eb14b999657d14c04c94c824",
"transaction_hash": "0x612de8b84ba9c5454887b576a17af10b7be97dab5f01bf79d1ec2d3cca3e6c5",
"block_number": 28,
"block_number": 17,
"seed": "eternum",
"metadata": {
"profile_name": "dev",
Expand Down Expand Up @@ -1976,8 +1976,8 @@
{
"kind": "DojoContract",
"address": "0xca567be002d22ad080bf3ed80d869374022ee3d215462da7b048543dd79535",
"class_hash": "0x72d03b34f40b7cfc8fc04117d877cacef2efdbd7552b4051caf3e9e032b6a56",
"original_class_hash": "0x72d03b34f40b7cfc8fc04117d877cacef2efdbd7552b4051caf3e9e032b6a56",
"class_hash": "0x5e7fa715b0a5f674e5de150580bc2e5ee77f82d5d6f8501a091c261b7680cfb",
"original_class_hash": "0x5e7fa715b0a5f674e5de150580bc2e5ee77f82d5d6f8501a091c261b7680cfb",
"base_class_hash": "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46",
"abi": [
{
Expand Down Expand Up @@ -2113,6 +2113,18 @@
],
"state_mutability": "external"
},
{
"type": "function",
"name": "army_delete",
"inputs": [
{
"name": "army_id",
"type": "core::integer::u128"
}
],
"outputs": [],
"state_mutability": "external"
},
{
"type": "function",
"name": "army_buy_troops",
Expand Down Expand Up @@ -2330,8 +2342,8 @@
{
"kind": "DojoContract",
"address": "0x73f0efc06b135109b40f185f2a04a3a30e317f189642958f4f6848c1bb95a8e",
"class_hash": "0x6ac03a6cf52309eb6eb3e0e2feaf789e5b5de19b106af0c8839f7ce904b9bf4",
"original_class_hash": "0x6ac03a6cf52309eb6eb3e0e2feaf789e5b5de19b106af0c8839f7ce904b9bf4",
"class_hash": "0x321c29c1aa10326d7cad494b8b5a6adfa3debabee856097e5675707ac877133",
"original_class_hash": "0x321c29c1aa10326d7cad494b8b5a6adfa3debabee856097e5675707ac877133",
"base_class_hash": "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46",
"abi": [
{
Expand Down Expand Up @@ -2826,6 +2838,14 @@
{
"name": "pillage_health_divisor",
"type": "core::integer::u8"
},
{
"name": "army_free_per_structure",
"type": "core::integer::u8"
},
{
"name": "army_extra_per_building",
"type": "core::integer::u8"
}
]
},
Expand Down Expand Up @@ -4159,8 +4179,8 @@
{
"kind": "DojoContract",
"address": "0x1723599f44e8b02ac7893a4bcc993a9aa55729f0a91ee94bc5d57589a5276b5",
"class_hash": "0x360daf3f7d29d723464755db2f4044d556c121feb3dce34507d4b2bb5eef5d5",
"original_class_hash": "0x360daf3f7d29d723464755db2f4044d556c121feb3dce34507d4b2bb5eef5d5",
"class_hash": "0x7186d1f6f884ec6a97e8aa121905c69ae3d2125e6f3fcaf7685ef66db5faefa",
"original_class_hash": "0x7186d1f6f884ec6a97e8aa121905c69ae3d2125e6f3fcaf7685ef66db5faefa",
"base_class_hash": "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46",
"abi": [
{
Expand Down Expand Up @@ -17594,10 +17614,20 @@
"name": "pillage_health_divisor",
"type": "u8",
"key": false
},
{
"name": "army_free_per_structure",
"type": "u8",
"key": false
},
{
"name": "army_extra_per_building",
"type": "u8",
"key": false
}
],
"class_hash": "0x1086ff74ee20d703dc4e469b5606738d914c803eae8b8741481176de56ac888",
"original_class_hash": "0x1086ff74ee20d703dc4e469b5606738d914c803eae8b8741481176de56ac888",
"class_hash": "0x34967626060789bcfdbf317a8635c387fad8b0f38fcac085319d592bd3bedc4",
"original_class_hash": "0x34967626060789bcfdbf317a8635c387fad8b0f38fcac085319d592bd3bedc4",
"abi": [
{
"type": "impl",
Expand Down Expand Up @@ -17957,6 +17987,14 @@
{
"name": "pillage_health_divisor",
"type": "core::integer::u8"
},
{
"name": "army_free_per_structure",
"type": "core::integer::u8"
},
{
"name": "army_extra_per_building",
"type": "core::integer::u8"
}
]
},
Expand Down
28 changes: 19 additions & 9 deletions contracts/manifests/dev/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ original_class_hash = "0x3f63cecdc4964acafb921ba2934c6507d1b3c344edb64c2762cf080
abi = "manifests/dev/abis/deployments/dojo_world_world.json"
address = "0x161b08e252b353008665e85ab5dcb0044a61186eb14b999657d14c04c94c824"
transaction_hash = "0x612de8b84ba9c5454887b576a17af10b7be97dab5f01bf79d1ec2d3cca3e6c5"
block_number = 28
block_number = 17
seed = "eternum"
name = "dojo::world::world"

Expand Down Expand Up @@ -74,8 +74,8 @@ name = "eternum::systems::buildings::contracts::building_systems"
[[contracts]]
kind = "DojoContract"
address = "0xca567be002d22ad080bf3ed80d869374022ee3d215462da7b048543dd79535"
class_hash = "0x72d03b34f40b7cfc8fc04117d877cacef2efdbd7552b4051caf3e9e032b6a56"
original_class_hash = "0x72d03b34f40b7cfc8fc04117d877cacef2efdbd7552b4051caf3e9e032b6a56"
class_hash = "0x5e7fa715b0a5f674e5de150580bc2e5ee77f82d5d6f8501a091c261b7680cfb"
original_class_hash = "0x5e7fa715b0a5f674e5de150580bc2e5ee77f82d5d6f8501a091c261b7680cfb"
base_class_hash = "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46"
abi = "manifests/dev/abis/deployments/contracts/eternum_systems_combat_contracts_combat_systems.json"
reads = []
Expand All @@ -87,8 +87,8 @@ name = "eternum::systems::combat::contracts::combat_systems"
[[contracts]]
kind = "DojoContract"
address = "0x73f0efc06b135109b40f185f2a04a3a30e317f189642958f4f6848c1bb95a8e"
class_hash = "0x6ac03a6cf52309eb6eb3e0e2feaf789e5b5de19b106af0c8839f7ce904b9bf4"
original_class_hash = "0x6ac03a6cf52309eb6eb3e0e2feaf789e5b5de19b106af0c8839f7ce904b9bf4"
class_hash = "0x321c29c1aa10326d7cad494b8b5a6adfa3debabee856097e5675707ac877133"
original_class_hash = "0x321c29c1aa10326d7cad494b8b5a6adfa3debabee856097e5675707ac877133"
base_class_hash = "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46"
abi = "manifests/dev/abis/deployments/contracts/eternum_systems_config_contracts_config_systems.json"
reads = []
Expand Down Expand Up @@ -165,8 +165,8 @@ name = "eternum::systems::leveling::contracts::leveling_systems"
[[contracts]]
kind = "DojoContract"
address = "0x1723599f44e8b02ac7893a4bcc993a9aa55729f0a91ee94bc5d57589a5276b5"
class_hash = "0x360daf3f7d29d723464755db2f4044d556c121feb3dce34507d4b2bb5eef5d5"
original_class_hash = "0x360daf3f7d29d723464755db2f4044d556c121feb3dce34507d4b2bb5eef5d5"
class_hash = "0x7186d1f6f884ec6a97e8aa121905c69ae3d2125e6f3fcaf7685ef66db5faefa"
original_class_hash = "0x7186d1f6f884ec6a97e8aa121905c69ae3d2125e6f3fcaf7685ef66db5faefa"
base_class_hash = "0x22f3e55b61d86c2ac5239fa3b3b8761f26b9a5c0b5f61ddbd5d756ced498b46"
abi = "manifests/dev/abis/deployments/contracts/eternum_systems_map_contracts_map_systems.json"
reads = []
Expand Down Expand Up @@ -1069,8 +1069,8 @@ key = false

[[models]]
kind = "DojoModel"
class_hash = "0x1086ff74ee20d703dc4e469b5606738d914c803eae8b8741481176de56ac888"
original_class_hash = "0x1086ff74ee20d703dc4e469b5606738d914c803eae8b8741481176de56ac888"
class_hash = "0x34967626060789bcfdbf317a8635c387fad8b0f38fcac085319d592bd3bedc4"
original_class_hash = "0x34967626060789bcfdbf317a8635c387fad8b0f38fcac085319d592bd3bedc4"
abi = "manifests/dev/abis/deployments/models/eternum_models_config_troop_config.json"
name = "eternum::models::config::troop_config"

Expand Down Expand Up @@ -1114,6 +1114,16 @@ name = "pillage_health_divisor"
type = "u8"
key = false

[[models.members]]
name = "army_free_per_structure"
type = "u8"
key = false

[[models.members]]
name = "army_extra_per_building"
type = "u8"
key = false

[[models]]
kind = "DojoModel"
class_hash = "0x9dee9ab8f304143c7db802918b2e219f59071f374ea378b35d3e717456cefb"
Expand Down
1 change: 1 addition & 0 deletions contracts/scripts/system_models.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
"Movable",
"Resource",
"Production",
"QuantityTracker",
"OwnedResourcesTracker",
"Owner",
"Capacity",
Expand Down
15 changes: 1 addition & 14 deletions contracts/src/models/buildings.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::poseidon::poseidon_hash_span as hash;
use core::poseidon::poseidon_hash_span;
use core::zeroable::Zeroable;
use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use eternum::constants::{ResourceTypes, POPULATION_CONFIG_ID};
Expand Down Expand Up @@ -87,19 +87,6 @@ impl BuildingCategoryIntoFelt252 of Into<BuildingCategory, felt252> {
}


#[generate_trait]
impl BuildingQuantityv2TrackerImpl of BuildingQuantityv2TrackerTrait {
fn salt() -> felt252 {
'building_quantity'
}
fn key(entity_id: u128, category: felt252, resource_type: u8) -> felt252 {
let q: Array<felt252> = array![
entity_id.into(), Self::salt(), category, resource_type.into()
];
hash(q.span())
}
}

#[generate_trait]
impl BonusPercentageImpl of BonusPercentageTrait {
fn _1() -> u128 {
Expand Down
37 changes: 29 additions & 8 deletions contracts/src/models/combat.cairo
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use core::array::ArrayTrait;
use core::integer::BoundedInt;
use core::option::OptionTrait;
use core::poseidon::poseidon_hash_span;
use core::traits::Into;
use core::traits::TryInto;
use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use eternum::alias::ID;
use eternum::constants::all_resource_ids;
use eternum::models::capacity::{Capacity, CapacityTrait};
use eternum::models::config::{BattleConfig, BattleConfigImpl, BattleConfigTrait};
use eternum::models::config::{TroopConfig, TroopConfigImpl, TroopConfigTrait};
use eternum::models::config::{WeightConfig, WeightConfigImpl};
use eternum::models::quantity::{Quantity, QuantityTrait};
use eternum::models::quantity::{Quantity, QuantityTracker, QuantityTrackerType, QuantityTrait};
use eternum::models::resources::OwnedResourcesTrackerTrait;
use eternum::models::resources::ResourceTrait;
use eternum::models::resources::ResourceTransferLockTrait;
Expand All @@ -20,10 +22,9 @@ use eternum::models::resources::{
use eternum::models::structure::{Structure, StructureImpl};
use eternum::models::weight::Weight;
use eternum::models::weight::WeightTrait;
use eternum::utils::math::{PercentageImpl, PercentageValueImpl, min};
use eternum::utils::math::{PercentageImpl, PercentageValueImpl, min, max};
use eternum::utils::number::NumberTrait;


const STRENGTH_PRECISION: u256 = 10_000;


Expand Down Expand Up @@ -74,7 +75,12 @@ impl HealthImpl of HealthTrait {
num_steps += 1;
}

num_steps
// this condition is here in case
// self.current < deduction which would make
// num_steps = 0 but that would cause the
// "inaccurate winner invariant" error so we make it
// at least 1.
max(num_steps, 1)
}

fn percentage_left(self: Health) -> u128 {
Expand All @@ -86,7 +92,7 @@ impl HealthImpl of HealthTrait {
}


#[derive(Copy, Drop, Serde, Introspect, Default)]
#[derive(Copy, Drop, Serde, Introspect, Debug, PartialEq, Default)]
struct Troops {
knight_count: u64,
paladin_count: u64,
Expand Down Expand Up @@ -312,6 +318,12 @@ impl TroopsImpl of TroopsTrait {
}
}

#[generate_trait]
impl ArmyQuantityTracker of ArmyQuantityTrackerTrait {
fn key(entity_id: ID) -> felt252 {
poseidon_hash_span(array![entity_id.into(), QuantityTrackerType::ARMY_COUNT.into()].span())
}
}

#[derive(Copy, Drop, Serde, Default)]
#[dojo::model]
Expand Down Expand Up @@ -476,7 +488,7 @@ struct Battle {
}


#[derive(Copy, Drop, Serde, PartialEq, Introspect)]
#[derive(Copy, Drop, Serde, PartialEq, Debug, Introspect)]
enum BattleSide {
None,
Attack,
Expand Down Expand Up @@ -565,7 +577,14 @@ impl BattleEscrowImpl of BattleEscrowTrait {
.is_structure();

let winner_side: BattleSide = self.winner();
let to_army_lost = (winner_side != to_army.battle_side && winner_side != BattleSide::None);
let to_army_dead = to_army.troops.count().is_zero();

// the reason for checking if `to_army_dead` is `true` is that
// it's possible for the battle be a draw and both sides die in the process.
// if this edge case occurs, we assume they both lost for the purpose of this
// function. They both forfeit their balances.
let to_army_lost = to_army_dead
|| (winner_side != to_army.battle_side && winner_side != BattleSide::None);
let to_army_won = (winner_side == to_army.battle_side && winner_side != BattleSide::None);
let to_army_lost_or_battle_not_ended = !self.has_ended()
|| (self.has_ended() && to_army_lost);
Expand Down Expand Up @@ -804,7 +823,9 @@ mod tests {
crossbowman_strength: 1,
advantage_percent: 1000,
disadvantage_percent: 1000,
pillage_health_divisor: 8
pillage_health_divisor: 8,
army_free_per_structure: 100,
army_extra_per_building: 100,
}
}

Expand Down
8 changes: 7 additions & 1 deletion contracts/src/models/config.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,13 @@ struct TroopConfig {
// get to losing 12.5% each. If an army is far stronger than the order,
// they lose a small precentage (it goes closer to 0% health loss) while the
// weak army's loss is closer to 12.5%
pillage_health_divisor: u8
pillage_health_divisor: u8,
// the number of armies that can be created per structure
// before military buildings are required to create more
army_free_per_structure: u8,
// the number of additional armies that can be create with
// each new military building
army_extra_per_building: u8,
}


Expand Down
3 changes: 3 additions & 0 deletions contracts/src/models/quantity.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ struct QuantityTracker {
count: u128,
}

mod QuantityTrackerType {
const ARMY_COUNT: felt252 = 'army_quantity';
}
4 changes: 1 addition & 3 deletions contracts/src/models/resources.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use debug::PrintTrait;
use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use eternum::constants::{ResourceTypes, resource_type_name};
use eternum::constants::{get_resource_probabilities, RESOURCE_PRECISION, BASE_STOREHOUSE_CAPACITY};
use eternum::models::buildings::{
Building, BuildingTrait, BuildingQuantityv2TrackerImpl, BuildingCategory, BuildingQuantityv2
};
use eternum::models::buildings::{Building, BuildingTrait, BuildingCategory, BuildingQuantityv2};
use eternum::models::config::{ProductionConfig, TickConfig, TickImpl, TickTrait};

use eternum::models::production::{Production, ProductionOutputImpl, ProductionRateTrait};
Expand Down
Loading

0 comments on commit 30b3da6

Please sign in to comment.