Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

contracts & client config: scale building cost #1722

Merged
merged 3 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
setBattleConfig,
setBuildingCategoryPopConfig,
setBuildingConfig,
setBuildingGeneralConfig,
setCapacityConfig,
setCombatConfig,
setHyperstructureConfig,
Expand Down Expand Up @@ -57,6 +58,7 @@ await setBuildingCategoryPopConfig(account, provider);
await setPopulationConfig(account, provider);
await setBuildingConfig(account, provider);
await setResourceBuildingConfig(account, provider);
await setBuildingGeneralConfig(account, provider);
await setWeightConfig(account, provider);
await setCombatConfig(account, provider);
await setBattleConfig(account, provider);
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 @@ -13,6 +13,7 @@
"BankConfig",
"TroopConfig",
"BuildingConfig",
"BuildingGeneralConfig",
"BuildingCategoryPopConfig",
"PopulationConfig",
"HyperstructureResourceConfig",
Expand Down
53 changes: 27 additions & 26 deletions contracts/src/models/buildings.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use core::poseidon::poseidon_hash_span;
use core::zeroable::Zeroable;
use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use eternum::alias::ID;
use eternum::constants::{ResourceTypes, POPULATION_CONFIG_ID};
use eternum::constants::{ResourceTypes, POPULATION_CONFIG_ID, WORLD_CONFIG_ID};
use eternum::models::config::{
TickConfig, TickImpl, TickTrait, ProductionConfig, BuildingConfig, BuildingConfigCustomImpl,
BuildingCategoryPopConfigCustomTrait, PopulationConfig
BuildingCategoryPopConfigCustomTrait, PopulationConfig, BuildingGeneralConfig
};
use eternum::models::owner::{EntityOwner, EntityOwnerCustomTrait};
use eternum::models::population::{Population, PopulationCustomTrait};
Expand All @@ -15,6 +15,7 @@ use eternum::models::production::{
};
use eternum::models::resources::ResourceCustomTrait;
use eternum::models::resources::{Resource, ResourceCustomImpl, ResourceCost};
use eternum::utils::math::{PercentageImpl, PercentageValueImpl};

//todo we need to define border of innner hexes

Expand Down Expand Up @@ -88,22 +89,6 @@ impl BuildingCategoryIntoFelt252 of Into<BuildingCategory, felt252> {
}


#[generate_trait]
impl BonusPercentageImpl of BonusPercentageTrait {
fn _1() -> u128 {
100
}

fn _10() -> u128 {
1_000
}

fn _100() -> u128 {
10_000
}
}


