steel_core/poi/poi_instance.rs
1//! Individual point of interest instance.
2
3use steel_utils::BlockPos;
4
5/// A single point of interest at a specific block position.
6///
7/// Tracks the POI type and available tickets (e.g., a bed has 1 ticket
8/// that gets reserved when a villager claims it).
9#[derive(Debug, Clone)]
10pub struct PointOfInterest {
11 /// The block position of this POI.
12 pub pos: BlockPos,
13 /// The registry ID of this POI's type.
14 pub poi_type_id: usize,
15 /// Number of tickets still available for claiming.
16 pub free_tickets: u32,
17}
18
19impl PointOfInterest {
20 /// Creates a new POI with all tickets available.
21 #[must_use]
22 pub const fn new(pos: BlockPos, poi_type_id: usize, max_tickets: u32) -> Self {
23 Self {
24 pos,
25 poi_type_id,
26 free_tickets: max_tickets,
27 }
28 }
29
30 /// Attempts to reserve a ticket. Returns `true` if successful.
31 pub const fn reserve_ticket(&mut self) -> bool {
32 if self.free_tickets > 0 {
33 self.free_tickets -= 1;
34 true
35 } else {
36 false
37 }
38 }
39
40 /// Releases a previously reserved ticket. Returns `true` if successful.
41 pub const fn release_ticket(&mut self, max_tickets: u32) -> bool {
42 if self.free_tickets < max_tickets {
43 self.free_tickets += 1;
44 true
45 } else {
46 false
47 }
48 }
49
50 /// Returns `true` if at least one ticket is available.
51 #[must_use]
52 pub const fn has_space(&self) -> bool {
53 self.free_tickets > 0
54 }
55
56 /// Returns `true` if at least one ticket has been reserved.
57 ///
58 /// Vanilla equivalent: `freeTickets != maxTickets`.
59 #[must_use]
60 pub const fn is_occupied(&self, max_tickets: u32) -> bool {
61 self.free_tickets != max_tickets
62 }
63}