rustic_mountain_core/objects/
fallfloor.rs

1use std::cell::RefCell;
2use std::rc::Rc;
3
4use crate::{structures::*, Celeste};
5use serde::{Deserialize, Serialize};
6
7#[derive(Serialize, Deserialize)]
8pub struct FallFloor {
9    state: u8,
10    delay: u8,
11}
12impl FallFloor {
13    pub fn init(_celeste: &mut Celeste, x: f32, y: f32) -> Object {
14        Object {
15            pos: Vector { x, y },
16            spd: Vector { x: 0.0, y: 0.0 },
17            rem: Vector { x: 0.0, y: 0.0 },
18            spr: 23,
19            hitbox: Rectangle {
20                x: 0.0,
21                y: 0.0,
22                w: 8.0,
23                h: 8.0,
24            },
25            flip: FlipState { x: false, y: false },
26            collidable: true,
27            obj_type: ObjectType::FallFloor(Rc::new(RefCell::new(Self { state: 0, delay: 0 }))),
28            draw: ObjFunc(Self::draw),
29            update: ObjFunc(Self::update),
30            name: "FallFloor",
31            solids: false,
32        }
33    }
34    pub fn update(obj: &mut Object, celeste: &mut Celeste) {
35        let tref = match &mut obj.obj_type {
36            ObjectType::FallFloor(p) => p.clone(),
37            _ => unreachable!(),
38        };
39        let mut this = tref.borrow_mut();
40        if this.state == 0 {
41            for i in 0..3 {
42                if obj
43                    .check(celeste, "Player", (i - 1) as f32, -(i % 2) as f32)
44                    .is_some()
45                {
46                    this.break_floor(obj, celeste);
47                }
48            }
49        } else if this.state == 1 {
50            this.delay -= 1;
51            if this.delay <= 0 {
52                this.state = 2;
53                this.delay = 60;
54                obj.collidable = false;
55            }
56        } else if this.state == 2 {
57            this.delay -= 1;
58            if this.delay <= 0 && obj.check(celeste, "Player", 0.0, 0.0).is_none() {
59                // psfx 7
60                this.state = 0;
61                obj.collidable = true;
62                obj.init_smoke(celeste, 0.0, 0.0);
63            }
64        }
65    }
66    pub fn draw(obj: &mut Object, celeste: &mut Celeste) {
67        let tref = match &mut obj.obj_type {
68            ObjectType::FallFloor(p) => p.clone(),
69            _ => unreachable!(),
70        };
71        let this = tref.borrow_mut();
72        celeste.mem.spr(
73            if this.state == 1 {
74                u8::max(25 - this.delay / 5, 23) // i shouldn't need this max(), but i do for some
75                                                 // reason. [TODO]: accuracy
76            } else if this.state == 0 {
77                23
78            } else {
79                0
80            },
81            obj.pos.x as i32,
82            obj.pos.y as i32,
83            None,
84        );
85        // this.state==1 and
86        // 26-this.delay/5 or
87        // this.state==0 and 23
88    }
89    pub fn break_floor(&mut self, obj: &mut Object, celeste: &mut Celeste) {
90        if self.state == 0 {
91            //psfx 15
92            self.state = 1;
93            self.delay = 15;
94            obj.init_smoke(celeste, 0.0, 0.0);
95            let springdex = obj.check(celeste, "Spring", 0.0, -1.0);
96            match springdex {
97                Some(i) => {
98                    let jref = celeste.objects[i].clone();
99                    let mut springobj = jref.borrow_mut();
100                    let pref = match &mut springobj.obj_type {
101                        ObjectType::Spring(p) => p.clone(),
102                        _ => unreachable!(),
103                    };
104                    pref.borrow_mut().hide_in = 15;
105                }
106                None => (),
107            }
108        }
109    }
110}