#[generate_trait]
impl BuildingProductionCustomImpl of BuildingProductionCustomTrait {
fn is_resource_producer(self: Building) -> bool {
Expand Down Expand Up @@ -138,7 +123,7 @@ impl BuildingProductionCustomImpl of BuildingProductionCustomTrait {
BuildingCategory::None => 0,
BuildingCategory::Castle => 0,
BuildingCategory::Resource => 0,
BuildingCategory::Farm => BonusPercentageImpl::_10().try_into().unwrap(), // 10%
BuildingCategory::Farm => PercentageValueImpl::_10().try_into().unwrap(), // 10%
BuildingCategory::FishingVillage => 0,
BuildingCategory::Barracks => 0,
BuildingCategory::Market => 0,
Expand Down Expand Up @@ -293,7 +278,7 @@ impl BuildingProductionCustomImpl of BuildingProductionCustomTrait {
let production_config: ProductionConfig = get!(world, produced_resource_type, ProductionConfig);

let bonus_amount: u128 = (production_config.amount * (*self.bonus_percent).into())
/ BonusPercentageImpl::_100();
/ PercentageValueImpl::_100().into();

production_config.amount + bonus_amount
}
Expand Down Expand Up @@ -428,7 +413,7 @@ impl BuildingCustomImpl of BuildingCustomTrait {
category: BuildingCategory,
produce_resource_type: Option<u8>,
inner_coord: Coord
) -> Building {
) -> (Building, BuildingQuantityv2) {
// check that the entity has a position
let outer_entity_position = get!(world, outer_entity_id, Position);
outer_entity_position.assert_not_zero();
Expand Down Expand Up @@ -488,7 +473,7 @@ impl BuildingCustomImpl of BuildingCustomTrait {
// set population
set!(world, (population));

building
(building, building_quantity)
}

/// Pause building production without removing the building
Expand Down Expand Up @@ -598,17 +583,33 @@ impl BuildingCustomImpl of BuildingCustomTrait {
destroyed_building_category
}
edisontim marked this conversation as resolved.
Show resolved Hide resolved

fn make_payment(world: IWorldDispatcher, entity_id: ID, category: BuildingCategory, resource_type: u8) {
let building_config: BuildingConfig = BuildingConfigCustomImpl::get(world, category, resource_type);
fn make_payment(self: Building, building_quantity: BuildingQuantityv2, world: IWorldDispatcher) {
let building_general_config: BuildingGeneralConfig = get!(world, WORLD_CONFIG_ID, BuildingGeneralConfig);
let building_config: BuildingConfig = BuildingConfigCustomImpl::get(
world, self.category, self.produced_resource_type
);
let mut index = 0;
loop {
if index == building_config.resource_cost_count {
break;
}

// calculate cost of building based on the formula:
// Cost = Base + (Base * Rate * (N - 1)²)
// Where:
// Base = The cost of the first building
// Rate = How quickly the cost goes up (a small number like 0.1 or 0.2)
// N = Which number building this is (1st, 2nd, 3rd, etc.)
//
let resource_cost: ResourceCost = get!(world, (building_config.resource_cost_id, index), ResourceCost);
let mut resource = ResourceCustomImpl::get(world, (entity_id, resource_cost.resource_type));
resource.burn(resource_cost.amount);
let mut resource = ResourceCustomImpl::get(world, (self.outer_entity_id, resource_cost.resource_type));
let percentage_additional_cost = PercentageImpl::get(
resource_cost.amount, building_general_config.base_cost_percent_increase.into()
);
let scale_factor = building_quantity.value - 1;
let total_cost = resource_cost.amount
+ (scale_factor.into() * scale_factor.into() * percentage_additional_cost);
resource.burn(total_cost);
resource.save(world);
index += 1;
};
Expand Down
9 changes: 9 additions & 0 deletions contracts/src/models/config.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ pub struct BankConfig {
lp_fee_denom: u128,
}

#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct BuildingGeneralConfig {
#[key]
config_id: ID,
base_cost_percent_increase: u16,
}


#[derive(Copy, Drop, Serde)]
#[dojo::model]
pub struct BuildingConfig {
Expand Down
8 changes: 3 additions & 5 deletions contracts/src/systems/buildings/contracts.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,12 @@ mod building_systems {
get!(world, entity_id, EntityOwner).assert_caller_owner(world);

// todo: check that entity is a realm
let building: Building = BuildingCustomImpl::create(
let (building, building_quantity) = BuildingCustomImpl::create(
world, entity_id, building_category, produce_resource_type, building_coord
);

// make payment for building
BuildingCustomImpl::make_payment(
world, building.outer_entity_id, building.category, building.produced_resource_type
);
// pay one time cost of the building
building.make_payment(building_quantity, world);
}
fn pause_production(ref world: IWorldDispatcher, entity_id: ID, building_coord: Coord) {
BuildingCustomImpl::pause_production(world, entity_id, building_coord);
Expand Down
9 changes: 8 additions & 1 deletion contracts/src/systems/config/contracts.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ trait ITroopConfig {

#[dojo::interface]
trait IBuildingConfig {
fn set_building_general_config(ref world: IWorldDispatcher, base_cost_percent_increase: u16);
fn set_building_config(
ref world: IWorldDispatcher,
building_category: BuildingCategory,
Expand Down Expand Up @@ -149,7 +150,7 @@ mod config_systems {
CapacityConfig, SpeedConfig, WeightConfig, WorldConfig, LevelingConfig, RealmFreeMintConfig, MapConfig,
TickConfig, ProductionConfig, BankConfig, TroopConfig, BuildingConfig, BuildingCategoryPopConfig,
PopulationConfig, HyperstructureResourceConfig, HyperstructureConfig, StaminaConfig, StaminaRefillConfig,
MercenariesConfig, BattleConfig, TravelStaminaCostConfig
MercenariesConfig, BattleConfig, TravelStaminaCostConfig, BuildingGeneralConfig
};

use eternum::models::position::{Position, PositionCustomTrait, Coord};
Expand Down Expand Up @@ -528,6 +529,12 @@ mod config_systems {

#[abi(embed_v0)]
impl BuildingConfigCustomImpl of super::IBuildingConfig<ContractState> {
fn set_building_general_config(ref world: IWorldDispatcher, base_cost_percent_increase: u16) {
assert_caller_is_admin(world);

set!(world, BuildingGeneralConfig { config_id: WORLD_CONFIG_ID, base_cost_percent_increase });
}

fn set_building_config(
ref world: IWorldDispatcher,
building_category: BuildingCategory,
Expand Down
10 changes: 10 additions & 0 deletions sdk/packages/eternum/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ARMY_ENTITY_TYPE,
BASE_POPULATION_CAPACITY,
BUILDING_CAPACITY,
BUILDING_FIXED_COST_SCALE_PERCENT,
BUILDING_POPULATION,
BUILDING_RESOURCE_PRODUCED,
DONKEY_ENTITY_TYPE,
Expand Down Expand Up @@ -72,6 +73,15 @@ export const setBuildingCategoryPopConfig = async (account: Account, provider: E
console.log(`Configuring building category population ${tx.statusReceipt}...`);
};

export const setBuildingGeneralConfig = async (account: Account, provider: EternumProvider) => {
const tx = await provider.set_building_general_config({
signer: account,
base_cost_percent_increase: BUILDING_FIXED_COST_SCALE_PERCENT,
});

console.log(`Configuring building general config ${tx.statusReceipt}...`);
};

export const setPopulationConfig = async (account: Account, provider: EternumProvider) => {
const tx = await provider.set_population_config({
signer: account,
Expand Down
2 changes: 1 addition & 1 deletion sdk/packages/eternum/src/constants/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export const ONE_MONTH = 2628000;

// Buildings
export const BASE_POPULATION_CAPACITY = 5;

export const BUILDING_FIXED_COST_SCALE_PERCENT = 5_000; // 5_000/10_000 = 50%
// Points
export const HYPERSTRUCTURE_POINTS_PER_CYCLE = 10;
export const HYPERSTRUCTURE_POINTS_ON_COMPLETION = 2_000_000; // about the amount of points generated by the structure in 2 days
Expand Down
10 changes: 10 additions & 0 deletions sdk/packages/eternum/src/provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,16 @@ export class EternumProvider extends EnhancedDojoProvider {
);
}

public async set_building_general_config(props: SystemProps.SetBuildingGeneralConfigProps) {
const { base_cost_percent_increase, signer } = props;

return await this.executeAndCheckTransaction(signer, {
contractAddress: getContractByName(this.manifest, `${NAMESPACE}-config_systems`),
entrypoint: "set_building_general_config",
calldata: [base_cost_percent_increase],
});
}

public async set_population_config(props: SystemProps.SetPopulationConfigProps) {
const { base_population, signer } = props;

Expand Down
4 changes: 4 additions & 0 deletions sdk/packages/eternum/src/types/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ export interface SetBuildingCategoryPopConfigProps extends SystemSigner {
calls: { building_category: BuildingType; population: num.BigNumberish; capacity: num.BigNumberish }[];
}

export interface SetBuildingGeneralConfigProps extends SystemSigner {
base_cost_percent_increase: num.BigNumberish;
}

export interface SetPopulationConfigProps extends SystemSigner {
base_population: num.BigNumberish;
}
Expand Down
Loading