diff options
author | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:11:21 +0200 |
---|---|---|
committer | Lassi Pulkkinen <lassi@pulk.fi> | 2024-10-31 03:51:35 +0200 |
commit | ae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch) | |
tree | 5f462459ae4b47d22114eed717d1382d08cf4dfe /death.ha |
Diffstat (limited to 'death.ha')
-rw-r--r-- | death.ha | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/death.ha b/death.ha new file mode 100644 index 0000000..a446a26 --- /dev/null +++ b/death.ha @@ -0,0 +1,163 @@ +use glm; +use mcproto; +use strings; +use time; + +def DEATH_RESPAWN_DELAY = time::SECOND; + +let DEATH_SHOWN = false; +let DEATH_MESSAGE = ""; +let DEATH_SHOWN_SINCE = time::instant { ... }; +let DEATH_CAN_RESPAWN = false; +let DEATH_RESPAWNING = false; + +fn death_show(message: str) void = { + death_close(); + + DEATH_SHOWN = true; + DEATH_MESSAGE = strings::dup(message); + DEATH_SHOWN_SINCE = frame_timestamp(); +}; + +fn death_close() void = { + DEATH_SHOWN = false; + free(DEATH_MESSAGE); + DEATH_MESSAGE = ""; + DEATH_SHOWN_SINCE = time::instant { ... }; + DEATH_CAN_RESPAWN = false; + DEATH_RESPAWNING = false; +}; + +fn death_frame() void = { + if (!DEATH_SHOWN && PLAYER_HEALTH <= 0.0) { + death_show(""); + }; + + if (!DEATH_SHOWN) { + return; + }; + + if (!DEATH_CAN_RESPAWN && !DEATH_RESPAWNING) { + const t = time::diff(DEATH_SHOWN_SINCE, frame_timestamp()); + if (t > DEATH_RESPAWN_DELAY) { + DEATH_CAN_RESPAWN = true; + }; + }; +}; + +fn death_respawn() void = { + DEATH_RESPAWNING = true; + DEATH_CAN_RESPAWN = false; + + let out: []u8 = []; + defer free(out); + mcproto::encode_varint(&out, 0); + network_send(0x06, out); +}; + +const LAYER_DEATH = Layer { + blocks_input = &layer_death_blocks_input, + input = &layer_death_input, + is_opaque = &layer_death_is_opaque, + render = &layer_death_render, +}; + +fn layer_death_blocks_input() bool = { + return DEATH_SHOWN; +}; + +fn layer_death_input(event: InputEvent) bool = { + if (!DEATH_SHOWN) { + return false; + }; + + match (event) { + case let event: KeyEvent => + switch (event.key) { + case KEY_SPACE => + if (event.status == ButtonStatus::DOWN + && DEATH_CAN_RESPAWN) { + death_respawn(); + }; + case => void; + }; + case => void; + }; + + return true; +}; + +fn layer_death_is_opaque() bool = { + return false; +}; + +fn layer_death_render() void = { + if (!DEATH_SHOWN) { + return; + }; + + let (width, height) = drawable_size(); + let gui_width = width / gui_scale(); + let gui_height = height / gui_scale(); + + const font = fonts_find("minecraft:default") as *Font; + + const text = "You died!"; + const metrics = font_measure(font, text); + let text_trans = glm::m4_new_ident(); + glm::translate(&text_trans, &[ + -metrics.width / 2.0, + 0.0, + 0.0]); + glm::scale(&text_trans, &[2.0f32, 2.0, 1.0]); + glm::translate(&text_trans, &[ + gui_width: f32 / 2.0, + 60.0, + 0.0]); + const text_trans = glm::m4_mul(gui_proj(), &text_trans); + render_text_shadow(text, font, &text_trans, [255...]); + + const text = DEATH_MESSAGE; + const metrics = font_measure(font, text); + let text_trans = glm::m4_new_ident(); + glm::translate(&text_trans, &[ + (gui_width: f32 - metrics.width) / 2.0, + 85.0, + 0.0]); + const text_trans = glm::m4_mul(gui_proj(), &text_trans); + render_text_shadow(text, font, &text_trans, [255...]); + + const text = "Score: blah"; + const metrics = font_measure(font, text); + let text_trans = glm::m4_new_ident(); + glm::translate(&text_trans, &[ + (gui_width: f32 - metrics.width) / 2.0, + 100.0, + 0.0]); + const text_trans = glm::m4_mul(gui_proj(), &text_trans); + render_text_shadow(text, font, &text_trans, [255...]); + + if (DEATH_CAN_RESPAWN) { + const text = "Press SPACE to respawn"; + const metrics = font_measure(font, text); + let text_trans = glm::m4_new_ident(); + glm::translate(&text_trans, &[ + (gui_width: f32 - metrics.width) / 2.0, + gui_height: f32 / 4.0 + 72.0, + 0.0]); + const text_trans = glm::m4_mul(gui_proj(), &text_trans); + render_text_shadow(text, font, &text_trans, [255...]); + }; + + if (DEATH_RESPAWNING) { + const text = "Respawning..."; + const metrics = font_measure(font, text); + let text_trans = glm::m4_new_ident(); + glm::translate(&text_trans, &[ + (gui_width: f32 - metrics.width) / 2.0, + gui_height: f32 / 4.0 + 72.0, + 0.0]); + const text_trans = glm::m4_mul(gui_proj(), &text_trans); + render_text_shadow(text, font, &text_trans, [255...]); + }; +}; |