banished_game/people/
happiness.rs1use crate::town::Sim;
13
14impl Sim<'_, '_> {
15 pub(crate) fn happiness_active(&self, e: usize) -> bool {
19 let Some(site) = self.sites.get(&e) else {
20 return false;
21 };
22 let Some(d) = self.site_templates[site.template].happiness else {
23 return false;
24 };
25 if d.kind == 5 {
26 return true;
27 }
28 if d.needs_workers {
29 if let Some(w) = self.workforce.workplaces.get(&e) {
30 if w.workers.is_empty() || !w.enabled {
31 return false;
32 }
33 }
34 }
35 if !d.needs_stock {
36 return true;
37 }
38 self.storages[site.storage]
39 .items
40 .iter()
41 .any(|i| d.mask & self.materials[i.material].flags != 0)
42 }
43
44 fn happiness_layer(&mut self, e: usize, delta: i32) {
47 let Some(site) = self.sites.get(&e) else {
48 return;
49 };
50 let t = &self.site_templates[site.template];
51 let (Some(d), radius) = (t.happiness, t.radius.unwrap_or(0)) else {
52 return;
53 };
54 let layer = if (0..=4).contains(&d.kind) {
55 d.kind as usize
56 } else {
57 5
58 };
59 let (x, y) = self.placed[e].cell;
60 let (w, h) = self.placed[e].footprint;
61 self.cells
62 .add_layer(layer, (w >> 1) + x, (h >> 1) + y, radius, delta);
63 }
64
65 fn happiness_register(&mut self, e: usize) {
67 self.happiness_layer(e, 1);
68 self.happiness.push(e);
69 if let Some(s) = self.sites.get_mut(&e) {
70 s.happiness_registered = true;
71 }
72 }
73
74 fn happiness_unregister(&mut self, e: usize) {
76 if let Some(i) = self.happiness.iter().position(|&x| x == e) {
77 self.happiness.remove(i);
78 }
79 self.happiness_layer(e, -1);
80 if let Some(s) = self.sites.get_mut(&e) {
81 s.happiness_registered = false;
82 }
83 }
84
85 fn happiness_registered(&self, e: usize) -> bool {
86 self.sites.get(&e).is_some_and(|s| s.happiness_registered)
87 }
88
89 pub(crate) fn happiness_enter(&mut self, e: usize) {
91 if !self.happiness_registered(e) && self.happiness_active(e) {
92 self.happiness_register(e);
93 }
94 }
95
96 pub(crate) fn happiness_update(&mut self, e: usize) {
98 let active = self.happiness_active(e);
99 if !self.happiness_registered(e) {
100 if active {
101 self.happiness_register(e);
102 }
103 } else if !active {
104 self.happiness_unregister(e);
105 }
106 }
107
108 pub(crate) fn happiness_leave(&mut self, e: usize) {
110 if self.happiness_registered(e) {
111 self.happiness_unregister(e);
112 }
113 }
114
115 pub fn happiness_visit(&mut self, e: usize) {
121 let Some(site) = self.sites.get(&e) else {
122 return;
123 };
124 let Some(d) = self.site_templates[site.template].happiness else {
125 return;
126 };
127 if !d.needs_stock {
128 return;
129 }
130 let storage = &mut self.storages[site.storage];
131 let found = storage
132 .items
133 .iter()
134 .find(|i| d.mask & self.materials[i.material].flags != 0 && 0 < i.count - i.reserved);
135 if let Some(m) = found.map(|i| i.material) {
136 storage.remove(m, 1);
137 self.count_used(m, 1);
138 }
139 }
140}