diff --git a/builtin/client/death_formspec.lua b/builtin/client/death_formspec.lua deleted file mode 100644 index c25c799ab..000000000 --- a/builtin/client/death_formspec.lua +++ /dev/null @@ -1,15 +0,0 @@ --- CSM death formspec. Only used when clientside modding is enabled, otherwise --- handled by the engine. - -core.register_on_death(function() - local formspec = "size[11,5.5]bgcolor[#320000b4;true]" .. - "label[4.85,1.35;" .. fgettext("You died") .. - "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]" - core.show_formspec("bultin:death", formspec) -end) - -core.register_on_formspec_input(function(formname, fields) - if formname == "bultin:death" then - core.send_respawn() - end -end) diff --git a/builtin/client/init.lua b/builtin/client/init.lua index 301a8050c..8d01c99a4 100644 --- a/builtin/client/init.lua +++ b/builtin/client/init.lua @@ -9,6 +9,5 @@ dofile(commonpath .. "mod_storage.lua") dofile(commonpath .. "chatcommands.lua") dofile(commonpath .. "information_formspecs.lua") dofile(clientpath .. "chatcommands.lua") -dofile(clientpath .. "death_formspec.lua") dofile(clientpath .. "misc.lua") assert(loadfile(commonpath .. "item_s.lua"))({}) -- Just for push/read node functions diff --git a/builtin/game/death_screen.lua b/builtin/game/death_screen.lua new file mode 100644 index 000000000..77f56aaff --- /dev/null +++ b/builtin/game/death_screen.lua @@ -0,0 +1,31 @@ +local F = core.formspec_escape +local S = core.get_translator("__builtin") + +function core.show_death_screen(player, _reason) + local fs = { + "formspec_version[1]", + "size[11,5.5,true]", + "bgcolor[#320000b4;true]", + "label[4.85,1.35;", F(S("You died")), "]", + "button_exit[4,3;3,0.5;btn_respawn;", F(S("Respawn")), "]", + } + core.show_formspec(player:get_player_name(), "__builtin:death", table.concat(fs, "")) +end + +core.register_on_dieplayer(function(player, reason) + core.show_death_screen(player, reason) +end) + +core.register_on_joinplayer(function(player) + if player:get_hp() == 0 then + core.show_death_screen(player, nil) + end +end) + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname == "__builtin:death" and fields.quit and player:get_hp() == 0 then + player:respawn() + core.log("action", player:get_player_name() .. " respawns at " .. + player:get_pos():to_string()) + end +end) diff --git a/builtin/game/init.lua b/builtin/game/init.lua index 4e16c686d..b3c64e729 100644 --- a/builtin/game/init.lua +++ b/builtin/game/init.lua @@ -38,6 +38,7 @@ dofile(gamepath .. "forceloading.lua") dofile(gamepath .. "hud.lua") dofile(gamepath .. "knockback.lua") dofile(gamepath .. "async.lua") +dofile(gamepath .. "death_screen.lua") core.after(0, builtin_shared.cache_content_ids) diff --git a/builtin/locale/__builtin.be.tr b/builtin/locale/__builtin.be.tr new file mode 100644 index 000000000..bd8ea999e --- /dev/null +++ b/builtin/locale/__builtin.be.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Вы загінулі +Respawn=Адрадзіцца diff --git a/builtin/locale/__builtin.bg.tr b/builtin/locale/__builtin.bg.tr new file mode 100644 index 000000000..43fe8f31e --- /dev/null +++ b/builtin/locale/__builtin.bg.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Умряхте +Respawn=Прераждане diff --git a/builtin/locale/__builtin.ca.tr b/builtin/locale/__builtin.ca.tr new file mode 100644 index 000000000..5cde155f9 --- /dev/null +++ b/builtin/locale/__builtin.ca.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Has mort +Respawn=Reaparèixer diff --git a/builtin/locale/__builtin.cs.tr b/builtin/locale/__builtin.cs.tr new file mode 100644 index 000000000..4f4b592e4 --- /dev/null +++ b/builtin/locale/__builtin.cs.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Zemřel jsi +Respawn=Oživit diff --git a/builtin/locale/__builtin.cy.tr b/builtin/locale/__builtin.cy.tr new file mode 100644 index 000000000..372da1a89 --- /dev/null +++ b/builtin/locale/__builtin.cy.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Buest ti farw +Respawn=Atgyfodi diff --git a/builtin/locale/__builtin.da.tr b/builtin/locale/__builtin.da.tr new file mode 100644 index 000000000..c34eceeb9 --- /dev/null +++ b/builtin/locale/__builtin.da.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Du døde +Respawn=Genopstå diff --git a/builtin/locale/__builtin.de.tr b/builtin/locale/__builtin.de.tr index 0552ef88b..3665a3f54 100644 --- a/builtin/locale/__builtin.de.tr +++ b/builtin/locale/__builtin.de.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Es wurden insgesamt @1 Datenpunkt(e) aufgeze The output is limited to '@1'.=Die Ausgabe ist beschränkt auf „@1“. Saving of profile failed: @1=Speichern des Profils fehlgeschlagen: @1 Profile saved to @1=Profil abgespeichert nach @1 +You died=Sie sind gestorben +Respawn=Wiederbeleben diff --git a/builtin/locale/__builtin.el.tr b/builtin/locale/__builtin.el.tr new file mode 100644 index 000000000..c14180a62 --- /dev/null +++ b/builtin/locale/__builtin.el.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Πέθανες +Respawn=Επανεμφάνηση diff --git a/builtin/locale/__builtin.eo.tr b/builtin/locale/__builtin.eo.tr index c3fec6c37..f1fe5333b 100644 --- a/builtin/locale/__builtin.eo.tr +++ b/builtin/locale/__builtin.eo.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Sume @1 ekzemplero(j) konserviĝis. The output is limited to '@1'.=La eligo estas limigita al «@1». Saving of profile failed: @1=Konservado de profilo malsukcesis: @1 Profile saved to @1=Profilo konservita al @1 +You died=Vi mortis +Respawn=Renaskiĝi diff --git a/builtin/locale/__builtin.es.tr b/builtin/locale/__builtin.es.tr new file mode 100644 index 000000000..3c4a66933 --- /dev/null +++ b/builtin/locale/__builtin.es.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Has muerto +Respawn=Reaparecer diff --git a/builtin/locale/__builtin.et.tr b/builtin/locale/__builtin.et.tr new file mode 100644 index 000000000..e0745c24a --- /dev/null +++ b/builtin/locale/__builtin.et.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Said surma +Respawn=Ärka ellu diff --git a/builtin/locale/__builtin.eu.tr b/builtin/locale/__builtin.eu.tr new file mode 100644 index 000000000..77f510855 --- /dev/null +++ b/builtin/locale/__builtin.eu.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Hil zara +Respawn=Birsortu diff --git a/builtin/locale/__builtin.fi.tr b/builtin/locale/__builtin.fi.tr new file mode 100644 index 000000000..f7c0ee038 --- /dev/null +++ b/builtin/locale/__builtin.fi.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Kuolit +Respawn=Synny uudelleen diff --git a/builtin/locale/__builtin.fil.tr b/builtin/locale/__builtin.fil.tr new file mode 100644 index 000000000..0755234a1 --- /dev/null +++ b/builtin/locale/__builtin.fil.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Namatay ka +Respawn=Mag-respawn diff --git a/builtin/locale/__builtin.fr.tr b/builtin/locale/__builtin.fr.tr index 6c3a244dc..d36574afd 100644 --- a/builtin/locale/__builtin.fr.tr +++ b/builtin/locale/__builtin.fr.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=@1 échantillons ont été collectés. The output is limited to '@1'.=La sortie est limitée à '@1'. Saving of profile failed: @1=La sauvegarde du profil a échoué : @1 Profile saved to @1=Le profil a été sauvegardé dans @1 +You died=Vous êtes mort +Respawn=Réapparaître diff --git a/builtin/locale/__builtin.ga.tr b/builtin/locale/__builtin.ga.tr new file mode 100644 index 000000000..e19959b10 --- /dev/null +++ b/builtin/locale/__builtin.ga.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Fuair tú bás +Respawn=Athsceith diff --git a/builtin/locale/__builtin.gl.tr b/builtin/locale/__builtin.gl.tr new file mode 100644 index 000000000..7f692f633 --- /dev/null +++ b/builtin/locale/__builtin.gl.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Morreches +Respawn=Reaparecer diff --git a/builtin/locale/__builtin.hu.tr b/builtin/locale/__builtin.hu.tr new file mode 100644 index 000000000..d7eebf7a0 --- /dev/null +++ b/builtin/locale/__builtin.hu.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Meghaltál +Respawn=Újraéledés diff --git a/builtin/locale/__builtin.id.tr b/builtin/locale/__builtin.id.tr index a541b0f8c..a7eba8c1c 100644 --- a/builtin/locale/__builtin.id.tr +++ b/builtin/locale/__builtin.id.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Total @1 sampel yang diambil. The output is limited to '@1'.=Keluaran dibatasi ke '@1'. Saving of profile failed: @1=Penyimpanan profil gagal: @1 Profile saved to @1=Profil disimpan ke @1 +You died=Anda mati +Respawn=Bangkit kembali diff --git a/builtin/locale/__builtin.it.tr b/builtin/locale/__builtin.it.tr index aecb80a9a..24cf38104 100644 --- a/builtin/locale/__builtin.it.tr +++ b/builtin/locale/__builtin.it.tr @@ -245,3 +245,5 @@ A total of @1 sample(s) were taken.=Son stati ottenuti campioni per un totale di The output is limited to '@1'.=L'output è limitato a '@1'. Saving of profile failed: @1=Errore nel salvare il profilo: @1 Profile saved to @1=Profilo salvato in @1 +You died=Sei morto +Respawn=Rinasci diff --git a/builtin/locale/__builtin.ja.tr b/builtin/locale/__builtin.ja.tr new file mode 100644 index 000000000..1138edddd --- /dev/null +++ b/builtin/locale/__builtin.ja.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=死んでしまった +Respawn=リスポーン diff --git a/builtin/locale/__builtin.jbo.tr b/builtin/locale/__builtin.jbo.tr new file mode 100644 index 000000000..fe492bcdb --- /dev/null +++ b/builtin/locale/__builtin.jbo.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=.i do morsi +Respawn=tolcanci diff --git a/builtin/locale/__builtin.jv.tr b/builtin/locale/__builtin.jv.tr new file mode 100644 index 000000000..282cc5476 --- /dev/null +++ b/builtin/locale/__builtin.jv.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Panjenengan pejah +Respawn=Bangkit Malilh diff --git a/builtin/locale/__builtin.ko.tr b/builtin/locale/__builtin.ko.tr new file mode 100644 index 000000000..0d5d35a90 --- /dev/null +++ b/builtin/locale/__builtin.ko.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=사망했습니다 +Respawn=리스폰 diff --git a/builtin/locale/__builtin.kv.tr b/builtin/locale/__builtin.kv.tr new file mode 100644 index 000000000..f985d2ac4 --- /dev/null +++ b/builtin/locale/__builtin.kv.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Кулінныд +Respawn=Ловзьыны diff --git a/builtin/locale/__builtin.ky.tr b/builtin/locale/__builtin.ky.tr new file mode 100644 index 000000000..9ad468aa0 --- /dev/null +++ b/builtin/locale/__builtin.ky.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Сиз өлдүңүз. +Respawn=Кайтадан жаралуу diff --git a/builtin/locale/__builtin.lt.tr b/builtin/locale/__builtin.lt.tr new file mode 100644 index 000000000..cc613162c --- /dev/null +++ b/builtin/locale/__builtin.lt.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Jūs numirėte +Respawn=Prisikelti diff --git a/builtin/locale/__builtin.lv.tr b/builtin/locale/__builtin.lv.tr new file mode 100644 index 000000000..1da1fe3d8 --- /dev/null +++ b/builtin/locale/__builtin.lv.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Jūs nomirāt +Respawn=Atdzīvoties diff --git a/builtin/locale/__builtin.lzh.tr b/builtin/locale/__builtin.lzh.tr new file mode 100644 index 000000000..1af6aba98 --- /dev/null +++ b/builtin/locale/__builtin.lzh.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=尔死矣 +Respawn=复生 diff --git a/builtin/locale/__builtin.mn.tr b/builtin/locale/__builtin.mn.tr new file mode 100644 index 000000000..dd9a3465b --- /dev/null +++ b/builtin/locale/__builtin.mn.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Та үхсэн +Respawn=Дахин төрөх diff --git a/builtin/locale/__builtin.mr.tr b/builtin/locale/__builtin.mr.tr new file mode 100644 index 000000000..e4fcfb9b1 --- /dev/null +++ b/builtin/locale/__builtin.mr.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=तू मेलास +Respawn=पुनर्जन्म diff --git a/builtin/locale/__builtin.ms.tr b/builtin/locale/__builtin.ms.tr index ebf794e97..65ac557bf 100644 --- a/builtin/locale/__builtin.ms.tr +++ b/builtin/locale/__builtin.ms.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Sebanyak @1 sampel telah diambil secara kese The output is limited to '@1'.=Output dihadkan kepada '@1'. Saving of profile failed: @1=Penyimpanan profil telah gagal: @1 Profile saved to @1=Profil telah disimpan ke @1 +You died=Anda telah meninggal +Respawn=Jelma semula diff --git a/builtin/locale/__builtin.nb.tr b/builtin/locale/__builtin.nb.tr new file mode 100644 index 000000000..b02a2d282 --- /dev/null +++ b/builtin/locale/__builtin.nb.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Du døde +Respawn=Gjenoppstå diff --git a/builtin/locale/__builtin.nl.tr b/builtin/locale/__builtin.nl.tr new file mode 100644 index 000000000..bd23c04b0 --- /dev/null +++ b/builtin/locale/__builtin.nl.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Je bent gestorven +Respawn=Herboren worden diff --git a/builtin/locale/__builtin.nn.tr b/builtin/locale/__builtin.nn.tr new file mode 100644 index 000000000..240191f73 --- /dev/null +++ b/builtin/locale/__builtin.nn.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Du døydde +Respawn=Kom opp att diff --git a/builtin/locale/__builtin.oc.tr b/builtin/locale/__builtin.oc.tr new file mode 100644 index 000000000..34b6577ad --- /dev/null +++ b/builtin/locale/__builtin.oc.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Setz mòrt·a +Respawn=Tornar diff --git a/builtin/locale/__builtin.pl.tr b/builtin/locale/__builtin.pl.tr new file mode 100644 index 000000000..ec0a9b7c1 --- /dev/null +++ b/builtin/locale/__builtin.pl.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Nie żyjesz +Respawn=Wróć do gry diff --git a/builtin/locale/__builtin.pt.tr b/builtin/locale/__builtin.pt.tr new file mode 100644 index 000000000..fbdb461e5 --- /dev/null +++ b/builtin/locale/__builtin.pt.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Você morreu +Respawn=Renascer diff --git a/builtin/locale/__builtin.pt_BR.tr b/builtin/locale/__builtin.pt_BR.tr index e12e9fae8..e48425bda 100644 --- a/builtin/locale/__builtin.pt_BR.tr +++ b/builtin/locale/__builtin.pt_BR.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Um total de @1 amostra(s) foi coletada. The output is limited to '@1'.=A saída é limitada a '@1'. Saving of profile failed: @1=Falha ao salvar o perfil: @1 Profile saved to @1=Perfil salvo em @1 +You died=Você morreu +Respawn=Reviver diff --git a/builtin/locale/__builtin.ro.tr b/builtin/locale/__builtin.ro.tr new file mode 100644 index 000000000..7ff5e3c38 --- /dev/null +++ b/builtin/locale/__builtin.ro.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Ai murit +Respawn=Reînviere diff --git a/builtin/locale/__builtin.ru.tr b/builtin/locale/__builtin.ru.tr index d43fbc589..863cdd638 100644 --- a/builtin/locale/__builtin.ru.tr +++ b/builtin/locale/__builtin.ru.tr @@ -244,3 +244,5 @@ A total of @1 sample(s) were taken.=Всего было взято @1 образ The output is limited to '@1'.=Вывод ограничен значением '@1'. Saving of profile failed: @1=Не удалось сохранить данные профилирования: @1 Profile saved to @1=Данные профилирования сохранены в @1 +You died=Вы умерли +Respawn=Возродиться diff --git a/builtin/locale/__builtin.sk.tr b/builtin/locale/__builtin.sk.tr new file mode 100644 index 000000000..e9e93f6a3 --- /dev/null +++ b/builtin/locale/__builtin.sk.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Zomrel si +Respawn=Oživiť diff --git a/builtin/locale/__builtin.sl.tr b/builtin/locale/__builtin.sl.tr new file mode 100644 index 000000000..6dc77c3b2 --- /dev/null +++ b/builtin/locale/__builtin.sl.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Umrl si +Respawn=Ponovno oživi diff --git a/builtin/locale/__builtin.sr_Cyrl.tr b/builtin/locale/__builtin.sr_Cyrl.tr new file mode 100644 index 000000000..68551e77a --- /dev/null +++ b/builtin/locale/__builtin.sr_Cyrl.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Умро си +Respawn=Врати се у живот diff --git a/builtin/locale/__builtin.sr_Latn.tr b/builtin/locale/__builtin.sr_Latn.tr new file mode 100644 index 000000000..4adc496b4 --- /dev/null +++ b/builtin/locale/__builtin.sr_Latn.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Umro/la si. +Respawn=Vrati se u zivot diff --git a/builtin/locale/__builtin.sv.tr b/builtin/locale/__builtin.sv.tr new file mode 100644 index 000000000..115014506 --- /dev/null +++ b/builtin/locale/__builtin.sv.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Du dog +Respawn=Återuppstå diff --git a/builtin/locale/__builtin.sw.tr b/builtin/locale/__builtin.sw.tr new file mode 100644 index 000000000..92aa1f3e1 --- /dev/null +++ b/builtin/locale/__builtin.sw.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Umekufa. +Respawn=Respawn diff --git a/builtin/locale/__builtin.tok.tr b/builtin/locale/__builtin.tok.tr new file mode 100644 index 000000000..14d131d6a --- /dev/null +++ b/builtin/locale/__builtin.tok.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=sina moli +Respawn=o kama sin diff --git a/builtin/locale/__builtin.tr.tr b/builtin/locale/__builtin.tr.tr new file mode 100644 index 000000000..dafec5630 --- /dev/null +++ b/builtin/locale/__builtin.tr.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Öldün +Respawn=Yeniden Canlan diff --git a/builtin/locale/__builtin.tt.tr b/builtin/locale/__builtin.tt.tr new file mode 100644 index 000000000..a162cd9b7 --- /dev/null +++ b/builtin/locale/__builtin.tt.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Сез үлдегез +Respawn=Тергезелергә diff --git a/builtin/locale/__builtin.uk.tr b/builtin/locale/__builtin.uk.tr new file mode 100644 index 000000000..e82a10bde --- /dev/null +++ b/builtin/locale/__builtin.uk.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Ви загинули +Respawn=Відродитися diff --git a/builtin/locale/__builtin.vi.tr b/builtin/locale/__builtin.vi.tr new file mode 100644 index 000000000..53caac93c --- /dev/null +++ b/builtin/locale/__builtin.vi.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=Bạn đã bị chết +Respawn=Hồi sinh diff --git a/builtin/locale/__builtin.zh_CN.tr b/builtin/locale/__builtin.zh_CN.tr new file mode 100644 index 000000000..5b1077429 --- /dev/null +++ b/builtin/locale/__builtin.zh_CN.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=您已死亡 +Respawn=重生 diff --git a/builtin/locale/__builtin.zh_TW.tr b/builtin/locale/__builtin.zh_TW.tr new file mode 100644 index 000000000..5b1077429 --- /dev/null +++ b/builtin/locale/__builtin.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: __builtin +You died=您已死亡 +Respawn=重生 diff --git a/doc/client_lua_api.md b/doc/client_lua_api.md index 08d0317ab..cd651f1b3 100644 --- a/doc/client_lua_api.md +++ b/doc/client_lua_api.md @@ -338,8 +338,6 @@ Call these functions only at load time! is checked to see if the command exists, but after the input is parsed. * Return `true` to mark the command as handled, which means that the default handlers will be prevented. -* `minetest.register_on_death(function())` - * Called when the local player dies * `minetest.register_on_hp_modification(function(hp))` * Called when server modified player's HP * `minetest.register_on_damage_taken(function(hp))` @@ -487,8 +485,6 @@ Call these functions only at load time! * Returns `false` if the client is already disconnecting otherwise returns `true`. * `minetest.get_server_info()` * Returns [server info](#server-info). -* `minetest.send_respawn()` - * Sends a respawn request to the server. ### Storage API * `minetest.get_mod_storage()`: diff --git a/doc/lua_api.md b/doc/lua_api.md index 3a5f7e128..66a83542e 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -5869,6 +5869,7 @@ Call these functions only at load time! * `minetest.register_on_dieplayer(function(ObjectRef, reason))` * Called when a player dies * `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange + * For customizing the death screen, see `minetest.show_death_screen`. * `minetest.register_on_respawnplayer(function(ObjectRef))` * Called when player is to be respawned * Called _before_ repositioning of player occurs @@ -6573,6 +6574,13 @@ Formspec * `"INV"`: something failed * `"CHG"`: has been changed * `"VAL"`: not changed +* `minetest.show_death_screen(player, reason)` + * Called when the death screen should be shown. + * `player` is an ObjectRef, `reason` is a PlayerHPChangeReason table or nil. + * By default, this shows a simple formspec with the option to respawn. + Respawning is done via `ObjectRef:respawn`. + * You can override this to show a custom death screen. + * For general death handling, use `minetest.register_on_dieplayer` instead. Item handling ------------- diff --git a/src/client/client.cpp b/src/client/client.cpp index b14ef7004..1a2f51db9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1359,9 +1359,9 @@ void Client::sendDamage(u16 damage) Send(&pkt); } -void Client::sendRespawn() +void Client::sendRespawnLegacy() { - NetworkPacket pkt(TOSERVER_RESPAWN, 0); + NetworkPacket pkt(TOSERVER_RESPAWN_LEGACY, 0); Send(&pkt); } diff --git a/src/client/client.h b/src/client/client.h index adbe7a70d..f9f77ede4 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -194,7 +194,7 @@ public: void handleCommand_Breath(NetworkPacket* pkt); void handleCommand_MovePlayer(NetworkPacket* pkt); void handleCommand_MovePlayerRel(NetworkPacket* pkt); - void handleCommand_DeathScreen(NetworkPacket* pkt); + void handleCommand_DeathScreenLegacy(NetworkPacket* pkt); void handleCommand_AnnounceMedia(NetworkPacket* pkt); void handleCommand_Media(NetworkPacket* pkt); void handleCommand_NodeDef(NetworkPacket* pkt); @@ -249,7 +249,7 @@ public: void sendChangePassword(const std::string &oldpassword, const std::string &newpassword); void sendDamage(u16 damage); - void sendRespawn(); + void sendRespawnLegacy(); void sendReady(); void sendHaveMedia(const std::vector &tokens); void sendUpdateClientInfo(const ClientDynamicInfo &info); diff --git a/src/client/clientevent.h b/src/client/clientevent.h index acd375a4e..8c505786b 100644 --- a/src/client/clientevent.h +++ b/src/client/clientevent.h @@ -35,7 +35,7 @@ enum ClientEventType : u8 CE_NONE, CE_PLAYER_DAMAGE, CE_PLAYER_FORCE_MOVE, - CE_DEATHSCREEN, + CE_DEATHSCREEN_LEGACY, CE_SHOW_FORMSPEC, CE_SHOW_LOCAL_FORMSPEC, CE_SPAWN_PARTICLE, @@ -96,13 +96,6 @@ struct ClientEvent f32 yaw; } player_force_move; struct - { - bool set_camera_point_target; - f32 camera_point_target_x; - f32 camera_point_target_y; - f32 camera_point_target_z; - } deathscreen; - struct { std::string *formspec; std::string *formname; diff --git a/src/client/game.cpp b/src/client/game.cpp index ed593abba..6cbf54f5a 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -186,7 +186,7 @@ struct LocalFormspecHandler : public TextDest assert(m_client != nullptr); if (fields.find("quit") != fields.end()) - m_client->sendRespawn(); + m_client->sendRespawnLegacy(); return; } @@ -837,7 +837,7 @@ private: bool disable_camera_update = false; }; - void showDeathFormspec(); + void showDeathFormspecLegacy(); void showPauseMenu(); void pauseAnimation(); @@ -847,7 +847,7 @@ private: void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam); - void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam); + void handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_HandleParticleEvent(ClientEvent *event, @@ -2854,7 +2854,7 @@ const ClientEventHandler Game::clientEventHandler[CLIENTEVENT_MAX] = { {&Game::handleClientEvent_None}, {&Game::handleClientEvent_PlayerDamage}, {&Game::handleClientEvent_PlayerForceMove}, - {&Game::handleClientEvent_Deathscreen}, + {&Game::handleClientEvent_DeathscreenLegacy}, {&Game::handleClientEvent_ShowFormSpec}, {&Game::handleClientEvent_ShowLocalFormSpec}, {&Game::handleClientEvent_HandleParticleEvent}, @@ -2910,20 +2910,9 @@ void Game::handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientati cam->camera_pitch = event->player_force_move.pitch; } -void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam) +void Game::handleClientEvent_DeathscreenLegacy(ClientEvent *event, CameraOrientation *cam) { - // If client scripting is enabled, deathscreen is handled by CSM code in - // builtin/client/init.lua - if (client->modsLoaded()) - client->getScript()->on_death(); - else - showDeathFormspec(); - - /* Handle visualization */ - LocalPlayer *player = client->getEnv().getLocalPlayer(); - runData.damage_flash = 0; - player->hurt_tilt_timer = 0; - player->hurt_tilt_strength = 0; + showDeathFormspecLegacy(); } void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam) @@ -4468,7 +4457,7 @@ void Game::readSettings() ****************************************************************************/ /****************************************************************************/ -void Game::showDeathFormspec() +void Game::showDeathFormspecLegacy() { static std::string formspec_str = std::string("formspec_version[1]") + diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index d426d3fe7..7d0840754 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -81,7 +81,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_MOVE_PLAYER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MovePlayer }, // 0x34 { "TOCLIENT_ACCESS_DENIED_LEGACY", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied }, // 0x35 { "TOCLIENT_FOV", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Fov }, // 0x36 - { "TOCLIENT_DEATHSCREEN", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeathScreen }, // 0x37 + { "TOCLIENT_DEATHSCREEN_LEGACY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeathScreenLegacy }, // 0x37 { "TOCLIENT_MEDIA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Media }, // 0x38 null_command_handler, { "TOCLIENT_NODEDEF", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_NodeDef }, // 0x3a @@ -198,7 +198,7 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = { "TOSERVER_DAMAGE", 0, true }, // 0x35 null_command_factory, // 0x36 { "TOSERVER_PLAYERITEM", 0, true }, // 0x37 - { "TOSERVER_RESPAWN", 0, true }, // 0x38 + { "TOSERVER_RESPAWN_LEGACY", 0, true }, // 0x38 { "TOSERVER_INTERACT", 0, true }, // 0x39 { "TOSERVER_REMOVED_SOUNDS", 2, true }, // 0x3a { "TOSERVER_NODEMETA_FIELDS", 0, true }, // 0x3b diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 5b7c2f527..2716879f4 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -653,20 +653,10 @@ void Client::handleCommand_MovePlayerRel(NetworkPacket *pkt) player->addPosition(added_pos); } -void Client::handleCommand_DeathScreen(NetworkPacket* pkt) +void Client::handleCommand_DeathScreenLegacy(NetworkPacket* pkt) { - bool set_camera_point_target; - v3f camera_point_target; - - *pkt >> set_camera_point_target; - *pkt >> camera_point_target; - ClientEvent *event = new ClientEvent(); - event->type = CE_DEATHSCREEN; - event->deathscreen.set_camera_point_target = set_camera_point_target; - event->deathscreen.camera_point_target_x = camera_point_target.X; - event->deathscreen.camera_point_target_y = camera_point_target.Y; - event->deathscreen.camera_point_target_z = camera_point_target.Z; + event->type = CE_DEATHSCREEN_LEGACY; m_client_event_queue.push(event); } diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 85931c71b..cae2a3291 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -231,6 +231,12 @@ with this program; if not, write to the Free Software Foundation, Inc., Move default hotbar from client-side C++ to server-side builtin Lua Add shadow tint to Lighting packets Add shadow color to CloudParam packets + Move death screen to server and make it a regular formspec + The server no longer triggers the hardcoded client-side death + formspec, but the client still supports it for compatibility with + old servers. + Rename TOCLIENT_DEATHSCREEN to TOCLIENT_DEATHSCREEN_LEGACY + Rename TOSERVER_RESPAWN to TOSERVER_RESPAWN_LEGACY [scheduled bump for 5.10.0] */ @@ -391,10 +397,10 @@ enum ToClientCommand : u16 f32 transition_time */ - TOCLIENT_DEATHSCREEN = 0x37, + TOCLIENT_DEATHSCREEN_LEGACY = 0x37, /* - u8 bool set camera point target - v3f1000 camera point target (to point the death cause or whatever) + u8 bool unused + v3f1000 unused */ TOCLIENT_MEDIA = 0x38, @@ -1002,10 +1008,7 @@ enum ToServerCommand : u16 [2] u16 item */ - TOSERVER_RESPAWN = 0x38, - /* - u16 TOSERVER_RESPAWN - */ + TOSERVER_RESPAWN_LEGACY = 0x38, TOSERVER_INTERACT = 0x39, /* diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index 1cb413492..4b87c3fbe 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -82,7 +82,7 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = { "TOSERVER_DAMAGE", TOSERVER_STATE_INGAME, &Server::handleCommand_Damage }, // 0x35 null_command_handler, // 0x36 { "TOSERVER_PLAYERITEM", TOSERVER_STATE_INGAME, &Server::handleCommand_PlayerItem }, // 0x37 - { "TOSERVER_RESPAWN", TOSERVER_STATE_INGAME, &Server::handleCommand_Respawn }, // 0x38 + null_command_handler, // 0x38 { "TOSERVER_INTERACT", TOSERVER_STATE_INGAME, &Server::handleCommand_Interact }, // 0x39 { "TOSERVER_REMOVED_SOUNDS", TOSERVER_STATE_INGAME, &Server::handleCommand_RemovedSounds }, // 0x3a { "TOSERVER_NODEMETA_FIELDS", TOSERVER_STATE_INGAME, &Server::handleCommand_NodeMetaFields }, // 0x3b @@ -181,7 +181,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_MOVE_PLAYER", 0, true }, // 0x34 null_command_factory, // 0x35 { "TOCLIENT_FOV", 0, true }, // 0x36 - { "TOCLIENT_DEATHSCREEN", 0, true }, // 0x37 + null_command_factory, // 0x37 { "TOCLIENT_MEDIA", 2, true }, // 0x38 null_command_factory, // 0x39 { "TOCLIENT_NODEDEF", 0, true }, // 0x3A diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 7d8555c8e..c17d32e41 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -858,33 +858,6 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt) playersao->getPlayer()->setWieldIndex(item); } -void Server::handleCommand_Respawn(NetworkPacket* pkt) -{ - session_t peer_id = pkt->getPeerId(); - RemotePlayer *player = m_env->getPlayer(peer_id); - if (player == NULL) { - errorstream << - "Server::ProcessData(): Canceling: No player for peer_id=" << - peer_id << " disconnecting peer!" << std::endl; - DisconnectPeer(peer_id); - return; - } - - PlayerSAO *playersao = player->getPlayerSAO(); - assert(playersao); - - if (!playersao->isDead()) - return; - - RespawnPlayer(peer_id); - - actionstream << player->getName() << " respawns at " - << (playersao->getBasePosition() / BS) << std::endl; - - // ActiveObject is added to environment in AsyncRunStep after - // the previous addition has been successfully removed -} - bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what) { ItemStack selected_item, hand_item; diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 6faa0695c..78d0ec44d 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -125,21 +125,6 @@ void ScriptApiClient::on_hp_modification(int32_t newhp) } } -void ScriptApiClient::on_death() -{ - SCRIPTAPI_PRECHECKHEADER - - // Get registered shutdown hooks - lua_getglobal(L, "core"); - lua_getfield(L, -1, "registered_on_death"); - // Call callbacks - try { - runCallbacks(0, RUN_CALLBACKS_MODE_FIRST); - } catch (LuaError &e) { - getClient()->setFatalError(e); - } -} - void ScriptApiClient::environment_step(float dtime) { SCRIPTAPI_PRECHECKHEADER diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 8a5523d0d..74cc0d898 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -49,7 +49,6 @@ public: void on_damage_taken(int32_t damage_amount); void on_hp_modification(int32_t newhp); - void on_death(); void environment_step(float dtime); void on_formspec_input(const std::string &formname, const StringMap &fields); diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index da19ed0ea..3bd9fc04d 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -157,13 +157,6 @@ int ModApiClient::l_show_formspec(lua_State *L) return 1; } -// send_respawn() -int ModApiClient::l_send_respawn(lua_State *L) -{ - getClient(L)->sendRespawn(); - return 0; -} - // disconnect() int ModApiClient::l_disconnect(lua_State *L) { @@ -348,7 +341,6 @@ void ModApiClient::Initialize(lua_State *L, int top) API_FCT(clear_out_chat_queue); API_FCT(get_player_names); API_FCT(show_formspec); - API_FCT(send_respawn); API_FCT(gettext); API_FCT(get_node_or_nil); API_FCT(disconnect); diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h index e960dc4cf..d726bc8a3 100644 --- a/src/script/lua_api/l_client.h +++ b/src/script/lua_api/l_client.h @@ -51,9 +51,6 @@ private: // show_formspec(name, formspec) static int l_show_formspec(lua_State *L); - // send_respawn() - static int l_send_respawn(lua_State *L); - // disconnect() static int l_disconnect(lua_State *L); diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index d6d608aab..ebd1bde71 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -2693,11 +2693,11 @@ int ObjectRef::l_respawn(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkObject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == nullptr) + auto *psao = getplayersao(ref); + if (psao == nullptr) return 0; - getServer(L)->RespawnPlayer(player->getPeerId()); + psao->respawn(); lua_pushboolean(L, true); return 1; } diff --git a/src/server.cpp b/src/server.cpp index 4be3aa26a..fe3dc8516 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1159,10 +1159,6 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id) // Send HP SendPlayerHP(playersao, false); - // Send death screen - if (playersao->isDead()) - SendDeathscreen(peer_id, false, v3f(0,0,0)); - // Send Breath SendPlayerBreath(playersao); @@ -1405,14 +1401,6 @@ void Server::SendAccessDenied(session_t peer_id, AccessDeniedCode reason, Send(&pkt); } -void Server::SendDeathscreen(session_t peer_id, bool set_camera_point_target, - v3f camera_point_target) -{ - NetworkPacket pkt(TOCLIENT_DEATHSCREEN, 1 + sizeof(v3f), peer_id); - pkt << set_camera_point_target << camera_point_target; - Send(&pkt); -} - void Server::SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version) { @@ -2803,32 +2791,8 @@ void Server::HandlePlayerDeath(PlayerSAO *playersao, const PlayerHPChangeReason // Trigger scripted stuff m_script->on_dieplayer(playersao, reason); - - SendDeathscreen(playersao->getPeerID(), false, v3f(0,0,0)); } -void Server::RespawnPlayer(session_t peer_id) -{ - PlayerSAO *playersao = getPlayerSAO(peer_id); - assert(playersao); - - infostream << "Server::RespawnPlayer(): Player " - << playersao->getPlayer()->getName() - << " respawns" << std::endl; - - const auto *prop = playersao->accessObjectProperties(); - playersao->setHP(prop->hp_max, - PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN)); - playersao->setBreath(prop->breath_max); - - bool repositioned = m_script->on_respawnplayer(playersao); - if (!repositioned) { - // setPos will send the new position to client - playersao->setPos(findSpawnPos()); - } -} - - void Server::DenySudoAccess(session_t peer_id) { NetworkPacket pkt(TOCLIENT_DENY_SUDO_MODE, 0, peer_id); diff --git a/src/server.h b/src/server.h index 58805c667..5f6086cde 100644 --- a/src/server.h +++ b/src/server.h @@ -193,7 +193,6 @@ public: void handleCommand_ChatMessage(NetworkPacket* pkt); void handleCommand_Damage(NetworkPacket* pkt); void handleCommand_PlayerItem(NetworkPacket* pkt); - void handleCommand_Respawn(NetworkPacket* pkt); void handleCommand_Interact(NetworkPacket* pkt); void handleCommand_RemovedSounds(NetworkPacket* pkt); void handleCommand_NodeMetaFields(NetworkPacket* pkt); @@ -356,8 +355,6 @@ public: void setLighting(RemotePlayer *player, const Lighting &lighting); - void RespawnPlayer(session_t peer_id); - /* con::PeerHandler implementation. */ void peerAdded(con::IPeer *peer); void deletingPeer(con::IPeer *peer, bool timeout); @@ -486,8 +483,6 @@ private: void SendBreath(session_t peer_id, u16 breath); void SendAccessDenied(session_t peer_id, AccessDeniedCode reason, std::string_view custom_reason, bool reconnect = false); - void SendDeathscreen(session_t peer_id, bool set_camera_point_target, - v3f camera_point_target); void SendItemDef(session_t peer_id, IItemDefManager *itemdef, u16 protocol_version); void SendNodeDef(session_t peer_id, const NodeDefManager *nodedef, u16 protocol_version); diff --git a/src/server/clientiface.h b/src/server/clientiface.h index f930e7f3e..3f5ba6434 100644 --- a/src/server/clientiface.h +++ b/src/server/clientiface.h @@ -126,7 +126,7 @@ class EmergeManager; | TOCLIENT_INVENTORY | | | | | TOCLIENT_HP (opt) | \-----------------/ | | TOCLIENT_BREATH | | -| TOCLIENT_DEATHSCREEN | | +| TOCLIENT_DEATHSCREEN_LEGACY | | +-----------------------------+ | | | v | diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 11922b2c6..30c41bb1e 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -558,6 +558,21 @@ void PlayerSAO::setBreath(const u16 breath, bool send) m_env->getGameDef()->SendPlayerBreath(this); } +void PlayerSAO::respawn() +{ + infostream << "PlayerSAO::respawn(): Player " << m_player->getName() + << " respawns" << std::endl; + + setHP(m_prop.hp_max, PlayerHPChangeReason(PlayerHPChangeReason::RESPAWN)); + setBreath(m_prop.breath_max); + + bool repositioned = m_env->getScriptIface()->on_respawnplayer(this); + if (!repositioned) { + // setPos will send the new position to client + setPos(m_env->getGameDef()->findSpawnPos()); + } +} + Inventory *PlayerSAO::getInventory() const { return m_player ? &m_player->inventory : nullptr; diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 95bd1d109..487e37957 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -124,6 +124,7 @@ public: void setHPRaw(u16 hp) { m_hp = hp; } u16 getBreath() const { return m_breath; } void setBreath(const u16 breath, bool send = true); + void respawn(); /* Inventory interface