1use crate::{
2 comp::{Density, Mass, item::Reagent},
3 consts::{IRON_DENSITY, WATER_DENSITY},
4 make_case_elim,
5};
6use rand::{seq::SliceRandom, thread_rng};
7use serde::{Deserialize, Serialize};
8use vek::Vec3;
9
10make_case_elim!(
11 body,
12 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
13 #[repr(u32)]
14 pub enum Body {
15 Arrow = 0,
16 Bomb = 1,
17 Scarecrow = 2,
18 Cauldron = 3,
19 ChestVines = 4,
20 Chest = 5,
21 ChestDark = 6,
22 ChestDemon = 7,
23 ChestGold = 8,
24 ChestLight = 9,
25 ChestOpen = 10,
26 ChestSkull = 11,
27 Pumpkin = 12,
28 Pumpkin2 = 13,
29 Pumpkin3 = 14,
30 Pumpkin4 = 15,
31 Pumpkin5 = 16,
32 Campfire = 17,
33 LanternGround = 18,
34 LanternGroundOpen = 19,
35 LanternStanding2 = 20,
36 LanternStanding = 21,
37 PotionBlue = 22,
38 PotionGreen = 23,
39 PotionRed = 24,
40 Crate = 25,
41 Tent = 26,
42 WindowSpooky = 27,
43 DoorSpooky = 28,
44 Anvil = 29,
45 Gravestone = 30,
46 Gravestone2 = 31,
47 Bench = 32,
48 Chair = 33,
49 Chair2 = 34,
50 Chair3 = 35,
51 Table = 36,
52 Table2 = 37,
53 Table3 = 38,
54 Drawer = 39,
55 BedBlue = 40,
56 Carpet = 41,
57 Bedroll = 42,
58 CarpetHumanRound = 43,
59 CarpetHumanSquare = 44,
60 CarpetHumanSquare2 = 45,
61 CarpetHumanSquircle = 46,
62 Pouch = 47,
63 CraftingBench = 48,
64 BoltFire = 49,
65 ArrowSnake = 50,
66 CampfireLit = 51,
67 BoltFireBig = 52,
68 TrainingDummy = 53,
69 FireworkBlue = 54,
70 FireworkGreen = 55,
71 FireworkPurple = 56,
72 FireworkRed = 57,
73 FireworkWhite = 58,
74 FireworkYellow = 59,
75 MultiArrow = 60,
76 BoltNature = 61,
77 ToughMeat = 62,
78 BeastMeat = 63,
79 Crossbow = 64,
80 ArrowTurret = 65,
81 Coins = 66,
82 GoldOre = 67,
83 SilverOre = 68,
84 ClayRocket = 69,
85 HaniwaSentry = 70,
86 SeaLantern = 71,
87 Snowball = 72,
88 BirdMeat = 73,
89 FishMeat = 74,
90 SmallMeat = 75,
91 Tornado = 76,
92 Apple = 77,
93 Hive = 78,
94 Coconut = 79,
95 SpitPoison = 80,
96 BoltIcicle = 81,
97 Dart = 82,
98 GnarlingTotemRed = 83,
99 GnarlingTotemGreen = 84,
100 GnarlingTotemWhite = 85,
101 DagonBomb = 86,
102 BarrelOrgan = 87,
103 IceBomb = 88,
104 SpectralSwordSmall = 89,
105 SpectralSwordLarge = 90,
106 LaserBeam = 91,
107 AdletSpear = 92,
108 AdletTrap = 93,
109 Flamethrower = 94,
110 Mine = 95,
111 LightningBolt = 96,
112 SpearIcicle = 97,
113 Portal = 98,
114 PortalActive = 99,
115 FieryTornado = 100,
116 FireRainDrop = 101,
117 ArrowClay = 102,
118 GrenadeClay = 103,
119 Pebble = 104,
120 LaserBeamSmall = 105,
121 TerracottaStatue = 106,
122 TerracottaDemolisherBomb = 107,
123 BoltBesieger = 108,
124 SurpriseEgg = 109,
125 BubbleBomb = 110,
126 IronPikeBomb = 111,
127 Lavathrower = 112,
128 Scroll = 113,
129 PoisonBall = 114,
130 StrigoiHead = 115,
131 HarlequinDagger = 116,
132 BloodBomb = 117,
133 MinotaurAxe = 118,
134 BorealTrap = 119,
135 }
136);
137
138impl Body {
139 pub fn random() -> Self {
140 let mut rng = thread_rng();
141 *ALL_OBJECTS.choose(&mut rng).unwrap()
142 }
143}
144
145pub const ALL_OBJECTS: [Body; 120] = [
146 Body::Arrow,
147 Body::Bomb,
148 Body::Scarecrow,
149 Body::Cauldron,
150 Body::ChestVines,
151 Body::Chest,
152 Body::ChestDark,
153 Body::ChestDemon,
154 Body::ChestGold,
155 Body::ChestLight,
156 Body::ChestOpen,
157 Body::ChestSkull,
158 Body::SpectralSwordSmall,
159 Body::SpectralSwordLarge,
160 Body::Pumpkin,
161 Body::Pumpkin2,
162 Body::Pumpkin3,
163 Body::Pumpkin4,
164 Body::Pumpkin5,
165 Body::Campfire,
166 Body::CampfireLit,
167 Body::LanternGround,
168 Body::LanternGroundOpen,
169 Body::LanternStanding,
170 Body::LanternStanding2,
171 Body::PotionRed,
172 Body::PotionBlue,
173 Body::PotionGreen,
174 Body::Crate,
175 Body::Tent,
176 Body::WindowSpooky,
177 Body::DoorSpooky,
178 Body::Anvil,
179 Body::Gravestone,
180 Body::Gravestone2,
181 Body::Bench,
182 Body::Chair,
183 Body::Chair2,
184 Body::Chair3,
185 Body::Table,
186 Body::Table2,
187 Body::Table3,
188 Body::Drawer,
189 Body::BedBlue,
190 Body::Carpet,
191 Body::Bedroll,
192 Body::CarpetHumanRound,
193 Body::CarpetHumanSquare,
194 Body::CarpetHumanSquare2,
195 Body::CarpetHumanSquircle,
196 Body::Pouch,
197 Body::CraftingBench,
198 Body::BoltFire,
199 Body::BoltFireBig,
200 Body::ArrowSnake,
201 Body::TrainingDummy,
202 Body::FireworkBlue,
203 Body::FireworkGreen,
204 Body::FireworkPurple,
205 Body::FireworkRed,
206 Body::FireworkWhite,
207 Body::FireworkYellow,
208 Body::MultiArrow,
209 Body::BoltNature,
210 Body::ToughMeat,
211 Body::BeastMeat,
212 Body::Crossbow,
213 Body::ArrowTurret,
214 Body::Coins,
215 Body::SilverOre,
216 Body::GoldOre,
217 Body::ClayRocket,
218 Body::HaniwaSentry,
219 Body::SeaLantern,
220 Body::Snowball,
221 Body::BirdMeat,
222 Body::FishMeat,
223 Body::SmallMeat,
224 Body::Tornado,
225 Body::Apple,
226 Body::Hive,
227 Body::Coconut,
228 Body::SpitPoison,
229 Body::BoltIcicle,
230 Body::Dart,
231 Body::GnarlingTotemRed,
232 Body::GnarlingTotemWhite,
233 Body::GnarlingTotemGreen,
234 Body::DagonBomb,
235 Body::TerracottaDemolisherBomb,
236 Body::BarrelOrgan,
237 Body::IceBomb,
238 Body::LaserBeam,
239 Body::LaserBeamSmall,
240 Body::AdletSpear,
241 Body::AdletTrap,
242 Body::Flamethrower,
243 Body::Mine,
244 Body::LightningBolt,
245 Body::SpearIcicle,
246 Body::Portal,
247 Body::PortalActive,
248 Body::FieryTornado,
249 Body::FireRainDrop,
250 Body::ArrowClay,
251 Body::GrenadeClay,
252 Body::Pebble,
253 Body::TerracottaStatue,
254 Body::BoltBesieger,
255 Body::SurpriseEgg,
256 Body::BubbleBomb,
257 Body::IronPikeBomb,
258 Body::Lavathrower,
259 Body::Scroll,
260 Body::PoisonBall,
261 Body::StrigoiHead,
262 Body::HarlequinDagger,
263 Body::BloodBomb,
264 Body::MinotaurAxe,
265 Body::BorealTrap,
266];
267
268impl From<Body> for super::Body {
269 fn from(body: Body) -> Self { super::Body::Object(body) }
270}
271
272impl Body {
273 pub fn to_string(self) -> &'static str {
274 match self {
275 Body::Arrow => "arrow",
276 Body::Bomb => "bomb",
277 Body::Scarecrow => "scarecrow",
278 Body::Cauldron => "cauldron",
279 Body::ChestVines => "chest_vines",
280 Body::Chest => "chest",
281 Body::ChestDark => "chest_dark",
282 Body::ChestDemon => "chest_demon",
283 Body::ChestGold => "chest_gold",
284 Body::ChestLight => "chest_light",
285 Body::ChestOpen => "chest_open",
286 Body::ChestSkull => "chest_skull",
287 Body::Pumpkin => "pumpkin",
288 Body::Pumpkin2 => "pumpkin_2",
289 Body::Pumpkin3 => "pumpkin_3",
290 Body::Pumpkin4 => "pumpkin_4",
291 Body::Pumpkin5 => "pumpkin_5",
292 Body::Campfire => "campfire",
293 Body::CampfireLit => "campfire_lit",
294 Body::LanternGround => "lantern_ground",
295 Body::LanternGroundOpen => "lantern_ground_open",
296 Body::LanternStanding => "lantern_standing",
297 Body::LanternStanding2 => "lantern_standing_2",
298 Body::PotionRed => "potion_red",
299 Body::PotionBlue => "potion_blue",
300 Body::PotionGreen => "potion_green",
301 Body::Crate => "crate",
302 Body::Tent => "tent",
303 Body::WindowSpooky => "window_spooky",
304 Body::DoorSpooky => "door_spooky",
305 Body::Anvil => "anvil",
306 Body::Gravestone => "gravestone",
307 Body::Gravestone2 => "gravestone_2",
308 Body::Bench => "bench",
309 Body::Chair => "chair",
310 Body::Chair2 => "chair_2",
311 Body::Chair3 => "chair_3",
312 Body::Table => "table",
313 Body::Table2 => "table_2",
314 Body::Table3 => "table_3",
315 Body::Drawer => "drawer",
316 Body::BedBlue => "bed_blue",
317 Body::Carpet => "carpet",
318 Body::Bedroll => "bedroll",
319 Body::CarpetHumanRound => "carpet_human_round",
320 Body::CarpetHumanSquare => "carpet_human_square",
321 Body::CarpetHumanSquare2 => "carpet_human_square_2",
322 Body::CarpetHumanSquircle => "carpet_human_squircle",
323 Body::Pouch => "pouch",
324 Body::CraftingBench => "crafting_bench",
325 Body::BoltFire => "bolt_fire",
326 Body::BoltFireBig => "bolt_fire_big",
327 Body::ArrowSnake => "arrow_snake",
328 Body::TrainingDummy => "training_dummy",
329 Body::FireworkBlue => "firework_blue",
330 Body::FireworkGreen => "firework_green",
331 Body::FireworkPurple => "firework_purple",
332 Body::FireworkRed => "firework_red",
333 Body::FireworkWhite => "firework_white",
334 Body::FireworkYellow => "firework_yellow",
335 Body::MultiArrow => "multi_arrow",
336 Body::BoltNature => "bolt_nature",
337 Body::ToughMeat => "tough_meat",
338 Body::BeastMeat => "beast_meat",
339 Body::Crossbow => "crossbow",
340 Body::ArrowTurret => "arrow_turret",
341 Body::Coins => "coins",
342 Body::SilverOre => "silver_ore",
343 Body::GoldOre => "gold_ore",
344 Body::ClayRocket => "clay_rocket",
345 Body::HaniwaSentry => "haniwa_sentry",
346 Body::SeaLantern => "sea_lantern",
347 Body::Snowball => "snowball",
348 Body::BirdMeat => "bird_meat",
349 Body::FishMeat => "fish_meat",
350 Body::SmallMeat => "small_meat",
351 Body::Tornado => "tornado",
352 Body::Apple => "apple",
353 Body::Hive => "hive",
354 Body::Coconut => "coconut",
355 Body::SpitPoison => "spit_poison",
356 Body::BoltIcicle => "bolt_icicle",
357 Body::Dart => "dart",
358 Body::GnarlingTotemRed => "gnarling_totem_red",
359 Body::GnarlingTotemGreen => "gnarling_totem_green",
360 Body::GnarlingTotemWhite => "gnarling_totem_white",
361 Body::DagonBomb => "dagon_bomb",
362 Body::TerracottaDemolisherBomb => "terracotta_demolisher_bomb",
363 Body::BarrelOrgan => "barrel_organ",
364 Body::IceBomb => "ice_bomb",
365 Body::SpectralSwordSmall => "spectral_sword_small",
366 Body::SpectralSwordLarge => "spectral_sword_large",
367 Body::LaserBeam => "laser_beam",
368 Body::LaserBeamSmall => "laser_beam_small",
369 Body::AdletSpear => "adlet_spear",
370 Body::AdletTrap => "adlet_trap",
371 Body::Flamethrower => "flamethrower",
372 Body::Lavathrower => "lavathrower",
373 Body::Mine => "mine",
374 Body::LightningBolt => "lightning_bolt",
375 Body::SpearIcicle => "spear_icicle",
376 Body::Portal => "portal",
377 Body::PortalActive => "portal_active",
378 Body::FieryTornado => "fiery_tornado",
379 Body::FireRainDrop => "fire_rain_drop",
380 Body::ArrowClay => "arrow_clay",
381 Body::GrenadeClay => "grenade_clay",
382 Body::Pebble => "pebble",
383 Body::TerracottaStatue => "terracotta_statue",
384 Body::BoltBesieger => "besieger_bolt",
385 Body::SurpriseEgg => "surprise_egg",
386 Body::BubbleBomb => "bubble_bomb",
387 Body::IronPikeBomb => "iron_pike_bomb",
388 Body::Scroll => "recipe",
389 Body::PoisonBall => "poison_ball",
390 Body::StrigoiHead => "strigoi_head",
391 Body::HarlequinDagger => "harlequin_dagger",
392 Body::BloodBomb => "blood_bomb",
393 Body::MinotaurAxe => "minotaur_axe",
394 Body::BorealTrap => "boreal_trap",
395 }
396 }
397
398 pub fn for_firework(reagent: Reagent) -> Body {
399 match reagent {
400 Reagent::Blue => Body::FireworkBlue,
401 Reagent::Green => Body::FireworkGreen,
402 Reagent::Purple => Body::FireworkPurple,
403 Reagent::Red => Body::FireworkRed,
404 Reagent::White => Body::FireworkWhite,
405 Reagent::Yellow => Body::FireworkYellow,
406 Reagent::Phoenix => Body::FireRainDrop,
407 }
408 }
409
410 pub fn density(&self) -> Density {
411 let density = match self {
412 Body::Anvil | Body::Cauldron => IRON_DENSITY,
413 Body::Arrow
414 | Body::ArrowSnake
415 | Body::ArrowTurret
416 | Body::MultiArrow
417 | Body::ArrowClay
418 | Body::BoltBesieger
419 | Body::Dart
420 | Body::DagonBomb
421 | Body::TerracottaDemolisherBomb
422 | Body::SpectralSwordSmall
423 | Body::SpectralSwordLarge
424 | Body::AdletSpear
425 | Body::HarlequinDagger
426 | Body::AdletTrap
427 | Body::Flamethrower
428 | Body::Lavathrower
429 | Body::BorealTrap
430 | Body::BloodBomb => 500.0,
431 Body::Bomb | Body::Mine | Body::SurpriseEgg => 2000.0, Body::Crate => 300.0, Body::Scarecrow => 900.0,
435 Body::TrainingDummy => 2000.0,
436 Body::Snowball => 0.9 * WATER_DENSITY,
437 Body::Pebble => 1000.0,
438 Body::Scroll => 0.5 * WATER_DENSITY,
439 _ => 1.1 * WATER_DENSITY,
441 };
442
443 Density(density)
444 }
445
446 pub fn mass(&self) -> Mass {
447 let m = match self {
448 Body::Anvil => 100.0,
450 Body::Arrow | Body::ArrowSnake | Body::ArrowTurret | Body::MultiArrow | Body::Dart => {
451 0.003
452 },
453 Body::SpectralSwordSmall => 0.5,
454 Body::SpectralSwordLarge => 50.0,
455 Body::BedBlue => 50.0,
456 Body::Bedroll => 3.0,
457 Body::Bench => 100.0,
458 Body::BoltFire
459 | Body::BoltFireBig
460 | Body::BoltNature
461 | Body::BoltIcicle
462 | Body::FireRainDrop
463 | Body::ArrowClay
464 | Body::Pebble
465 | Body::BubbleBomb
466 | Body::IronPikeBomb
467 | Body::BoltBesieger
468 | Body::PoisonBall => 1.0,
469 Body::SpitPoison => 100.0,
470 Body::Bomb
471 | Body::DagonBomb
472 | Body::SurpriseEgg
473 | Body::TerracottaDemolisherBomb
474 | Body::BloodBomb => {
475 0.5 * IRON_DENSITY * std::f32::consts::PI / 6.0 * self.dimensions().x.powi(3)
476 },
477 Body::Campfire | Body::CampfireLit | Body::BarrelOrgan | Body::TerracottaStatue => {
478 300.0
479 },
480 Body::Carpet
481 | Body::CarpetHumanRound
482 | Body::CarpetHumanSquare
483 | Body::CarpetHumanSquare2
484 | Body::CarpetHumanSquircle => 10.0,
485 Body::Cauldron => 5.0,
486 Body::Chair | Body::Chair2 | Body::Chair3 => 10.0,
487 Body::Chest
488 | Body::ChestDark
489 | Body::ChestDemon
490 | Body::ChestGold
491 | Body::ChestLight
492 | Body::ChestOpen
493 | Body::ChestSkull
494 | Body::ChestVines => 100.0,
495 Body::Coins | Body::Scroll => 1.0,
496 Body::CraftingBench => 100.0,
497 Body::Crate => 50.0,
498 Body::Crossbow => 200.0,
499 Body::Flamethrower | Body::Lavathrower => 200.0,
500 Body::DoorSpooky => 20.0,
501 Body::Drawer => 50.0,
502 Body::FireworkBlue
503 | Body::FireworkGreen
504 | Body::FireworkPurple
505 | Body::FireworkRed
506 | Body::FireworkWhite
507 | Body::FireworkYellow => 1.0,
508 Body::Gravestone => 100.0,
509 Body::Gravestone2 => 100.0,
510 Body::LanternGround
511 | Body::LanternGroundOpen
512 | Body::LanternStanding
513 | Body::LanternStanding2 => 3.0,
514 Body::ToughMeat => 50.0,
515 Body::BeastMeat => 50.0,
516 Body::PotionBlue | Body::PotionGreen | Body::PotionRed => 5.0,
517 Body::Pouch => 1.0,
518 Body::Pumpkin
519 | Body::Pumpkin2
520 | Body::Pumpkin3
521 | Body::Pumpkin4
522 | Body::Pumpkin5
523 | Body::StrigoiHead => 10.0,
524 Body::Scarecrow => 50.0,
525 Body::Table | Body::Table2 | Body::Table3 => 50.0,
526 Body::Tent => 50.0,
527 Body::TrainingDummy => 60.0,
528 Body::WindowSpooky => 10.0,
529 Body::SilverOre => 1000.0,
530 Body::GoldOre => 1000.0,
531 Body::ClayRocket | Body::GrenadeClay => 50.0,
532 Body::HaniwaSentry => 300.0,
533 Body::SeaLantern => 1000.0,
534 Body::MinotaurAxe => 100000.0,
535 Body::Snowball => 7360.0, Body::FishMeat => 10.0,
537 Body::BirdMeat => 10.0,
538 Body::SmallMeat => 10.0,
539 Body::Tornado | Body::FieryTornado => 50.0,
540 Body::Apple => 2.0,
541 Body::Hive => 2.0,
542 Body::Coconut => 2.0,
543 Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => 100.0,
544 Body::IceBomb => 12298.0, Body::LaserBeam | Body::LaserBeamSmall => 80000.0,
546 Body::AdletSpear => 1.5,
547 Body::AdletTrap => 10.0,
548 Body::Mine => 100.0,
549 Body::HarlequinDagger => 1.5,
550 Body::BorealTrap => 10.0,
551 Body::LightningBolt | Body::SpearIcicle => 20000.0,
552 Body::Portal | Body::PortalActive => 10., };
554
555 Mass(m)
556 }
557
558 pub fn dimensions(&self) -> Vec3<f32> {
559 match self {
560 Body::Arrow
561 | Body::ArrowSnake
562 | Body::MultiArrow
563 | Body::ArrowTurret
564 | Body::ArrowClay
565 | Body::BoltBesieger
566 | Body::Dart
567 | Body::HarlequinDagger
568 | Body::AdletSpear => Vec3::new(0.01, 0.8, 0.01),
569 Body::AdletTrap => Vec3::new(1.0, 0.6, 0.3),
570 Body::BoltFire | Body::PoisonBall => Vec3::new(0.1, 0.1, 0.1),
571 Body::SpectralSwordSmall => Vec3::new(0.2, 0.9, 0.1),
572 Body::SpectralSwordLarge => Vec3::new(0.2, 1.5, 0.1),
573 Body::Crossbow => Vec3::new(3.0, 3.0, 1.5),
574 Body::Flamethrower => Vec3::new(3.0, 3.0, 2.5),
575 Body::Lavathrower => Vec3::new(3.0, 3.0, 2.0),
576 Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
577 Body::SeaLantern => Vec3::new(0.8, 0.8, 1.4),
578 Body::Snowball => Vec3::broadcast(2.5),
579 Body::Tornado | Body::FieryTornado => Vec3::new(2.0, 2.0, 3.4),
580 Body::TrainingDummy => Vec3::new(1.5, 1.5, 3.0),
581 Body::BorealTrap => Vec3::new(1.0, 0.6, 0.3),
582 Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => {
583 Vec3::new(0.8, 0.8, 1.4)
584 },
585 Body::BarrelOrgan => Vec3::new(4.0, 2.0, 3.0),
586 Body::TerracottaStatue => Vec3::new(5.0, 5.0, 5.0),
587 Body::IceBomb => Vec3::broadcast(2.5),
588 Body::LaserBeam => Vec3::new(8.0, 8.0, 8.0),
589 Body::LaserBeamSmall => Vec3::new(1.0, 1.0, 1.0),
590 Body::Mine => Vec3::new(0.8, 0.8, 0.5),
591 Body::LightningBolt | Body::SpearIcicle => Vec3::new(1.0, 1.0, 1.0),
592 Body::FireRainDrop => Vec3::new(0.01, 0.01, 0.02),
593 Body::Pebble => Vec3::new(0.4, 0.4, 0.4),
594 Body::MinotaurAxe => Vec3::new(5.0, 5.0, 5.0),
595 _ => Vec3::broadcast(0.5),
597 }
598 }
599}