2024-05-26 01:00:37 +03:00
|
|
|
-- This module allows to handle getting damaged locally and redirects that damage to host.
|
2024-06-16 01:09:05 +03:00
|
|
|
-- Also handles shared health system in general.
|
|
|
|
-- Also recalculates percentage-based damage.
|
2024-05-26 01:00:37 +03:00
|
|
|
|
2024-08-07 17:11:55 +03:00
|
|
|
local ctx = dofile_once("mods/quant.ew/files/core/ctx.lua")
|
|
|
|
local net = dofile_once("mods/quant.ew/files/core/net.lua")
|
|
|
|
local util = dofile_once("mods/quant.ew/files/core/util.lua")
|
2024-05-26 00:49:53 +03:00
|
|
|
local np = require("noitapatcher")
|
|
|
|
|
|
|
|
local rpc = net.new_rpc_namespace()
|
|
|
|
|
|
|
|
local module = {}
|
|
|
|
|
|
|
|
module.recent_damage = 0
|
|
|
|
module.recent_message = "unknown"
|
2024-06-16 16:07:09 +03:00
|
|
|
module.last_damage_message = "unknown"
|
2024-05-26 00:49:53 +03:00
|
|
|
|
2024-08-07 17:11:55 +03:00
|
|
|
ModLuaFileAppend("data/scripts/game_helpers.lua", "mods/quant.ew/files/system/damage/append/game_helpers.lua")
|
|
|
|
ModTextFileSetContent("data/entities/misc/effect_hearty.xml", ModTextFileGetContent("mods/quant.ew/files/system/damage/append/hearty_effect.xml"))
|
2024-06-19 17:44:22 +03:00
|
|
|
|
2024-06-19 21:20:06 +03:00
|
|
|
local function damage_received(damage, message, entity_id, add_healing_effect)
|
2024-06-19 17:44:22 +03:00
|
|
|
local was_my_player = entity_id == nil or ctx.my_player.entity == entity_id
|
|
|
|
if not was_my_player then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-05-26 00:49:53 +03:00
|
|
|
module.recent_damage = module.recent_damage + damage
|
2024-06-23 11:14:53 +03:00
|
|
|
if message ~= nil then
|
|
|
|
module.recent_message = message
|
|
|
|
module.last_damage_message = GameTextGetTranslatedOrNot(message) .. " from "..ctx.my_player.name
|
|
|
|
end
|
2024-06-16 13:13:59 +03:00
|
|
|
if ctx.is_host then
|
|
|
|
module.inflict_damage(damage)
|
|
|
|
end
|
2024-06-19 21:20:06 +03:00
|
|
|
if add_healing_effect then
|
|
|
|
rpc.healing_effect()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
np.CrossCallAdd("ew_ds_damaged", damage_received)
|
2024-05-26 00:49:53 +03:00
|
|
|
|
2024-06-16 16:07:09 +03:00
|
|
|
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
|
|
|
|
|
2024-05-26 00:49:53 +03:00
|
|
|
function module.on_local_player_spawn(my_player)
|
2024-06-16 14:31:52 +03:00
|
|
|
local damage_model = EntityGetFirstComponentIncludingDisabled(my_player.entity, "DamageModelComponent")
|
2024-07-23 15:30:42 +03:00
|
|
|
if ctx.is_host then
|
|
|
|
util.ensure_component_present(my_player.entity, "LuaComponent", "ew_player_damage", {
|
2024-08-07 17:11:55 +03:00
|
|
|
script_damage_received = "mods/quant.ew/files/system/damage/cbs/host_adjust_received_damage.lua"
|
2024-07-23 15:30:42 +03:00
|
|
|
})
|
|
|
|
else
|
|
|
|
util.ensure_component_present(my_player.entity, "LuaComponent", "ew_player_damage", {
|
2024-08-07 17:11:55 +03:00
|
|
|
script_damage_received = "mods/quant.ew/files/system/damage/cbs/send_damage_to_host.lua"
|
2024-07-23 15:30:42 +03:00
|
|
|
})
|
2024-07-23 13:37:24 +03:00
|
|
|
end
|
2024-06-16 14:31:52 +03:00
|
|
|
ComponentSetValue2(damage_model, "wait_for_kill_flag_on_death", true)
|
|
|
|
|
2024-05-26 00:49:53 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
function module.on_world_update_client()
|
|
|
|
if module.recent_damage ~= 0 and GameGetFrameNum() % 15 == 2 then
|
2024-06-16 16:07:09 +03:00
|
|
|
if not ctx.run_ended then
|
|
|
|
rpc.deal_damage(module.recent_damage, module.recent_message)
|
|
|
|
module.recent_damage = 0
|
|
|
|
module.recent_message = "unknown"
|
|
|
|
end
|
2024-05-26 00:49:53 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-23 10:47:22 +03:00
|
|
|
local last_health = nil
|
|
|
|
|
|
|
|
local function do_health_diff(hp, max_hp)
|
|
|
|
local current_hp = util.get_ent_health(ctx.my_player.entity)
|
|
|
|
util.set_ent_health(ctx.my_player.entity, {hp, max_hp})
|
|
|
|
if last_health ~= nil then
|
|
|
|
local diff = last_health - current_hp
|
|
|
|
if diff ~= 0 then
|
2024-06-23 11:14:53 +03:00
|
|
|
damage_received(diff, nil)
|
2024-06-23 10:47:22 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
last_health = util.get_ent_health(ctx.my_player.entity)
|
|
|
|
end
|
|
|
|
|
2024-06-16 01:09:05 +03:00
|
|
|
function module.on_world_update_host()
|
|
|
|
if GameGetFrameNum() % 4 == 3 then
|
2024-06-16 13:13:59 +03:00
|
|
|
local hp, max_hp = module.health(), module.max_health()
|
|
|
|
if not ctx.my_player.currently_polymorphed then
|
2024-06-23 10:47:22 +03:00
|
|
|
do_health_diff(hp, max_hp)
|
2024-06-16 13:13:59 +03:00
|
|
|
end
|
2024-06-16 01:09:05 +03:00
|
|
|
rpc.update_shared_health(hp, max_hp)
|
2024-06-16 16:07:09 +03:00
|
|
|
if hp <= 0 and not ctx.run_ended then
|
|
|
|
local message = module.last_damage_message
|
|
|
|
do_game_over(message)
|
|
|
|
rpc.trigger_game_over(message)
|
2024-06-16 14:31:52 +03:00
|
|
|
end
|
2024-06-16 01:09:05 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-07-18 16:39:03 +03:00
|
|
|
function module.on_new_player_seen(new_playerdata, player_count)
|
2024-06-29 18:19:08 +03:00
|
|
|
local hp = 4
|
2024-07-18 16:39:03 +03:00
|
|
|
if player_count > 4 then
|
|
|
|
hp = 1
|
|
|
|
end
|
2024-06-29 18:19:08 +03:00
|
|
|
module.set_max_health(module.max_health()+hp)
|
|
|
|
module.set_health(module.health()+hp)
|
2024-06-16 13:13:59 +03:00
|
|
|
end
|
|
|
|
|
2024-07-23 13:37:24 +03:00
|
|
|
function module.on_client_spawned(peer_id, playerdata)
|
|
|
|
if ctx.is_host then
|
2024-08-07 17:11:55 +03:00
|
|
|
EntityAddComponent2(playerdata.entity, "LuaComponent", {script_damage_received = "mods/quant.ew/files/system/damage/cbs/send_damage_to_client.lua"})
|
2024-07-23 13:37:24 +03:00
|
|
|
else
|
2024-08-07 17:21:25 +03:00
|
|
|
EntityAddComponent2(playerdata.entity, "LuaComponent", {script_damage_about_to_be_received = "mods/quant.ew/files/resource/cbs/immortal.lua"})
|
2024-07-23 13:37:24 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-16 13:13:59 +03:00
|
|
|
function module.health()
|
|
|
|
return tonumber(GlobalsGetValue("ew_shared_hp", "4"))
|
|
|
|
end
|
|
|
|
|
|
|
|
function module.max_health()
|
|
|
|
return tonumber(GlobalsGetValue("ew_shared_max_hp", "4"))
|
|
|
|
end
|
|
|
|
|
|
|
|
function module.set_health(hp)
|
|
|
|
GlobalsSetValue("ew_shared_hp", tostring(hp))
|
|
|
|
end
|
|
|
|
|
|
|
|
function module.set_max_health(hp)
|
|
|
|
GlobalsSetValue("ew_shared_max_hp", tostring(hp))
|
|
|
|
end
|
|
|
|
|
|
|
|
function module.inflict_damage(dmg)
|
|
|
|
local hp = module.health()
|
|
|
|
module.set_health(math.min(math.max(hp-dmg, 0), module.max_health()))
|
|
|
|
end
|
|
|
|
|
2024-06-23 10:47:22 +03:00
|
|
|
-- Provides health capability
|
2024-06-16 14:31:52 +03:00
|
|
|
ctx.cap.health = {
|
|
|
|
health = module.health,
|
|
|
|
max_health = module.max_health,
|
|
|
|
set_health = module.set_health,
|
|
|
|
set_max_health = module.set_max_health,
|
|
|
|
inflict_damage = module.inflict_damage,
|
2024-08-07 15:05:38 +03:00
|
|
|
do_game_over = function(message) do_game_over(message) rpc.trigger_game_over(message) end,
|
|
|
|
on_poly_death = function(message) do_game_over(message) rpc.trigger_game_over(message) end,
|
2024-06-16 14:31:52 +03:00
|
|
|
}
|
|
|
|
|
2024-05-26 00:49:53 +03:00
|
|
|
rpc.opts_reliable()
|
|
|
|
function rpc.deal_damage(damage, message)
|
2024-06-23 11:05:25 +03:00
|
|
|
local message = GameTextGetTranslatedOrNot(message) .. " ("..ctx.rpc_player_data.name..")"
|
2024-06-16 16:07:09 +03:00
|
|
|
module.last_damage_message = message
|
2024-05-26 00:49:53 +03:00
|
|
|
if ctx.is_host then
|
|
|
|
local host_entity_id = ctx.my_player.entity
|
|
|
|
local protection_component_id = GameGetGameEffect(host_entity_id, "PROTECTION_ALL")
|
2024-06-01 17:27:35 +03:00
|
|
|
if protection_component_id ~= 0 then
|
2024-05-26 00:49:53 +03:00
|
|
|
EntitySetComponentIsEnabled(host_entity_id, protection_component_id, false)
|
|
|
|
end
|
2024-06-16 16:07:09 +03:00
|
|
|
|
2024-06-16 13:13:59 +03:00
|
|
|
module.inflict_damage(damage)
|
2024-06-01 17:27:35 +03:00
|
|
|
if protection_component_id ~= 0 then
|
2024-05-26 00:49:53 +03:00
|
|
|
EntitySetComponentIsEnabled(host_entity_id, protection_component_id, true)
|
|
|
|
end
|
|
|
|
end
|
2024-07-23 13:37:24 +03:00
|
|
|
GamePrint(string.format("Got %.2f damage: %s", damage*25, message))
|
2024-05-26 00:49:53 +03:00
|
|
|
end
|
|
|
|
|
2024-06-19 22:28:14 +03:00
|
|
|
function rpc.update_shared_health(hp, max_hp)
|
|
|
|
if not ctx.my_player.currently_polymorphed then
|
2024-06-23 10:47:22 +03:00
|
|
|
do_health_diff(hp, max_hp)
|
2024-06-19 22:26:41 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-06-19 21:20:06 +03:00
|
|
|
rpc.opts_reliable()
|
2024-06-16 16:07:09 +03:00
|
|
|
function rpc.trigger_game_over(message)
|
|
|
|
do_game_over(message)
|
2024-06-16 14:31:52 +03:00
|
|
|
end
|
|
|
|
|
2024-06-19 21:20:06 +03:00
|
|
|
function rpc.healing_effect()
|
|
|
|
local entity_id = ctx.rpc_player_data.entity
|
|
|
|
local x, y = EntityGetTransform( entity_id )
|
|
|
|
local entity_fx = EntityLoad( "data/entities/particles/heal_effect.xml", x, y )
|
|
|
|
EntityAddChild( entity_id, entity_fx )
|
|
|
|
end
|
|
|
|
|
2024-07-03 00:00:44 +03:00
|
|
|
rpc.opts_reliable()
|
|
|
|
rpc.opts_everywhere()
|
|
|
|
function rpc.effect_hearty(applied)
|
|
|
|
if not ctx.is_host then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local hearty_applied_count = tonumber(GlobalsGetValue("ew_effect_hearty", "0"))
|
|
|
|
if applied then
|
|
|
|
-- The effect was added
|
|
|
|
if module.max_health() <= 0.4 then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
module.set_health(math.max(module.health() * 0.5, 0.04))
|
|
|
|
module.set_max_health(module.max_health() * 0.5)
|
|
|
|
hearty_applied_count = hearty_applied_count + 1
|
|
|
|
else
|
|
|
|
-- The effect was removed
|
|
|
|
if hearty_applied_count <= 0 then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
module.set_max_health(module.max_health() * 2)
|
|
|
|
module.set_health(module.health() * 2)
|
|
|
|
hearty_applied_count = hearty_applied_count - 1
|
|
|
|
end
|
|
|
|
GlobalsSetValue("ew_effect_hearty", tostring(hearty_applied_count))
|
|
|
|
end
|
|
|
|
|
|
|
|
np.CrossCallAdd("ew_ds_effect_hearty", rpc.effect_hearty)
|
|
|
|
|
2024-07-23 13:37:24 +03:00
|
|
|
rpc.opts_reliable()
|
|
|
|
function rpc.melee_damage_client(target_peer, damage, message)
|
|
|
|
if ctx.my_player.peer_id == target_peer then
|
|
|
|
EntityInflictDamage(ctx.my_player.entity, damage, "DAMAGE_MELEE", message, "NONE", 0, 0, 0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
np.CrossCallAdd("ew_ds_client_damaged", rpc.melee_damage_client)
|
|
|
|
|
2024-06-16 01:09:05 +03:00
|
|
|
return module
|