screeps/constants/numbers.rs
1//! Plain data constants and functions returning plain data.
2use super::types::{ResourceType, StructureType};
3
4// OK and ERR_* defined in ReturnCode in `small_enums.rs`
5
6// FIND_* defined in `find.rs`
7
8// directions and COLOR_* defined in `small_enums.rs`
9
10// LOOK_* defined in `look.rs`
11
12// OBSTACLE_OBJECT_TYPES not yet implemented
13
14// BODYPART_COST defined in `small_enums.rs`
15
16// WORLD_WIDTH/HEIGHT deprecated, not implemented
17
18/// Initial ticks_to_live of a creep without any claim parts.
19pub const CREEP_LIFE_TIME: u32 = 1500;
20/// Initial ticks_to_live of a creep with at least one claim part.
21pub const CREEP_CLAIM_LIFE_TIME: u32 = 600;
22/// Percentage of TTL-adjusted creep resource costs added to tombstone.
23///
24/// When creeps die, if they had remaining TTL then a proportion of the cost of
25/// the creep, both in energy per body part (bounded by
26/// [`CREEP_PART_MAX_ENERGY`]) and resources spent on boosts, are placed in the
27/// creep's tombstone.
28pub const CREEP_CORPSE_RATE: f32 = 0.2;
29/// The upper limit of energy per body part considered for return in tombstones
30///
31/// Energy spent on a creep body part for parts that cost more that this limit
32/// will be capped at this value for tombstone resource calculations
33pub const CREEP_PART_MAX_ENERGY: u32 = 125;
34
35/// Store capacity provided per effective carry part.
36pub const CARRY_CAPACITY: u32 = 50;
37/// Energy harvested from a source per effective work part per
38/// [`Creep::harvest`] action.
39///
40/// [`Creep::harvest`]: crate::objects::Creep::harvest
41pub const HARVEST_POWER: u32 = 2;
42/// Amount harvested from a mineral per effective work part per
43/// [`Creep::harvest`] action.
44///
45/// [`Creep::harvest`]: crate::objects::Creep::harvest
46pub const HARVEST_MINERAL_POWER: u32 = 1;
47/// Amount harvested from a deposit per effective work part per
48/// [`Creep::harvest`] action.
49///
50/// [`Creep::harvest`]: crate::objects::Creep::harvest
51pub const HARVEST_DEPOSIT_POWER: u32 = 1;
52/// Hits repaired per effective work part per [`Creep::repair`] action.
53///
54/// [`Creep::repair`]: crate::objects::Creep::repair
55pub const REPAIR_POWER: u32 = 100;
56/// Hits removed per effective work part per [`Creep::dismantle`] action.
57///
58/// [`Creep::dismantle`]: crate::objects::Creep::dismantle
59pub const DISMANTLE_POWER: u32 = 50;
60/// Construction site progress added per effective work part per
61/// [`Creep::build`] action.
62///
63/// [`Creep::build`]: crate::objects::Creep::build
64pub const BUILD_POWER: u32 = 5;
65/// Hits of damage per effective attack part per [`Creep::attack`] action.
66///
67/// [`Creep::attack`]: crate::objects::Creep::attack
68pub const ATTACK_POWER: u32 = 30;
69/// Control points added per effective work part per
70/// [`Creep::upgrade_controller`] action.
71///
72/// [`Creep::upgrade_controller`]: crate::objects::Creep::upgrade_controller
73pub const UPGRADE_CONTROLLER_POWER: u32 = 1;
74/// Hits of damage per effective ranged attack part per [`Creep::ranged_attack`]
75/// action.
76///
77/// [`Creep::ranged_attack`]: crate::objects::Creep::ranged_attack
78pub const RANGED_ATTACK_POWER: u32 = 10;
79/// Hits of damage healed per effective heal part per [`Creep::heal`] action.
80///
81/// [`Creep::heal`]: crate::objects::Creep::heal
82pub const HEAL_POWER: u32 = 12;
83/// Hits of damage healed per effective heal part per [`Creep::ranged_heal`]
84/// action.
85///
86/// [`Creep::ranged_heal`]: crate::objects::Creep::ranged_heal
87pub const RANGED_HEAL_POWER: u32 = 4;
88/// Cost in energy for each hit repaired by creeps before boosts.
89pub const REPAIR_COST: f32 = 0.01;
90/// Amount in energy returned to the dismantling creep per hit dismantled.
91pub const DISMANTLE_COST: f32 = 0.005;
92
93/// Hits lost per decay period for ramparts
94pub const RAMPART_DECAY_AMOUNT: u32 = 300;
95/// Ticks between rampart decays, losing [`RAMPART_DECAY_AMOUNT`] hits.
96pub const RAMPART_DECAY_TIME: u32 = 100;
97/// Initial hits for rampart structures when built; consider using the
98/// [`StructureType::initial_hits`] function.
99pub const RAMPART_HITS: u32 = 1;
100/// Max rampart hits at RCL 2; consider using the [`rampart_hits_max`] function.
101pub const RAMPART_HITS_MAX_RCL2: u32 = 300_000;
102/// Max rampart hits at RCL 3; consider using the [`rampart_hits_max`] function.
103pub const RAMPART_HITS_MAX_RCL3: u32 = 1_000_000;
104/// Max rampart hits at RCL 4; consider using the [`rampart_hits_max`] function.
105pub const RAMPART_HITS_MAX_RCL4: u32 = 3_000_000;
106/// Max rampart hits at RCL 5; consider using the [`rampart_hits_max`] function.
107pub const RAMPART_HITS_MAX_RCL5: u32 = 10_000_000;
108/// Max rampart hits at RCL 6; consider using the [`rampart_hits_max`] function.
109pub const RAMPART_HITS_MAX_RCL6: u32 = 30_000_000;
110/// Max rampart hits at RCL 7; consider using the [`rampart_hits_max`] function.
111pub const RAMPART_HITS_MAX_RCL7: u32 = 100_000_000;
112/// Max rampart hits at RCL 8; consider using the [`rampart_hits_max`] function.
113pub const RAMPART_HITS_MAX_RCL8: u32 = 300_000_000;
114
115/// Translates the `RAMPART_HITS_MAX` constant, the maximum rampart hits for a
116/// given room control level.
117#[inline]
118pub const fn rampart_hits_max(rcl: u32) -> u32 {
119 match rcl {
120 r if r < 2 => 0,
121 2 => RAMPART_HITS_MAX_RCL2,
122 3 => RAMPART_HITS_MAX_RCL3,
123 4 => RAMPART_HITS_MAX_RCL4,
124 5 => RAMPART_HITS_MAX_RCL5,
125 6 => RAMPART_HITS_MAX_RCL6,
126 7 => RAMPART_HITS_MAX_RCL7,
127 _ => RAMPART_HITS_MAX_RCL8,
128 }
129}
130
131/// Ticks to source regen after first [`Creep::harvest`] since last regen.
132///
133/// [`Creep::harvest`]: crate::objects::Creep::harvest
134pub const ENERGY_REGEN_TIME: u32 = 300;
135/// The total amount of a resource that must be accumulated in a dropped
136/// [`Resource`] for one unit of that resource to decay each tick, rounded up.
137///
138/// [`Resource`]: crate::objects::Resource
139pub const ENERGY_DECAY: u32 = 1000;
140
141/// Initial hits for spawn structures; consider using the
142/// [`StructureType::initial_hits`] function.
143pub const SPAWN_HITS: u32 = 5000;
144/// Initial energy for spawn structures when built.
145pub const SPAWN_ENERGY_START: u32 = 300;
146/// Maximum energy capacity of spawn structures.
147pub const SPAWN_ENERGY_CAPACITY: u32 = 300;
148/// Ticks taken to spawn each creep body part, before power creep effects.
149pub const CREEP_SPAWN_TIME: u32 = 3;
150
151/// Additional TTL bonus, and reduction in energy cost, when renewing a creep
152/// compared to spawning.
153///
154/// Quoting from [`StructureSpawn.renewCreep`] documentation:
155///
156/// > Each execution increases the creep's timer by amount of ticks according to
157/// > this formula:
158/// >
159/// > `floor(600/body_size)`
160/// >
161/// > Energy required for each execution is determined using this formula:
162/// >
163/// > `ceil(creep_cost/2.5/body_size)`
164///
165/// 600 in the TTL addition formula is calculated as [`SPAWN_RENEW_RATIO`] *
166/// [`CREEP_LIFE_TIME`] / [`CREEP_SPAWN_TIME`], or `1.2 * 1500 / 3 == 600`
167///
168/// 2.5 in the cost formula is calculated as [`CREEP_SPAWN_TIME`] /
169/// [`SPAWN_RENEW_RATIO`], or `3 / 1.2 == 2.5`
170///
171/// [`StructureSpawn.renewCreep`]: https://docs.screeps.com/api/#StructureSpawn.renewCreep
172pub const SPAWN_RENEW_RATIO: f32 = 1.2;
173
174/// Source energy capacity immediately after regeneration in owned and reserved
175/// rooms.
176pub const SOURCE_ENERGY_CAPACITY: u32 = 3000;
177/// Source energy capacity immediately after regeneration in neutral rooms.
178pub const SOURCE_ENERGY_NEUTRAL_CAPACITY: u32 = 1500;
179/// Source energy capacity immediately after regeneration in source keeper
180/// (sector center) rooms.
181pub const SOURCE_ENERGY_KEEPER_CAPACITY: u32 = 4000;
182
183/// Initial hits for wall structures when built; consider using the
184/// [`StructureType::initial_hits`] function.
185pub const WALL_HITS: u32 = 1;
186/// Maximum hits for wall structures.
187pub const WALL_HITS_MAX: u32 = 300_000_000;
188
189/// Initial hits for extension structures; consider using the
190/// [`StructureType::initial_hits`] function.
191pub const EXTENSION_HITS: u32 = 1000;
192
193/// Translates the `EXTENSION_ENERGY_CAPACITY` constant, the energy capacity of
194/// each source structure at a given room control level.
195#[inline]
196pub const fn extension_energy_capacity(rcl: u32) -> u32 {
197 match rcl {
198 r if r < 7 => 50,
199 7 => 100,
200 _ => 200,
201 }
202}
203
204/// Maximum hits for road structures, before swamp/tunnel multipliers
205///
206/// Cost, hits, and decay rate are multiplied in the cases of building on
207/// swamps or tunneling (see [`CONSTRUCTION_COST_ROAD_SWAMP_RATIO`] and
208/// [`CONSTRUCTION_COST_ROAD_WALL_RATIO`] terrain multipliers).
209pub const ROAD_HITS: u32 = 5000;
210/// Tick penalty to a road's decay, per creep body part, when a creep steps on
211/// it.
212pub const ROAD_WEAROUT: u32 = 1;
213/// Tick penalty to a road's decay when a power creep steps on it.
214pub const ROAD_WEAROUT_POWER_CREEP: u32 = 100;
215/// Hits lost upon decay for roads, before swamp/tunnel multipliers
216///
217/// Cost, hits, and decay rate are multiplied in the cases of building on
218/// swamps or tunneling (see [`CONSTRUCTION_COST_ROAD_SWAMP_RATIO`] and
219/// [`CONSTRUCTION_COST_ROAD_WALL_RATIO`] terrain multipliers).
220pub const ROAD_DECAY_AMOUNT: u32 = 100;
221/// Ticks between road decay events without traffic
222///
223/// The number of ticks between roads losing hits to decay, before reduction due
224/// to creep traffic wear-out.
225pub const ROAD_DECAY_TIME: u32 = 1000;
226
227/// Initial hits for link structures; consider using the
228/// [`StructureType::initial_hits`] function.
229pub const LINK_HITS: u32 = 1000;
230/// Energy capacity of link structures.
231pub const LINK_CAPACITY: u32 = 800;
232/// Ticks of link cooldown after transferring energy per distance to
233/// destination.
234pub const LINK_COOLDOWN: u32 = 1;
235/// Percentage of the energy that is lost when transferred by
236/// [`StructureLink::transfer_energy`].
237///
238/// [`StructureLink::transfer_energy`]:
239/// crate::objects::StructureLink::transfer_energy
240pub const LINK_LOSS_RATIO: f32 = 0.03;
241
242/// Store capacity for storage structures without power creep effects.
243pub const STORAGE_CAPACITY: u32 = 1_000_000;
244/// Initial hits for storage structures; consider using the
245/// [`StructureType::initial_hits`] function.
246pub const STORAGE_HITS: u32 = 10_000;
247
248// Structure types and CONSTRUCTION_COST defined in `types.rs`
249
250/// Build, decay, and hits multiplier for roads built on swamp tiles.
251pub const CONSTRUCTION_COST_ROAD_SWAMP_RATIO: u32 = 5;
252/// Build, decay, and hits multiplier for roads built on natural wall tiles
253/// (tunnels)
254pub const CONSTRUCTION_COST_ROAD_WALL_RATIO: u32 = 150;
255
256/// Translates the `CONTROLLER_LEVELS` constant.
257///
258/// The number of control points required to upgrade to the next level at each
259/// room control level.
260///
261/// Returns `Some` for levels 1-7, `None` for all others.
262#[inline]
263pub const fn controller_levels(current_rcl: u32) -> Option<u32> {
264 match current_rcl {
265 1 => Some(200),
266 2 => Some(45_000),
267 3 => Some(135_000),
268 4 => Some(405_000),
269 5 => Some(1_215_000),
270 6 => Some(3_645_000),
271 7 => Some(10_935_000),
272 _ => None,
273 }
274}
275
276// CONTROLLER_STRUCTURES defined in `types.rs`
277
278/// Translates the `CONTROLLER_DOWNGRADE` constant, the maximum value of
279/// [`StructureController::ticks_to_downgrade`] for each controller level.
280///
281/// Note that rooms that upgrade or downgrade in level start at half of this
282/// maximum value for their new level, and that a controller will not upgrade to
283/// the next level unless filled completely.
284///
285/// Returns `Some` for levels 1-8, `None` for all others.
286///
287/// [`StructureController::ticks_to_downgrade`]:
288/// crate::objects::StructureController::ticks_to_downgrade
289#[inline]
290pub const fn controller_downgrade(rcl: u8) -> Option<u32> {
291 match rcl {
292 1 => Some(20_000),
293 2 => Some(10_000),
294 3 => Some(20_000),
295 4 => Some(40_000),
296 5 => Some(80_000),
297 6 => Some(120_000),
298 7 => Some(150_000),
299 8 => Some(200_000),
300 _ => None,
301 }
302}
303
304/// Ticks added to a [`StructureController::ticks_to_downgrade`] timer on each
305/// tick that at least one creep successfully used
306/// [`Creep::upgrade_controller`].
307///
308/// [`StructureController::ticks_to_downgrade`]:
309/// crate::objects::StructureController::ticks_to_downgrade
310/// [`Creep::upgrade_controller`]: crate::objects::Creep::upgrade_controller
311pub const CONTROLLER_DOWNGRADE_RESTORE: u32 = 100;
312
313/// Ticks under 50% of [`controller_downgrade`] max that safe mode becomes
314/// unavailable.
315///
316/// Once the [`StructureController::ticks_to_downgrade`] timer is reduced to a
317/// certain level by [`Creep::attack_controller`] or lack of
318/// [`Creep::upgrade_controller`] activity, safe mode cannot be activated.
319///
320/// The point at which this occurs is half of the [`controller_downgrade`] total
321/// for the current level, minus this amount. Note that because a room's
322/// [`StructureController::ticks_to_downgrade`] is placed at exactly 50% after
323/// an upgrade or downgrade.
324///
325/// Quoting from the [3.2.0 patch notes](https://blog.screeps.com/2018/12/changelog-2018-12-14/):
326///
327/// * When the controller gains or loses one level, its downgrade timer is set
328/// to 50% instead of 100%.
329/// * Safe mode activation unavailable period starts from this 50% point minus
330/// 5000 ticks.
331///
332/// For example, a newly upgraded RCL7 room will have 75,000 ticks to downgrade
333/// out of its 150,000 maximum, and safe mode becomes unavailable if the timer
334/// falls below 70,000 ticks.
335///
336/// [`StructureController::ticks_to_downgrade`]:
337/// crate::objects::StructureController::ticks_to_downgrade
338/// [`Creep::attack_controller`]: crate::objects::Creep::attack_controller
339/// [`Creep::upgrade_controller`]: crate::objects::Creep::upgrade_controller
340pub const CONTROLLER_DOWNGRADE_SAFEMODE_THRESHOLD: u32 = 5000;
341/// Additional decay of the [`StructureController::ticks_to_downgrade`] timer
342/// caused by each claim part used per [`Creep::attack_controller`] action.
343///
344/// [`StructureController::ticks_to_downgrade`]:
345/// crate::objects::StructureController::ticks_to_downgrade
346/// [`Creep::attack_controller`]: crate::objects::Creep::attack_controller
347pub const CONTROLLER_CLAIM_DOWNGRADE: u32 = 300;
348/// Reservation ticks added per claim part per [`Creep::reserve_controller`]
349/// action.
350///
351/// [`Creep::reserve_controller`]: crate::objects::Creep::reserve_controller
352pub const CONTROLLER_RESERVE: u32 = 1;
353/// Maximum ticks of reservation allowed on a controller
354pub const CONTROLLER_RESERVE_MAX: u32 = 5000;
355/// Maxiumum energy per tick that can be spent on [`Creep::upgrade_controller`]
356/// at room control level 8 without power creep effects or boosts.
357///
358/// [`Creep::upgrade_controller`]: crate::objects::Creep::upgrade_controller
359pub const CONTROLLER_MAX_UPGRADE_PER_TICK: u32 = 15;
360/// A controller cannot be attacked or upgraded for this number of ticks after
361/// one or more creeps successfully uses [`Creep::attack_controller`] against
362/// it.
363///
364/// [`Creep::attack_controller`]: crate::objects::Creep::attack_controller
365pub const CONTROLLER_ATTACK_BLOCKED_UPGRADE: u32 = 1000;
366/// Ticks a controller cannot be attacked or upgraded for after a nuke
367/// detonation in the room.
368pub const CONTROLLER_NUKE_BLOCKED_UPGRADE: u32 = 200;
369
370/// Duration of safe mode once activated, in ticks.
371pub const SAFE_MODE_DURATION: u32 = 20_000;
372/// Ticks since last safe mode activation before another is allowed.
373pub const SAFE_MODE_COOLDOWN: u32 = 50_000;
374/// Cost in [`Ghodium`] to add a safe mode activation to a controller via
375/// [`Creep::generate_safe_mode`]
376///
377/// [`Ghodium`]: crate::constants::ResourceType::Ghodium
378/// [`Creep::generate_safe_mode`]: crate::objects::Creep::generate_safe_mode
379pub const SAFE_MODE_COST: u32 = 1000;
380
381/// Initial hits for tower structures; consider using the
382/// [`StructureType::initial_hits`] function.
383pub const TOWER_HITS: u32 = 3000;
384/// Energy capacity of tower structures.
385pub const TOWER_CAPACITY: u32 = 1000;
386/// Energy cost of each tower action.
387pub const TOWER_ENERGY_COST: u32 = 10;
388/// Tower damage per [`StructureTower::attack`] before range reduction.
389///
390/// [`StructureTower::attack`]: crate::objects::StructureTower::attack
391pub const TOWER_POWER_ATTACK: u32 = 600;
392/// Hits healed per [`StructureTower::heal`] before range reduction.
393///
394/// [`StructureTower::heal`]: crate::objects::StructureTower::heal
395pub const TOWER_POWER_HEAL: u32 = 400;
396/// Hits healed per [`StructureTower::repair`] before range reduction.
397///
398/// [`StructureTower::repair`]: crate::objects::StructureTower::repair
399pub const TOWER_POWER_REPAIR: u32 = 800;
400/// Tower actions at a range beyond this distance suffer falloff penalties - see
401/// [`TOWER_FALLOFF`].
402pub const TOWER_OPTIMAL_RANGE: u8 = 5;
403/// Tower actions at a range greater than or equal to this distance suffer the
404/// maxium falloff penalties - see [`TOWER_FALLOFF`].
405pub const TOWER_FALLOFF_RANGE: u8 = 20;
406/// Maximum percentage reduction in healing, repair, and attack effectiveness
407/// for towers due to range.
408///
409/// When targets are at range beyond [`TOWER_OPTIMAL_RANGE`] until reaching the
410/// maximum penalty at range [`TOWER_FALLOFF_RANGE`], the amount of healing,
411/// repair, or damage done by a tower is reduced according to the formula
412/// ([source]):
413///
414/// ```js
415/// amount -= amount * TOWER_FALLOFF * (range - TOWER_OPTIMAL_RANGE) / (TOWER_FALLOFF_RANGE - TOWER_OPTIMAL_RANGE)
416/// ```
417///
418/// [source]: https://github.com/screeps/engine/blob/f02d16a44a00c35615ae227fc72a3c9a07a6a39a/src/processor/intents/towers/attack.js#L38
419pub const TOWER_FALLOFF: f64 = 0.75;
420
421/// Initial hits for observer structures; consider using the
422/// [`StructureType::initial_hits`] function.
423pub const OBSERVER_HITS: u32 = 500;
424/// Maximum range in rooms for [`StructureObserver::observe_room`].
425///
426/// [`StructureObserver::observe_room`]:
427/// crate::objects::StructureObserver::observe_room
428pub const OBSERVER_RANGE: u32 = 10;
429
430/// Initial hits for power bank structures; consider using the
431/// [`StructureType::initial_hits`] function.
432pub const POWER_BANK_HITS: u32 = 2_000_000;
433/// Maximum power capacity for power banks, before accounting for
434/// [`POWER_BANK_CAPACITY_CRIT`].
435pub const POWER_BANK_CAPACITY_MAX: u32 = 5000;
436/// Maximum power capacity for power banks.
437pub const POWER_BANK_CAPACITY_MIN: u32 = 500;
438/// Chance of adding an additional [`POWER_BANK_CAPACITY_MAX`] to the random
439/// power amount calculated when spawning a power bank. ([source])
440///
441/// [source]: https://github.com/screeps/backend-local/blob/81cbe7884afed23f3e1deaa3dcc77411fcbd697b/lib/cronjobs.js#L228
442pub const POWER_BANK_CAPACITY_CRIT: f32 = 0.3;
443/// Ticks for a power bank to decay if not destroyed.
444pub const POWER_BANK_DECAY: u32 = 5000;
445/// Percentage of damage dealt to power banks that is dealt back to attacking
446/// creeps.
447pub const POWER_BANK_HIT_BACK: f32 = 0.5;
448
449/// Initial hits for power spawn structures; consider using the
450/// [`StructureType::initial_hits`] function.
451pub const POWER_SPAWN_HITS: u32 = 5000;
452/// Maximum energy capacity for a power spawn to use in
453/// [`StructurePowerSpawn::process_power`].
454///
455/// [`StructurePowerSpawn::process_power`]:
456/// crate::objects::StructurePowerSpawn::process_power
457pub const POWER_SPAWN_ENERGY_CAPACITY: u32 = 5000;
458/// Maximum power capacity for a power spawn to use in
459/// [`StructurePowerSpawn::process_power`].
460///
461/// [`StructurePowerSpawn::process_power`]:
462/// crate::objects::StructurePowerSpawn::process_power
463pub const POWER_SPAWN_POWER_CAPACITY: u32 = 100;
464/// Energy consumed per point of power processed by
465/// [`StructurePowerSpawn::process_power`].
466///
467/// [`StructurePowerSpawn::process_power`]:
468/// crate::objects::StructurePowerSpawn::process_power
469pub const POWER_SPAWN_ENERGY_RATIO: u32 = 50;
470
471/// Initial hits for extractor structures; consider using the
472/// [`StructureType::initial_hits`] function.
473pub const EXTRACTOR_HITS: u32 = 500;
474/// Ticks of cooldown for the extractor timer after tick that at least one creep
475/// successfully used [`Creep::harvest`].
476///
477/// [`Creep::harvest`]: crate::objects::Creep::harvest
478pub const EXTRACTOR_COOLDOWN: u32 = 5;
479
480/// Initial hits for lab structures; consider using the
481/// [`StructureType::initial_hits`] function.
482pub const LAB_HITS: u32 = 500;
483/// Store capacity for minerals in lab structures.
484pub const LAB_MINERAL_CAPACITY: u32 = 3000;
485/// Store capacity for energy in lab structures.
486pub const LAB_ENERGY_CAPACITY: u32 = 2000;
487/// Cost in energy to boost each creep body part.
488pub const LAB_BOOST_ENERGY: u32 = 20;
489/// Cost in boost minerals to boost each creep body part.
490pub const LAB_BOOST_MINERAL: u32 = 30;
491// LAB_COOLDOWN is marked as unused, not implemented
492/// Amount of compounds consumed and produced per reaction, before power creep
493/// effects.
494pub const LAB_REACTION_AMOUNT: u32 = 5;
495/// Energy refunded by [`StructureLab::unboost_creep`] per creep body part
496/// (none).
497///
498/// [`StructureLab::unboost_creep`]: crate::objects::StructureLab::unboost_creep
499pub const LAB_UNBOOST_ENERGY: u32 = 0;
500/// Minerals spent on boosts refunded by [`StructureLab::unboost_creep`] per
501/// creep body part.
502///
503/// [`StructureLab::unboost_creep`]: crate::objects::StructureLab::unboost_creep
504pub const LAB_UNBOOST_MINERAL: u32 = 15;
505
506/// Exponential growth rate of control points needed per global control level
507/// (GCL).
508pub const GCL_POW: f64 = 2.4;
509/// Base growth rate of control points needed per global control level (GCL).
510pub const GCL_MULTIPLY: u32 = 1_000_000;
511/// Maximum GCL for players allowed to spawn in a Novice area.
512pub const GCL_NOVICE: u32 = 3;
513
514// TERRAIN_* defined in `small_enums.rs`
515
516/// Maximum allowed construction sites at once per player.
517pub const MAX_CONSTRUCTION_SITES: u32 = 100;
518/// Maximum body parts per creep.
519pub const MAX_CREEP_SIZE: u32 = 50;
520
521/// Ticks after depletion for minerals to regenerate.
522pub const MINERAL_REGEN_TIME: u32 = 50_000;
523
524/// Translates the `MINERAL_MIN_AMOUNT` constant; currently unused in game (see
525/// [`Density::amount`] instead).
526///
527/// [`Density::amount`]: crate::constants::Density::amount
528#[inline]
529pub const fn mineral_min_amount(mineral: ResourceType) -> Option<u32> {
530 match mineral {
531 ResourceType::Hydrogen => Some(35_000),
532 ResourceType::Oxygen => Some(35_000),
533 ResourceType::Lemergium => Some(35_000),
534 ResourceType::Keanium => Some(35_000),
535 ResourceType::Zynthium => Some(35_000),
536 ResourceType::Utrium => Some(35_000),
537 ResourceType::Catalyst => Some(35_000),
538 _ => None,
539 }
540}
541
542/// Currently unused in game (see [`Density::probability`] instead).
543///
544/// [`Density::probability`]: crate::constants::Density::probability
545pub const MINERAL_RANDOM_FACTOR: u32 = 2;
546
547// MINERAL_DENSITY, MINERAL_DENSITY_PROBABILITY defined in `small_enums.rs`
548
549/// Percentage chance to randomly determine a new density when currently
550/// moderate or high density (a new density is always chosen when low or ultra).
551pub const MINERAL_DENSITY_CHANGE: f32 = 0.05;
552
553// DENSITY_* defined in `small_enums.rs`
554
555/// Multiplier for deposit cooldown determination.
556///
557/// Cooldown is determined by the formula ([source]):
558///
559/// ```js
560/// cooldown = ceil(DEPOSIT_EXHAUST_MULTIPLY * total_harvested ^ DEPOSIT_EXHAUST_POW)
561/// ```
562///
563/// [source]: https://github.com/screeps/engine/blob/f02d16a44a00c35615ae227fc72a3c9a07a6a39a/src/processor/intents/creeps/harvest.js#L134
564pub const DEPOSIT_EXHAUST_MULTIPLY: f32 = 0.001;
565
566/// Exponential growth rate for deposit cooldown determination.
567///
568/// Cooldown is determined by the formula ([source]):
569///
570/// ```js
571/// cooldown = ceil(DEPOSIT_EXHAUST_MULTIPLY * total_harvested ^ DEPOSIT_EXHAUST_POW)
572/// ```
573///
574/// [source]: https://github.com/screeps/engine/blob/f02d16a44a00c35615ae227fc72a3c9a07a6a39a/src/processor/intents/creeps/harvest.js#L134
575pub const DEPOSIT_EXHAUST_POW: f32 = 1.2;
576/// Time since last harvest that a deposit will decay.
577pub const DEPOSIT_DECAY_TIME: u32 = 50_000;
578
579/// Initial hits for terminal structures; consider using the
580/// [`StructureType::initial_hits`] function.
581pub const TERMINAL_HITS: u32 = 3000;
582/// Store capacity of terminal structures.
583pub const TERMINAL_CAPACITY: u32 = 300_000;
584/// Currently unused in game (see [`market::calc_transaction_cost`] and
585/// [`TERMINAL_SEND_COST_SCALE`] instead).
586///
587/// [`market::calc_transaction_cost`]: [`crate::market::calc_transaction_cost`].
588/// [`TERMINAL_SEND_COST_SCALE`]:
589/// [`crate::constants::TERMINAL_SEND_COST_SCALE`].
590pub const TERMINAL_SEND_COST: f32 = 0.1;
591/// Currently unused in game.
592pub const TERMINAL_MIN_SEND: u32 = 100;
593/// Cooldown after a terminal is used before it can be used again.
594pub const TERMINAL_COOLDOWN: u32 = 10;
595
596/// Initial hits for container structures; consider using the
597/// [`StructureType::initial_hits`] function.
598pub const CONTAINER_HITS: u32 = 250_000;
599/// Store capacity of container structures.
600pub const CONTAINER_CAPACITY: u32 = 2000;
601/// Hits lost on the container per decay.
602pub const CONTAINER_DECAY: u32 = 5000;
603/// Ticks between hit loss due to decay in unowned rooms.
604pub const CONTAINER_DECAY_TIME: u32 = 100;
605/// Ticks between hit loss due to decay in owned rooms.
606pub const CONTAINER_DECAY_TIME_OWNED: u32 = 500;
607
608/// Initial hits for nuker structures; consider using the
609/// [`StructureType::initial_hits`] function.
610pub const NUKER_HITS: u32 = 1000;
611/// Cooldown for nuker structers after firing.
612pub const NUKER_COOLDOWN: u32 = 100_000;
613/// Energy capacity of the nuker, which is spent to fire a nuke.
614pub const NUKER_ENERGY_CAPACITY: u32 = 300_000;
615/// Ghodium capacity of the nuker, which is spent to fire a nuke.
616pub const NUKER_GHODIUM_CAPACITY: u32 = 5000;
617/// Tick until impact after firing a nuke.
618pub const NUKE_LAND_TIME: u32 = 50_000;
619/// Range in rooms of nukers.
620pub const NUKE_RANGE: u32 = 10;
621/// Damage in hits done by nukes at the point of impact.
622pub const NUKE_DAMAGE_RANGE_0: u32 = 10_000_000;
623/// Damage in hits done by nukes within range 2.
624pub const NUKE_DAMAGE_RANGE_2: u32 = 5_000_000;
625
626/// Initial hits for factory structures; consider using the
627/// [`StructureType::initial_hits`] function.
628pub const FACTORY_HITS: u32 = 1000;
629/// Store capacity of factory structures.
630pub const FACTORY_CAPACITY: u32 = 50_000;
631
632/// Ticks per body part in total creep size that a creep's tombstone will
633/// remain before decaying.
634pub const TOMBSTONE_DECAY_PER_PART: u32 = 5;
635/// Ticks that a power creep's tombstone will remain.
636pub const TOMBSTONE_DECAY_POWER_CREEP: u32 = 500;
637
638/// Ticks that ruins will last when structures are destroyed.
639pub const RUIN_DECAY: u32 = 500;
640
641/// Structures with special rules for their ruins' ticks to live, currently only
642/// power banks.
643#[inline]
644pub const fn ruin_decay_structures(structure_type: StructureType) -> Option<u32> {
645 match structure_type {
646 StructureType::PowerBank => Some(10),
647 _ => None,
648 }
649}
650
651/// Ticks that a portal that has reached the end of its stable lifetime will
652/// remain before decaying.
653pub const PORTAL_DECAY: u32 = 30_000;
654
655// ORDER_SELL / ORDER_BUY defined in `small_enums.rs`
656
657/// Percentage of order value in credits charged as a fee for market listings.
658pub const MARKET_FEE: f32 = 0.05;
659
660/// Maximum number of total orders a player is allowed to have on the market.
661pub const MARKET_MAX_ORDERS: u32 = 300;
662/// Time, in milliseconds, after which a market order will expire (30 days).
663pub const MARKET_ORDER_LIFE_TIME: u32 = 30 * 24 * 3600 * 1000;
664
665/// Maximum number of total flags a player is allowed to have on a shard.
666pub const FLAGS_LIMIT: u32 = 10_000;
667
668/// Cost, paid from [`CpuInfo::bucket`], to generate a pixel using
669/// [`CpuInfo::generate_pixel`]
670///
671/// [`CpuInfo::bucket`]: crate::game::cpu::bucket
672/// [`CpuInfo::generate_pixel`]: crate::game::cpu::generate_pixel
673pub const PIXEL_CPU_COST: u32 = 10_000;
674
675// Resources defined in `types.rs`
676
677// REACTIONS defined in `recipes.rs`
678
679// BOOSTS defined in `types.rs`
680
681// REACTION_TIME defined in `recipes.rs`
682
683/// The amount of time after spawning, in milliseconds, that random center room
684/// portals will become unstable and begin to decay, disappearing
685/// [`PORTAL_DECAY`] ticks later.
686pub const PORTAL_UNSTABLE: u32 = 10 * 24 * 3600 * 1000;
687/// Minimum time after a portal decays in a center room that a new portal will
688/// appear, in milliseconds.
689pub const PORTAL_MIN_TIMEOUT: u32 = 12 * 24 * 3600 * 1000;
690/// Maximum time after a portal decays in a center room that a new portal will
691/// appear, in milliseconds.
692pub const PORTAL_MAX_TIMEOUT: u32 = 22 * 24 * 3600 * 1000;
693
694/// Base value for power bank respawn time calculation.
695///
696/// Calculated respawn time falls randomly in a range from 50% to 125% of this
697/// value. Determined by the formula ([source]):
698///
699/// ```js
700/// respawnTime = Math.round(Math.random() * POWER_BANK_RESPAWN_TIME / 2 + POWER_BANK_RESPAWN_TIME * 0.75)
701/// ```
702///
703/// [source]: https://github.com/screeps/backend-local/blob/81cbe7884afed23f3e1deaa3dcc77411fcbd697b/lib/cronjobs.js#L199
704pub const POWER_BANK_RESPAWN_TIME: u32 = 50_000;
705
706/// Base value for calculating the energy harvest amount that will trigger
707/// invader spawns.
708///
709/// Calculated energy to be harvested in a given room until invader creeps spawn
710/// falls randomly in a range from 70% to 130% of this value, then has a chance
711/// to have a modifier applied according to the formula ([source]):
712///
713/// ```js
714/// let invaderGoal = Math.floor(INVADERS_ENERGY_GOAL * (Math.random()*0.6 + 0.7));
715/// if(Math.random() < 0.1) {
716/// invaderGoal *= Math.floor( Math.random() > 0.5 ? 2 : 0.5 );
717/// }
718/// ```
719///
720/// Note that due to the use of `Math.floor`, the 0.5 will become a multiplier of 0, which won't be used; this bug is reported [here](https://screeps.com/forum/topic/2846)
721///
722/// [source]: https://github.com/screeps/backend-local/blob/81cbe7884afed23f3e1deaa3dcc77411fcbd697b/lib/cronjobs.js#L433
723pub const INVADERS_ENERGY_GOAL: u32 = 100_000;
724
725/// Owner username of system-owned structures and creeps.
726pub const SYSTEM_USERNAME: &str = "Screeps";
727
728/// Text added to signs of unowned rooms when a novice or respawn area is
729/// planned for the sector.
730pub const SIGN_PLANNED_AREA: &str = "A new Novice or Respawn Area is being planned somewhere \
731 in this sector. Please make sure all important rooms are reserved.";
732
733// EVENT_* constants in src/objects/impls/room.rs
734
735/// Base growth rate of processed power needed per global power level (GPL).
736pub const POWER_LEVEL_MULTIPLY: u32 = 1000;
737/// Exponential growth rate of processed power needed per global power level
738/// (GPL).
739pub const POWER_LEVEL_POW: u32 = 2;
740/// Time, in milliseconds, that a power creep must wait to respawn after dying.
741pub const POWER_CREEP_SPAWN_COOLDOWN: u32 = 8 * 3600 * 1000;
742/// Time, in milliseconds, after a deletion is started via
743/// [`AccountPowerCreep::delete`] that it can no longer be canceled.
744///
745/// [`AccountPowerCreep::delete`]: crate::objects::AccountPowerCreep::delete
746pub const POWER_CREEP_DELETE_COOLDOWN: u32 = 24 * 3600 * 1000;
747/// Maximum level for power creeps.
748pub const POWER_CREEP_MAX_LEVEL: u32 = 25;
749/// Maximum ticks to live for power creeps
750pub const POWER_CREEP_LIFE_TIME: u32 = 5000;
751
752// POWER_CLASS, PWR_*, EFFECT_* defined in `types.rs`
753
754/// Initial hits for invader cores; consider using the
755/// [`StructureType::initial_hits`] function.
756pub const INVADER_CORE_HITS: u32 = 100_000;
757
758/// Ticks per body part that invader cores of each level take to spawn defensive
759/// creeps.
760#[inline]
761pub const fn invader_core_creep_spawn_time(core_level: u32) -> Option<u32> {
762 match core_level {
763 1 => Some(0),
764 2 => Some(6),
765 3 => Some(3),
766 4 => Some(2),
767 5 => Some(1),
768 _ => None,
769 }
770}
771
772/// Ticks between creation of invader cores in rooms in the sector for each
773/// level of stronghold.
774#[inline]
775pub const fn invader_core_expand_time(core_level: u32) -> Option<u32> {
776 match core_level {
777 1 => Some(4000),
778 2 => Some(3500),
779 3 => Some(3000),
780 4 => Some(2500),
781 5 => Some(2000),
782 _ => None,
783 }
784}
785
786/// The reservation points added or removed per tick by invader cores.
787pub const INVADER_CORE_CONTROLLER_POWER: u32 = 2;
788/// Duration of stronghold 'deployment', during which they are invulnerable.
789///
790/// The name reflects prior behavior by strongholds upgrading controllers
791/// in owned rooms, which has been removed. Now only used for the deploy timer.
792pub const INVADER_CORE_CONTROLLER_DOWNGRADE: u32 = 5000;
793
794/// Rampart hits for each level of stronghold.
795#[inline]
796pub const fn stronghold_rampart_hits(core_level: u32) -> Option<u32> {
797 match core_level {
798 1 => Some(100_000),
799 2 => Some(200_000),
800 3 => Some(500_000),
801 4 => Some(1_000_000),
802 5 => Some(2_000_000),
803 _ => None,
804 }
805}
806
807/// Average ticks until collapse for a stronghold.
808///
809/// Calculated lifetime includes a random 10% variation. Value is determined by
810/// the formula ([source]):
811///
812/// ```js
813/// duration = Math.round(STRONGHOLD_DECAY_TICKS * (0.9 + Math.random() * 0.2))
814/// ```
815///
816/// [source]: https://github.com/screeps/engine/blob/b2ac4720abe399837b0ba38712aaadfd4a9e9a7e/src/processor/intents/invader-core/stronghold/stronghold.js#L27
817pub const STRONGHOLD_DECAY_TICKS: u32 = 75_000;
818
819// POWER_INFO not yet implemented
820// BODYPARTS_ALL implemented via Sequence trait in `small_enums.rs`
821// RESOURCES_ALL implemented via Sequence trait in `types.rs`
822// COLORS_ALL implemented via Sequence trait in `small_enums.rs`
823// INTERSHARD_RESOURCES defined in `types.rs`
824// COMMODITIES defined in `recipes.rs`