1use js_sys::{Array, JsString};
2use wasm_bindgen::prelude::*;
3
4use crate::{
5 constants::{Direction, Part, ResourceType},
6 enums::action_error_codes::{
7 AttackControllerErrorCode, BuildErrorCode, ClaimControllerErrorCode, CreepAttackErrorCode,
8 CreepCancelOrderErrorCode, CreepHealErrorCode, CreepMoveByPathErrorCode,
9 CreepMoveDirectionErrorCode, CreepMovePulledByErrorCode, CreepMoveToErrorCode,
10 CreepRepairErrorCode, DismantleErrorCode, DropErrorCode, GenerateSafeModeErrorCode,
11 HarvestErrorCode, NotifyWhenAttackedErrorCode, PickupErrorCode, PullErrorCode,
12 RangedAttackErrorCode, RangedHealErrorCode, RangedMassAttackErrorCode,
13 ReserveControllerErrorCode, SayErrorCode, SignControllerErrorCode, SuicideErrorCode,
14 TransferErrorCode, UpgradeControllerErrorCode, WithdrawErrorCode,
15 },
16 objects::{
17 ConstructionSite, Owner, Resource, RoomObject, Store, Structure, StructureController,
18 },
19 pathfinder::SingleRoomCostResult,
20 prelude::*,
21 CostMatrix, MoveToOptions, RoomName, RoomPosition,
22};
23
24#[cfg(feature = "seasonal-season-5")]
25use crate::objects::Reactor;
26
27#[cfg(feature = "seasonal-season-5")]
28use crate::enums::action_error_codes::CreepClaimReactorErrorCode;
29
30#[wasm_bindgen]
31extern "C" {
32 #[wasm_bindgen(extends = RoomObject)]
36 #[derive(Clone, Debug)]
37 pub type Creep;
38
39 #[wasm_bindgen(structural, method, getter = body)]
43 fn body_internal(this: &Creep) -> Array;
44
45 #[wasm_bindgen(structural, method, getter = fatigue)]
46 fn fatigue_internal(this: &Creep) -> u32;
47
48 #[wasm_bindgen(structural, method, getter = hits)]
49 fn hits_internal(this: &Creep) -> u32;
50
51 #[wasm_bindgen(structural, method, getter = hitsMax)]
52 fn hits_max_internal(this: &Creep) -> u32;
53
54 #[wasm_bindgen(structural, method, getter = id)]
55 fn id_internal(this: &Creep) -> Option<JsString>;
56
57 #[wasm_bindgen(structural, method, getter = memory)]
58 fn memory_internal(this: &Creep) -> JsValue;
59
60 #[wasm_bindgen(structural, method, setter = memory)]
61 fn set_memory_internal(this: &Creep, val: &JsValue);
62
63 #[wasm_bindgen(structural, method, getter = my)]
64 fn my_internal(this: &Creep) -> bool;
65
66 #[wasm_bindgen(structural, method, getter = name)]
67 fn name_internal(this: &Creep) -> String;
68
69 #[wasm_bindgen(structural, method, getter = name)]
70 fn name_jsstring_internal(this: &Creep) -> JsString;
71
72 #[wasm_bindgen(structural, method, getter = owner)]
73 fn owner_internal(this: &Creep) -> Owner;
74
75 #[wasm_bindgen(structural, method, getter = saying)]
76 fn saying_internal(this: &Creep) -> Option<JsString>;
77
78 #[wasm_bindgen(structural, method, getter = spawning)]
79 fn spawning_internal(this: &Creep) -> bool;
80
81 #[wasm_bindgen(structural, method, getter = store)]
82 fn store_internal(this: &Creep) -> Store;
83
84 #[wasm_bindgen(structural, method, getter = ticksToLive)]
85 fn ticks_to_live_internal(this: &Creep) -> Option<u32>;
86
87 #[wasm_bindgen(final, method, js_name = attack)]
88 fn attack_internal(this: &Creep, target: &RoomObject) -> i8;
89
90 #[wasm_bindgen(final, method, js_name = attackController)]
91 fn attack_controller_internal(this: &Creep, target: &StructureController) -> i8;
92
93 #[wasm_bindgen(final, method, js_name = build)]
94 fn build_internal(this: &Creep, target: &ConstructionSite) -> i8;
95
96 #[wasm_bindgen(final, method, js_name = cancelOrder)]
97 fn cancel_order_internal(this: &Creep, target: &JsString) -> i8;
98
99 #[wasm_bindgen(final, method, js_name = claimController)]
100 fn claim_controller_internal(this: &Creep, target: &StructureController) -> i8;
101
102 #[cfg(feature = "seasonal-season-5")]
103 #[wasm_bindgen(final, method, js_name = claimReactor)]
104 fn claim_reactor_internal(this: &Creep, target: &Reactor) -> i8;
105
106 #[wasm_bindgen(final, method, js_name = dismantle)]
107 fn dismantle_internal(this: &Creep, target: &Structure) -> i8;
108
109 #[wasm_bindgen(final, method, js_name = drop)]
110 fn drop_internal(this: &Creep, ty: ResourceType, amount: Option<u32>) -> i8;
111
112 #[wasm_bindgen(final, method, js_name = generateSafeMode)]
113 fn generate_safe_mode_internal(this: &Creep, target: &StructureController) -> i8;
114
115 #[wasm_bindgen(final, method, js_name = getActiveBodyparts)]
116 fn get_active_bodyparts_internal(this: &Creep, ty: Part) -> u8;
117
118 #[wasm_bindgen(final, method, js_name = harvest)]
119 fn harvest_internal(this: &Creep, target: &RoomObject) -> i8;
120
121 #[wasm_bindgen(final, method, js_name = heal)]
122 fn heal_internal(this: &Creep, target: &RoomObject) -> i8;
123
124 #[wasm_bindgen(final, method, js_name = move)]
125 fn move_direction_internal(this: &Creep, direction: Direction) -> i8;
126
127 #[wasm_bindgen(final, method, js_name = move)]
128 fn move_pulled_by_internal(this: &Creep, target: &Creep) -> i8;
129
130 #[wasm_bindgen(final, method, js_name = moveByPath)]
131 fn move_by_path_internal(this: &Creep, path: &JsValue) -> i8;
132
133 #[wasm_bindgen(final, method, js_name = moveTo)]
134 fn move_to_internal(this: &Creep, target: &JsValue, options: &JsValue) -> i8;
135
136 #[wasm_bindgen(final, method, js_name = notifyWhenAttacked)]
137 fn notify_when_attacked_internal(this: &Creep, enabled: bool) -> i8;
138
139 #[wasm_bindgen(final, method, js_name = pickup)]
140 fn pickup_internal(this: &Creep, target: &Resource) -> i8;
141
142 #[wasm_bindgen(final, method, js_name = pull)]
143 fn pull_internal(this: &Creep, target: &Creep) -> i8;
144
145 #[wasm_bindgen(final, method, js_name = rangedAttack)]
146 fn ranged_attack_internal(this: &Creep, target: &RoomObject) -> i8;
147
148 #[wasm_bindgen(final, method, js_name = rangedHeal)]
149 fn ranged_heal_internal(this: &Creep, target: &RoomObject) -> i8;
150
151 #[wasm_bindgen(final, method, js_name = rangedMassAttack)]
152 fn ranged_mass_attack_internal(this: &Creep) -> i8;
153
154 #[wasm_bindgen(final, method, js_name = repair)]
155 fn repair_internal(this: &Creep, target: &RoomObject) -> i8;
156
157 #[wasm_bindgen(final, method, js_name = reserveController)]
158 fn reserve_controller_internal(this: &Creep, target: &StructureController) -> i8;
159
160 #[wasm_bindgen(final, method, js_name = say)]
161 fn say_internal(this: &Creep, message: &str, public: bool) -> i8;
162
163 #[wasm_bindgen(final, method, js_name = signController)]
164 fn sign_controller_internal(this: &Creep, target: &StructureController, text: &str) -> i8;
165
166 #[wasm_bindgen(final, method, js_name = suicide)]
167 fn suicide_internal(this: &Creep) -> i8;
168
169 #[wasm_bindgen(final, method, js_name = transfer)]
170 fn transfer_internal(
171 this: &Creep,
172 target: &RoomObject,
173 ty: ResourceType,
174 amount: Option<u32>,
175 ) -> i8;
176
177 #[wasm_bindgen(final, method, js_name = upgradeController)]
178 fn upgrade_controller_internal(this: &Creep, target: &StructureController) -> i8;
179
180 #[wasm_bindgen(final, method, js_name = withdraw)]
181 fn withdraw_internal(
182 this: &Creep,
183 target: &RoomObject,
184 ty: ResourceType,
185 amount: Option<u32>,
186 ) -> i8;
187}
188
189impl Creep {
190 pub fn body(&self) -> Vec<BodyPart> {
195 self.body_internal().iter().map(BodyPart::from).collect()
196 }
197
198 pub fn fatigue(&self) -> u32 {
203 self.fatigue_internal()
204 }
205
206 pub fn hits(&self) -> u32 {
210 self.hits_internal()
211 }
212
213 pub fn hits_max(&self) -> u32 {
218 self.hits_max_internal()
219 }
220
221 pub fn memory(&self) -> JsValue {
225 self.memory_internal()
226 }
227
228 pub fn set_memory(&self, val: &JsValue) {
232 self.set_memory_internal(val)
233 }
234
235 pub fn my(&self) -> bool {
239 self.my_internal()
240 }
241
242 pub fn owner(&self) -> Owner {
246 self.owner_internal()
247 }
248
249 pub fn saying(&self) -> Option<JsString> {
253 self.saying_internal()
254 }
255
256 pub fn spawning(&self) -> bool {
260 self.spawning_internal()
261 }
262
263 pub fn store(&self) -> Store {
268 self.store_internal()
269 }
270
271 pub fn ticks_to_live(&self) -> Option<u32> {
275 self.ticks_to_live_internal()
276 }
277
278 pub fn attack<T>(&self, target: &T) -> Result<(), CreepAttackErrorCode>
282 where
283 T: ?Sized + Attackable,
284 {
285 CreepAttackErrorCode::result_from_i8(self.attack_internal(target.as_ref()))
286 }
287
288 pub fn attack_controller(
293 &self,
294 target: &StructureController,
295 ) -> Result<(), AttackControllerErrorCode> {
296 AttackControllerErrorCode::result_from_i8(self.attack_controller_internal(target))
297 }
298
299 pub fn build(&self, target: &ConstructionSite) -> Result<(), BuildErrorCode> {
304 BuildErrorCode::result_from_i8(self.build_internal(target))
305 }
306
307 pub fn cancel_order(&self, target: &JsString) -> Result<(), CreepCancelOrderErrorCode> {
313 CreepCancelOrderErrorCode::result_from_i8(self.cancel_order_internal(target))
314 }
315
316 pub fn claim_controller(
321 &self,
322 target: &StructureController,
323 ) -> Result<(), ClaimControllerErrorCode> {
324 ClaimControllerErrorCode::result_from_i8(self.claim_controller_internal(target))
325 }
326
327 #[cfg(feature = "seasonal-season-5")]
332 pub fn claim_reactor(&self, target: &Reactor) -> Result<(), CreepClaimReactorErrorCode> {
333 CreepClaimReactorErrorCode::result_from_i8(self.claim_reactor_internal(target))
334 }
335
336 pub fn dismantle<T>(&self, target: &T) -> Result<(), DismantleErrorCode>
348 where
349 T: ?Sized + Dismantleable,
350 {
351 DismantleErrorCode::result_from_i8(self.dismantle_internal(target.as_ref()))
352 }
353
354 pub fn drop(&self, ty: ResourceType, amount: Option<u32>) -> Result<(), DropErrorCode> {
358 DropErrorCode::result_from_i8(self.drop_internal(ty, amount))
359 }
360
361 pub fn generate_safe_mode(
369 &self,
370 target: &StructureController,
371 ) -> Result<(), GenerateSafeModeErrorCode> {
372 GenerateSafeModeErrorCode::result_from_i8(self.generate_safe_mode_internal(target))
373 }
374
375 pub fn get_active_bodyparts(&self, ty: Part) -> u8 {
380 self.get_active_bodyparts_internal(ty)
381 }
382
383 pub fn harvest<T>(&self, target: &T) -> Result<(), HarvestErrorCode>
391 where
392 T: ?Sized + Harvestable,
393 {
394 HarvestErrorCode::result_from_i8(self.harvest_internal(target.as_ref()))
395 }
396
397 pub fn heal<T>(&self, target: &T) -> Result<(), CreepHealErrorCode>
403 where
404 T: ?Sized + Healable,
405 {
406 CreepHealErrorCode::result_from_i8(self.heal_internal(target.as_ref()))
407 }
408
409 pub fn move_direction(&self, direction: Direction) -> Result<(), CreepMoveDirectionErrorCode> {
413 CreepMoveDirectionErrorCode::result_from_i8(self.move_direction_internal(direction))
414 }
415
416 pub fn move_pulled_by(&self, target: &Creep) -> Result<(), CreepMovePulledByErrorCode> {
420 CreepMovePulledByErrorCode::result_from_i8(self.move_pulled_by_internal(target))
421 }
422
423 pub fn move_by_path(&self, path: &JsValue) -> Result<(), CreepMoveByPathErrorCode> {
428 CreepMoveByPathErrorCode::result_from_i8(self.move_by_path_internal(path))
429 }
430
431 pub fn notify_when_attacked(&self, enabled: bool) -> Result<(), NotifyWhenAttackedErrorCode> {
435 NotifyWhenAttackedErrorCode::result_from_i8(self.notify_when_attacked_internal(enabled))
436 }
437
438 pub fn pickup(&self, target: &Resource) -> Result<(), PickupErrorCode> {
443 PickupErrorCode::result_from_i8(self.pickup_internal(target))
444 }
445
446 pub fn pull(&self, target: &Creep) -> Result<(), PullErrorCode> {
450 PullErrorCode::result_from_i8(self.pull_internal(target))
451 }
452
453 pub fn ranged_attack<T>(&self, target: &T) -> Result<(), RangedAttackErrorCode>
457 where
458 T: ?Sized + Attackable,
459 {
460 RangedAttackErrorCode::result_from_i8(self.ranged_attack_internal(target.as_ref()))
461 }
462
463 pub fn ranged_heal<T>(&self, target: &T) -> Result<(), RangedHealErrorCode>
467 where
468 T: ?Sized + Healable,
469 {
470 RangedHealErrorCode::result_from_i8(self.ranged_heal_internal(target.as_ref()))
471 }
472
473 pub fn ranged_mass_attack(&self) -> Result<(), RangedMassAttackErrorCode> {
478 RangedMassAttackErrorCode::result_from_i8(self.ranged_mass_attack_internal())
479 }
480
481 pub fn repair<T>(&self, target: &T) -> Result<(), CreepRepairErrorCode>
486 where
487 T: ?Sized + Repairable,
488 {
489 CreepRepairErrorCode::result_from_i8(self.repair_internal(target.as_ref()))
490 }
491
492 pub fn reserve_controller(
497 &self,
498 target: &StructureController,
499 ) -> Result<(), ReserveControllerErrorCode> {
500 ReserveControllerErrorCode::result_from_i8(self.reserve_controller_internal(target))
501 }
502
503 pub fn say(&self, message: &str, public: bool) -> Result<(), SayErrorCode> {
508 SayErrorCode::result_from_i8(self.say_internal(message, public))
509 }
510
511 pub fn sign_controller(
516 &self,
517 target: &StructureController,
518 text: &str,
519 ) -> Result<(), SignControllerErrorCode> {
520 SignControllerErrorCode::result_from_i8(self.sign_controller_internal(target, text))
521 }
522
523 pub fn suicide(&self) -> Result<(), SuicideErrorCode> {
529 SuicideErrorCode::result_from_i8(self.suicide_internal())
530 }
531
532 pub fn upgrade_controller(
537 &self,
538 target: &StructureController,
539 ) -> Result<(), UpgradeControllerErrorCode> {
540 UpgradeControllerErrorCode::result_from_i8(self.upgrade_controller_internal(target))
541 }
542
543 pub fn move_to<T>(&self, target: T) -> Result<(), CreepMoveToErrorCode>
551 where
552 T: HasPosition,
553 {
554 let target: RoomPosition = target.pos().into();
555 CreepMoveToErrorCode::result_from_i8(self.move_to_internal(&target, &JsValue::UNDEFINED))
556 }
557
558 pub fn move_to_with_options<T, F>(
566 &self,
567 target: T,
568 options: Option<MoveToOptions<F>>,
569 ) -> Result<(), CreepMoveToErrorCode>
570 where
571 T: HasPosition,
572 F: FnMut(RoomName, CostMatrix) -> SingleRoomCostResult,
573 {
574 let target: RoomPosition = target.pos().into();
575
576 if let Some(options) = options {
577 options.into_js_options(|js_options| {
578 CreepMoveToErrorCode::result_from_i8(self.move_to_internal(&target, js_options))
579 })
580 } else {
581 CreepMoveToErrorCode::result_from_i8(
582 self.move_to_internal(&target, &JsValue::UNDEFINED),
583 )
584 }
585 }
586}
587
588impl JsCollectionFromValue for Creep {
589 fn from_value(val: JsValue) -> Self {
590 val.unchecked_into()
591 }
592}
593
594impl HasHits for Creep {
595 fn hits(&self) -> u32 {
596 self.hits()
597 }
598
599 fn hits_max(&self) -> u32 {
600 self.hits_max()
601 }
602}
603
604impl MaybeHasId for Creep {
605 fn try_js_raw_id(&self) -> Option<JsString> {
610 self.id_internal()
611 }
612}
613
614impl HasStore for Creep {
615 fn store(&self) -> Store {
616 self.store()
617 }
618}
619
620impl Attackable for Creep {}
621impl Healable for Creep {}
622impl Transferable for Creep {}
623
624impl SharedCreepProperties for Creep {
625 fn memory(&self) -> JsValue {
626 self.memory()
627 }
628
629 fn set_memory(&self, val: &JsValue) {
630 self.set_memory(val)
631 }
632
633 fn my(&self) -> bool {
634 self.my()
635 }
636
637 fn name(&self) -> String {
638 self.name_internal()
639 }
640
641 fn name_jsstring(&self) -> JsString {
642 self.name_jsstring_internal()
643 }
644
645 fn owner(&self) -> Owner {
646 self.owner()
647 }
648
649 fn saying(&self) -> Option<JsString> {
650 self.saying()
651 }
652
653 fn ticks_to_live(&self) -> Option<u32> {
654 self.ticks_to_live()
655 }
656
657 fn drop(&self, ty: ResourceType, amount: Option<u32>) -> Result<(), DropErrorCode> {
658 self.drop(ty, amount)
659 }
660
661 fn notify_when_attacked(&self, enabled: bool) -> Result<(), NotifyWhenAttackedErrorCode> {
662 self.notify_when_attacked(enabled)
663 }
664
665 fn pickup(&self, target: &Resource) -> Result<(), PickupErrorCode> {
666 self.pickup(target)
667 }
668
669 fn say(&self, message: &str, public: bool) -> Result<(), SayErrorCode> {
670 self.say(message, public)
671 }
672
673 fn suicide(&self) -> Result<(), SuicideErrorCode> {
674 self.suicide()
675 }
676
677 fn transfer<T>(
678 &self,
679 target: &T,
680 ty: ResourceType,
681 amount: Option<u32>,
682 ) -> Result<(), TransferErrorCode>
683 where
684 T: Transferable + ?Sized,
685 {
686 TransferErrorCode::result_from_i8(self.transfer_internal(target.as_ref(), ty, amount))
687 }
688
689 fn withdraw<T>(
690 &self,
691 target: &T,
692 ty: ResourceType,
693 amount: Option<u32>,
694 ) -> Result<(), WithdrawErrorCode>
695 where
696 T: Withdrawable + ?Sized,
697 {
698 WithdrawErrorCode::result_from_i8(self.withdraw_internal(target.as_ref(), ty, amount))
699 }
700}
701
702#[wasm_bindgen]
703extern "C" {
704 #[wasm_bindgen]
708 pub type BodyPart;
709
710 #[wasm_bindgen(method, getter)]
711 pub fn boost(this: &BodyPart) -> Option<ResourceType>;
712
713 #[wasm_bindgen(method, getter = type)]
714 pub fn part(this: &BodyPart) -> Part;
715
716 #[wasm_bindgen(method, getter)]
717 pub fn hits(this: &BodyPart) -> u32;
718}