Handle death while polymorphed (by ending the run)

This commit is contained in:
IQuant 2024-06-16 16:07:09 +03:00
parent ef5ee79f1b
commit a8fc1d6027
8 changed files with 66 additions and 43 deletions

View file

@ -14,6 +14,7 @@ Functions:
- `set_health(hp: num)`
- `set_max_health(hp: num)`
- `inflict_damage(dmg: num)`
- `do_game_over(msg: str)`
Provided by:
- damage (shared health) system

View file

@ -394,7 +394,7 @@ function player_fns.peer_has_player(peer_id)
end
function player_fns.peer_get_player_data(peer_id, dont_spawn_new)
if (not dont_spawn_new) and (not player_fns.peer_has_player(peer_id)) then
if peer_id ~= ctx.my_player.peer_id and (not dont_spawn_new) and (not player_fns.peer_has_player(peer_id)) then
player_fns.spawn_player_for(peer_id, ctx.initial_player_pos.x, ctx.initial_player_pos.y)
end
return ctx.players[peer_id]
@ -405,6 +405,9 @@ function player_fns.get_player_data_by_local_entity_id(entity)
end
function player_fns.spawn_player_for(peer_id, x, y, existing_playerdata)
if ctx.run_ended then
util.print_traceback()
end
GamePrint("Spawning player for "..peer_id)
local new = EntityLoad("mods/quant.ew/files/entities/client.xml", x, y)
local new_playerdata = existing_playerdata or player_fns.make_playerdata_for(new, peer_id)

View file

