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...]); }; };