summaryrefslogtreecommitdiff
path: root/death.ha
diff options
context:
space:
mode:
authorLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:11:21 +0200
committerLassi Pulkkinen <lassi@pulk.fi>2024-10-31 03:51:35 +0200
commitae44478b30d890fe0fb04022f44d474dcdcc3f9d (patch)
tree5f462459ae4b47d22114eed717d1382d08cf4dfe /death.ha
Initial commit (import old repo)HEADmain
Diffstat (limited to 'death.ha')
-rw-r--r--death.ha163
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...]);
+ };
+};