@ -2,6 +2,10 @@ local adjust_damage = dofile_once("mods/quant.ew/files/src/system/damage/cbs/adj
-- Called on clients when they get damage and redirects it to the host's hp over the network, ignoring any resists.
function damage_received(damage, message, entity_thats_responsible, is_fatal, projectile_thats_responsible)
if entity_thats_responsible == GameGetWorldStateEntity() then
return
end
local dtypes = GetDamageDetails().damage_types
local new_damage = adjust_damage(damage, dtypes)

View file

@ -2,6 +2,10 @@ local adjust_damage = dofile_once("mods/quant.ew/files/src/system/damage/cbs/adj
-- Called on clients when they get damage and redirects it to the host's hp over the network, ignoring any resists.
function damage_received(damage, message, entity_thats_responsible, is_fatal, projectile_thats_responsible)
if entity_thats_responsible == GameGetWorldStateEntity() then
return
end
-- Change our health back
local entity_id = GetUpdatedEntityID();
local damageModelComponent = EntityGetFirstComponentIncludingDisabled( entity_id, "DamageModelComponent" )

View file

@ -13,6 +13,7 @@ local module = {}
module.recent_damage = 0
module.recent_message = "unknown"
module.last_damage_message = "unknown"
np.CrossCallAdd("ew_ds_damaged", function (damage, message)
module.recent_damage = module.recent_damage + damage
@ -20,8 +21,20 @@ np.CrossCallAdd("ew_ds_damaged", function (damage, message)
if ctx.is_host then
module.inflict_damage(damage)
end
module.last_damage_message = GameTextGetTranslatedOrNot(message) .. " from "..ctx.my_player.name
end)
local function do_game_over(message)
net.proxy_notify_game_over()
ctx.run_ended = true
local damage_model = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "DamageModelComponent")
ComponentSetValue2(damage_model, "wait_for_kill_flag_on_death", false)
EntityInflictDamage(ctx.my_player.entity, 1000000, "DAMAGE_CURSE", message, "NONE", 0, 0, GameGetWorldStateEntity())
GameTriggerGameOver()
EntityKill(ctx.my_player.entity)
end
function module.on_local_player_spawn(my_player)
if ctx.is_host then
EntityAddComponent2(my_player.entity, "LuaComponent", {script_damage_received = "mods/quant.ew/files/src/system/damage/cbs/host_adjust_received_damage.lua"})
@ -37,9 +50,11 @@ end
function module.on_world_update_client()
if module.recent_damage ~= 0 and GameGetFrameNum() % 15 == 2 then
rpc.deal_damage(module.recent_damage, module.recent_message)
module.recent_damage = 0
module.recent_message = "unknown"
if not ctx.run_ended then
rpc.deal_damage(module.recent_damage, module.recent_message)
module.recent_damage = 0
module.recent_message = "unknown"
end
end
end
@ -50,11 +65,10 @@ function module.on_world_update_host()
util.set_ent_health(ctx.my_player.entity, {hp, max_hp})
end
rpc.update_shared_health(hp, max_hp)
if hp <= 0 then
GameTriggerGameOver()
ctx.run_ended = true
net.proxy_notify_game_over()
rpc.trigger_game_over()
if hp <= 0 and not ctx.run_ended then
local message = module.last_damage_message
do_game_over(message)
rpc.trigger_game_over(message)
end
end
end
@ -91,19 +105,20 @@ ctx.cap.health = {
set_health = module.set_health,
set_max_health = module.set_max_health,
inflict_damage = module.inflict_damage,
do_game_over = function(message) do_game_over(message) rpc.trigger_game_over(message) end
}
rpc.opts_reliable()
function rpc.deal_damage(damage, message)
local message = GameTextGetTranslatedOrNot(message) .. " from "..ctx.rpc_player_data.name
module.last_damage_message = message
if ctx.is_host then
-- local entity_thats_responsible = ctx.rpc_player_data.entity
local host_entity_id = ctx.my_player.entity
local protection_component_id = GameGetGameEffect(host_entity_id, "PROTECTION_ALL")
if protection_component_id ~= 0 then
EntitySetComponentIsEnabled(host_entity_id, protection_component_id, false)
end
-- EntityInflictDamage(host_entity_id, damage, "DAMAGE_CURSE", message, "NONE", 0, 0, nil)
module.inflict_damage(damage)
if protection_component_id ~= 0 then
EntitySetComponentIsEnabled(host_entity_id, protection_component_id, true)
@ -118,10 +133,8 @@ function rpc.update_shared_health(hp, max_hp)
end
end
function rpc.trigger_game_over()
GameTriggerGameOver()
net.proxy_notify_game_over()
ctx.run_ended = true
function rpc.trigger_game_over(message)
do_game_over(message)
end
return module

View file

@ -13,6 +13,8 @@ local function entity_changed()
ctx.my_player.currently_polymorphed = currently_polymorphed
if currently_polymorphed then
local damage_model = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "DamageModelComponent")
ComponentSetValue2(damage_model, "wait_for_kill_flag_on_death", true)
rpc.change_entity(np.SerializeEntity(ctx.my_player.entity))
else
rpc.change_entity(nil)
@ -39,7 +41,17 @@ local function remove_all_effects(entity)
end
end
local gameover_requested = false
function module.on_world_update()
if ctx.my_player.currently_polymorphed then
local hp = util.get_ent_health(ctx.my_player.entity)
if hp <= 0 and not gameover_requested then
ctx.cap.health.do_game_over()
gameover_requested = true
end
end
end
function module.on_world_update_post()
local ent = np.GetPlayerEntity()

View file

@ -28,6 +28,10 @@ function util.tpcall(fn, ...)
return unpack(res)
end
function util.print_traceback()
util.print_error(debug.traceback())
end
function util.get_ent_variable(entity, key)
local storage = EntityGetFirstComponentIncludingDisabled(entity, "VariableStorageComponent", key)
if storage == nil then

View file

@ -184,19 +184,6 @@ local function on_world_pre_update_inner()
ctx.is_inventory_open = inventory_open
end
-- if not ctx.is_host then
-- local hp, _ = util.get_ent_health(ctx.my_player.entity)
-- if hp == 0 then
-- EntityInflictDamage(ctx.my_player.entity, 10000000, "DAMAGE_CURSE", "Out of shared health", "NONE", 0, 0, GameGetWorldStateEntity())
-- GameTriggerGameOver()
-- if not ctx.run_ended then
-- GamePrint("Notifying of run end")
-- net.proxy_notify_game_over()
-- ctx.run_ended = true
-- end
-- end
-- end
if GameGetFrameNum() % 120 == 0 then
player_fns.respawn_if_necessary()
player_fns.spread_max_health()
@ -228,12 +215,14 @@ local function on_world_pre_update_inner()
end
end
if ctx.is_host then
ctx.hook.on_world_update_host()
else
ctx.hook.on_world_update_client()
if not ctx.run_ended then
if ctx.is_host then
ctx.hook.on_world_update_host()
else
ctx.hook.on_world_update_client()
end
ctx.hook.on_world_update()
end
ctx.hook.on_world_update()
end
function OnWorldPreUpdate() -- This is called every time the game is about to start updating the world
@ -245,7 +234,9 @@ local function on_world_post_update_inner()
-- local px, py = EntityGetTransform(my_player.entity)
-- GameSetCameraPos(px, py)
ctx.hook.on_world_update_post()
if not ctx.run_ended then
ctx.hook.on_world_update_post()
end
local times_wand_fired = tonumber(GlobalsGetValue("ew_wand_fired", "0"))
GlobalsSetValue("ew_wand_fired", "0")
@ -256,15 +247,6 @@ local function on_world_post_update_inner()
net.send_fire(fire_data)
end
end
if ctx.is_host and not EntityGetIsAlive(ctx.my_player.entity) then
GamePrint("My player is not alive "..ctx.my_player.entity)
if not ctx.run_ended then
GamePrint("Notifying of run end")
net.proxy_notify_game_over()
ctx.run_ended = true
end
end
end
function OnWorldPostUpdate() -- This is called every time the game has finished updating the world