dreamwell_engine/physics/
promotion.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum PromotionTarget {
6 Pickup,
7 Hazard,
8 Interactable,
9 WorldScar,
10 PersistentDebris,
11 ResourceNode,
12 AIStimulus,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum PromotionAuthority {
18 ClientSuggestsServerConfirms,
19 ServerOnly,
20 EventDeterministic,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct PromotionRule {
26 pub when: String,
27 pub min_age: f32,
28 pub requires_tags: Vec<String>,
29 pub set_tags: Vec<String>,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct PromotionPolicy {
35 pub enabled: bool,
36 pub target: PromotionTarget,
37 pub rules: Vec<PromotionRule>,
38 pub authority: PromotionAuthority,
39}
40
41impl Default for PromotionPolicy {
42 fn default() -> Self {
43 Self {
44 enabled: false,
45 target: PromotionTarget::Pickup,
46 rules: Vec::new(),
47 authority: PromotionAuthority::ClientSuggestsServerConfirms,
48 }
49 }
50}
51
52impl PromotionTarget {
53 pub const ALL: &[PromotionTarget] = &[
54 Self::Pickup,
55 Self::Hazard,
56 Self::Interactable,
57 Self::WorldScar,
58 Self::PersistentDebris,
59 Self::ResourceNode,
60 Self::AIStimulus,
61 ];
62
63 pub fn name(&self) -> &'static str {
64 match self {
65 Self::Pickup => "Pickup",
66 Self::Hazard => "Hazard",
67 Self::Interactable => "Interactable",
68 Self::WorldScar => "World Scar",
69 Self::PersistentDebris => "Persistent Debris",
70 Self::ResourceNode => "Resource Node",
71 Self::AIStimulus => "AI Stimulus",
72 }
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn promotion_target_all() {
82 assert_eq!(PromotionTarget::ALL.len(), 7);
83 }
84
85 #[test]
86 fn promotion_policy_default() {
87 let p = PromotionPolicy::default();
88 assert!(!p.enabled);
89 }
90
91 #[test]
92 fn promotion_policy_serde() {
93 let p = PromotionPolicy {
94 enabled: true,
95 target: PromotionTarget::Pickup,
96 authority: PromotionAuthority::ClientSuggestsServerConfirms,
97 rules: vec![PromotionRule {
98 when: "resting".into(),
99 min_age: 1.5,
100 requires_tags: vec!["isDebris".into(), "isStone".into()],
101 set_tags: vec!["isPickupable".into(), "signal.promoted".into()],
102 }],
103 };
104 let json = serde_json::to_string(&p).unwrap();
105 let restored: PromotionPolicy = serde_json::from_str(&json).unwrap();
106 assert_eq!(restored.rules.len(), 1);
107 }
108}