Skip to content

Commit

Permalink
new production wip
Browse files Browse the repository at this point in the history
  • Loading branch information
credence0x committed Jan 8, 2025
1 parent 41cebe2 commit c2051d5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 37 deletions.
3 changes: 2 additions & 1 deletion contracts/game/src/constants.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ mod ResourceTypes {
// e.g Stone labor = 255 - 1 = 254
}

const LAST_REGULAR_RESOURCE_ID: u8 = 31;
fn resource_type_name(resource_type: u8) -> ByteArray {
if resource_type == 1 {
"STONE"
Expand Down Expand Up @@ -174,7 +175,7 @@ fn resource_type_name(resource_type: u8) -> ByteArray {
"LORDS"
} else if resource_type == 30 {
"WHEAT"
} else if resource_type == 31 {
} else if resource_type == LAST_REGULAR_RESOURCE_ID {
"FISH"

// LABOR
Expand Down
7 changes: 2 additions & 5 deletions contracts/game/src/models/buildings.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,9 @@ impl BuildingProductionImpl of BuildingProductionTrait {

// get labor resource
let mut labor_resource_type
= LaborImpl::labor_type_from_resource(produced_resource_type);

// we expect labor resource to not be produceable so it's okay to
// read it from the world storage rather than the resourceimpl::get()
= LaborImpl::labor_resource_from_regular(produced_resource_type);
let mut labor_resource: Resource
= world.read_model((self.outer_entity_id, labor_resource_type));
= ResourceImpl::get(ref world, (self.outer_entity_id, labor_resource_type));

// update production labor finish tick
let production_config: ProductionConfig = world.read_model(produced_resource_type);
Expand Down
13 changes: 11 additions & 2 deletions contracts/game/src/models/production/labor.cairo
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use dojo::model::ModelStorage;
use dojo::world::WorldStorage;
use s0_eternum::alias::ID;
use s0_eternum::constants::{LAST_REGULAR_RESOURCE_ID};
use s0_eternum::models::config::{LaborConfig};
use s0_eternum::models::config::{TickConfig, TickImpl, TickTrait};
use s0_eternum::models::resources::{Resource, ResourceImpl};
Expand All @@ -9,10 +10,18 @@ use s0_eternum::models::resources::{Resource, ResourceImpl};
#[generate_trait]
impl LaborImpl LaborTrait {

fn labor_type_from_resource(resource_type: u8) -> u8 {
fn labor_resource_from_regular(resource_type: u8) -> u8 {
return 255 - resource_type;
}

fn resource_from_labor(labor_type: u8) -> u8 {
return 255 - labor_type;
}

fn is_labor(resource_type: u8) -> bool {
return resource_type != 255 && resource_type >= 255 - LAST_LABOR_RESOURCE_ID;
}

fn make_labor(ref world: WorldStorage, entity_id: ID, resource_type: u8, labor_amount: u128) {

assert!(resource_type.is_non_zero(), "can't make labor for 0 resource");
Expand All @@ -37,7 +46,7 @@ impl LaborImpl LaborTrait {
}

// make labor resource
let labor_resource_type = Self::labor_type_from_resource(resource_type);
let labor_resource_type = Self::labor_resource_from_regular(resource_type);
let labor_resource = ResourceImpl::get(ref world, (entity_id, labor_resource_type));
labor_resource.add(labor_amount);
labor_resource.save(ref world);
Expand Down
2 changes: 1 addition & 1 deletion contracts/game/src/models/production/production.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl ProductionLaborImpl of ProductionLaborTrait {
let labor_cost_per_tick = (*production_config).labor_amount;
assert!(labor_cost_per_tick.is_non_zero(), "labor cost amount not set");

let labor_tick_amount = labor.balance / labor_cost_per_tick;
let labor_tick_amount = labor.balance / (labor_cost_per_tick * connected_production.building_count.into());
connected_production.labor_finish_tick = (*tick).current() + labor_tick_amount;
connected_production.last_updated_tick = (*tick).current();
}
Expand Down
95 changes: 67 additions & 28 deletions contracts/game/src/models/resources.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use s0_eternum::models::config::{
};
use s0_eternum::models::config::{WeightConfigImpl, WeightConfig};

use s0_eternum::models::production::{Production, ProductionOutputImpl, ProductionRateTrait};
use s0_eternum::models::production::{Production, ProductionTrait, ProductionLaborImpl};
use s0_eternum::models::production::labor::{LaborImpl, LaborTrait};
use s0_eternum::models::realm::Realm;
use s0_eternum::models::structure::StructureTrait;
use s0_eternum::models::structure::{Structure, StructureCategory};
Expand Down Expand Up @@ -171,17 +172,32 @@ impl ResourceFoodImpl of ResourceFoodTrait {
impl ResourceImpl of ResourceTrait {
fn get(ref world: WorldStorage, key: (ID, u8)) -> Resource {
let mut resource: Resource = world.read_model(key);
assert!(resource.resource_type.is_non_zero(), "resource type not found");
assert!(resource.entity_id.is_non_zero(), "entity id not found");

resource.harvest(ref world);

// if resource is labor, we need to update the production

// how to know if resource is labor?
// 255 - resource_type > 200

// we check production of resource for
assert!(
resource.resource_type != 0,
&& resource.resource_type != 255,
&& resource.resource_type <= LAST_REGULAR_RESOURCE_ID, // regular resources
&& resource.resource_type >= 255 - LAST_LABOR_RESOURCE_ID, // labor resources
"resource type not found"
);

let entity_structure: Structure = world.read_model(self.entity_id);
let entity_is_structure = entity_structure.is_structure();
if entity_is_structure {
if LaborImpl::is_labor(resource.resource_type) {
let regular_resource_type = LaborImpl::resource_from_labor(resource.resource_type);
let mut regular_resource: Resource
= world.read_model((resource.entity_id, regular_resource_type));
let labor_resource = resource;
regular_resource.update(ref labor_resource, ref world);
} else {
let labor_resource_type = LaborImpl::labor_resource_from_regular(self.resource_type);
let mut labor_resource: Resource = world.read_model((self.entity_id, labor_resource_type));
let regular_resource = resource;
regular_resource.update(ref labor_resource, ref world);
}
}


return resource;
}
Expand Down Expand Up @@ -212,27 +228,42 @@ impl ResourceImpl of ResourceTrait {
return;
};

// ensure realm has enough store houses to keep resource balance
let entity_structure: Structure = world.read_model(self.entity_id);
let entity_is_structure = entity_structure.is_structure();
if entity_is_structure {
if entity_structure.is_structure() {
// limit balance by storehouse capacity
self.limit_balance_by_storehouse_capacity(ref world);

// update the related production when labor resource is updated
if LaborImpl::is_labor(self.resource_type) {
let regular_resource_type = LaborImpl::resource_from_labor(resource.resource_type);
let mut regular_resource_production: Production
= world.read_model((self.entity_id, regular_resource_type));

if regular_resource_production.has_building() {
// check that the connected resource has already harvested production
let tick = TickImpl::get_default_tick_config(ref world);
assert!(
regular_resource_production.last_updated_tick == tick.current(),
"{} production has not been harvested", resource_type_name(regular_resource_type)
);

// update labor finish time
let production_config: ProductionConfig = world.read_model(regular_resource_type);
ProductionLaborImpl::update_connected_production(
ref labor_resource,
ref regular_resource_production,
@tick, @production_config
);
world.write_model(@regular_resource_production);
}
}
}

// save the updated resource
world.write_model(@self);

if entity_is_structure {
// sync end ticks of resources that use this resource in their production
// e.g `self` may be wheat resource and is stone, coal and gold are used
// in production of wheat, we update their exhaustion ticks
ProductionOutputImpl::sync_all_inputs_exhaustion_ticks_for(@self, ref world);
}

// Update the entity's owned resources tracker

// update the entity's resource tracker
let mut entity_owned_resources: OwnedResourcesTracker = world.read_model(self.entity_id);

if self.balance == 0 {
if entity_owned_resources.owns_resource_type(self.resource_type) {
entity_owned_resources.set_resource_ownership(self.resource_type, false);
Expand Down Expand Up @@ -273,20 +304,28 @@ impl ResourceImpl of ResourceTrait {
let storehouse_capacity_grams_with_precision = storehouse_capacity_grams * RESOURCE_PRECISION;

let max_weight_grams = min(resource_weight_grams_with_precision, storehouse_capacity_grams_with_precision);

let max_balance = max_weight_grams / resource_weight_config.weight_gram;

self.balance = max_balance
}

fn harvest(ref self: Resource, ref world: WorldStorage) {
fn update(ref self: Resource, ref labor_resource: Resource, ref world: WorldStorage) {
let mut production: Production = world.read_model((self.entity_id, self.resource_type));
let tick = TickImpl::get_default_tick_config(ref world);
if production.is_active() && production.last_updated_tick != tick.current() {
production.harvest(ref self, @tick);
if production.has_building() && production.last_updated_tick != tick.current() {

// harvest the production
let production_config: ProductionConfig = world.read_model(produced_resource_type);
production.harvest(ref self, ref labor_resource, @tick, @production_config);

// limit balance by storehouse capacity
self.limit_balance_by_storehouse_capacity(ref world);
labor_resource.limit_balance_by_storehouse_capacity(ref world);

// save the updated resources
world.write_model(@self);
world.write_model(@production);
world.write_model(@labor_resource);
}
}
}
Expand Down

0 comments on commit c2051d5

Please sign in to comment.