Host-side damage calculation

This commit is contained in:
IQuant 2024-05-10 22:17:45 +03:00
parent 29e9ed05f8
commit 4aa4c01646
8 changed files with 95 additions and 28 deletions

7
files/cbs/immortal.lua Normal file
View file

@ -0,0 +1,7 @@
function damage_about_to_be_received( damage, x, y, entity_thats_responsible, critical_hit_chance )
if(entity_thats_responsible ~= GameGetWorldStateEntity())then
return 0, 0
end
return damage, 0
end

View file

@ -94,10 +94,11 @@ function enemy_sync.handle_enemy_data(enemy_data)
if ctx.entity_by_remote_id[remote_enemy_id] ~= nil and not EntityGetIsAlive(ctx.entity_by_remote_id[remote_enemy_id].id) then
ctx.entity_by_remote_id[remote_enemy_id] = nil
end
if ctx.entity_by_remote_id[remote_enemy_id] == nil then
local enemy_id = EntityLoad(filename, x, y)
EntityAddTag(enemy_id, "ew_replicated")
EntityAddTag(enemy_id, "ew_replicated")
EntityAddComponent2(enemy_id, "LuaComponent", {script_damage_about_to_be_received = "mods/quant.ew/files/cbs/immortal.lua"})
local ai_component = EntityGetFirstComponentIncludingDisabled(enemy_id, "AnimalAIComponent")
if ai_component ~= 0 then
EntityRemoveComponent(enemy_id, ai_component)

View file

@ -1,6 +1,7 @@
local bitser = dofile_once("mods/quant.ew/files/lib/bitser.lua")
local pollnet = dofile_once("mods/quant.ew/files/lib/pollnet.lua")
local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua")
local util = dofile_once("mods/quant.ew/files/src/util.lua")
local reactor = pollnet.Reactor()
@ -11,13 +12,7 @@ function net.update()
reactor:update()
end
local function string_split( s, splitter )
local words = {};
for word in string.gmatch( s, '([^'..splitter..']+)') do
table.insert( words, word );
end
return words;
end
local string_split = util.string_split
function net.init()
local ready = false
@ -45,7 +40,7 @@ function net.init()
local peer_id = peer_id_l + peer_id_h * 256
local msg_l = string.sub(msg, 4)
local success, item = pcall(bitser.loads, msg_l)
if success then
if success then
msg_decoded = {
kind = "mod",
peer_id = peer_id,
@ -59,16 +54,12 @@ function net.init()
print("Unknown msg")
end
if msg_decoded ~= nil and net_handling[msg_decoded.kind] ~= nil and net_handling[msg_decoded.kind][msg_decoded.key] ~= nil then
if ctx.ready or msg_decoded.kind ~= "mod" then
local result, err = pcall(net_handling[msg_decoded.kind][msg_decoded.key], msg_decoded.peer_id, msg_decoded.value)
if not result then
GamePrint(tostring(err))
end
if ctx.ready or msg_decoded.kind ~= "mod" then
util.tpcall(net_handling[msg_decoded.kind][msg_decoded.key], msg_decoded.peer_id, msg_decoded.value)
end
-- GamePrint("NetHnd: "..msg_decoded.kind.." "..msg_decoded.key)
end
end
end
ready = true
end)
while not ready do
reactor:update()
@ -110,4 +101,8 @@ function net.send_world_data(world_data)
net.send("world", world_data)
end
function net.send_host_player_info(player_info)
net.send("host_player", player_info)
end
return net

View file

@ -1,5 +1,6 @@
local player_fns = dofile_once("mods/quant.ew/files/src/player_fns.lua")
local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua")
local util = dofile_once("mods/quant.ew/files/src/util.lua")
local enemy_sync = dofile_once("mods/quant.ew/files/src/enemy_sync.lua")
local world_sync = dofile_once("mods/quant.ew/files/src/world_sync.lua")
local perk_fns = dofile_once("mods/quant.ew/files/src/perk_fns.lua")
@ -30,8 +31,12 @@ function net_handling.mod.player(peer_id, value)
player_fns.spawn_player_for(peer_id, pos_data.x, pos_data.y)
end
local player_data = player_fns.peer_get_player_data(peer_id)
player_fns.deserialize_inputs(input_data, player_data)
player_fns.deserialize_position(pos_data, player_data)
if input_data ~= nil then
player_fns.deserialize_inputs(input_data, player_data)
end
if pos_data ~= nil then
player_fns.deserialize_position(pos_data, player_data)
end
if slot_data ~= nil then
player_fns.set_current_slot(slot_data, player_data)
end
@ -66,4 +71,16 @@ function net_handling.mod.world(peer_id, world_data)
end
end
function net_handling.mod.host_player(peer_id, player_infos)
if peer_id ~= ctx.host_id then
return
end
for id, player_data in pairs(ctx.players) do
if player_infos[id] ~= nil then
local info = player_infos[id]
util.set_ent_health(player_data.entity, {info[1], info[2]})
end
end
end
return net_handling

View file

@ -396,6 +396,9 @@ function player_fns.spawn_player_for(peer_id, x, y)
local new = EntityLoad("mods/quant.ew/files/entities/client.xml", x, y)
local new_playerdata = player_fns.make_playerdata_for(new, peer_id)
ctx.players[peer_id] = new_playerdata
if not ctx.is_host then
EntityAddComponent2(new, "LuaComponent", {script_damage_about_to_be_received = "mods/quant.ew/files/cbs/immortal.lua"})
end
end
function player_fns.is_inventory_open()

View file

@ -1,8 +1,35 @@
local bitser = dofile_once("mods/quant.ew/files/lib/bitser.lua")
local util = {}
function util.string_split( s, splitter )
local words = {};
for word in string.gmatch( s, '([^'..splitter..']+)') do
table.insert( words, word );
end
return words;
end
function util.print_error(error)
local lines = util.string_split(error, "\n")
for _, line in ipairs(lines) do
GamePrint(line)
end
end
function util.tpcall(fn, ...)
local res = {xpcall(fn, debug.traceback, ...)}
if not res[1] then
util.print_error(res[2])
end
return unpack(res)
end
function util.get_ent_variable(entity, key)
local storage = EntityGetFirstComponentIncludingDisabled(entity, "VariableStorageComponent", key)
if storage == nil then
return nil
end
local value = ComponentGetValue2(storage, "value_string")
if value == "" then
return nil

View file

@ -10,6 +10,7 @@ np.SilenceLogs("Warning - streaming didn\'t find any chunks it could stream away
local player_fns = dofile_once("mods/quant.ew/files/src/player_fns.lua")
local net = dofile_once("mods/quant.ew/files/src/net.lua")
local util = dofile_once("mods/quant.ew/files/src/util.lua")
local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua")
local pretty = dofile_once("mods/quant.ew/files/lib/pretty_print.lua")
local perk_fns = dofile_once("mods/quant.ew/files/src/perk_fns.lua")
@ -84,6 +85,10 @@ function OnPlayerSpawned( player_entity ) -- This runs when player entity has be
np.SetPauseState(4)
np.SetPauseState(0)
if not ctx.is_host then
EntityAddComponent2(player_entity, "LuaComponent", {script_damage_about_to_be_received = "mods/quant.ew/files/cbs/immortal.lua"})
end
dofile_once("data/scripts/perks/perk.lua")
local x, y = EntityGetFirstHitboxCenter(player_entity)
perk_spawn(x, y, "LASER_AIM", true)
@ -91,13 +96,12 @@ function OnPlayerSpawned( player_entity ) -- This runs when player entity has be
end
function OnWorldPreUpdate() -- This is called every time the game is about to start updating the world
local result, err = pcall(on_world_pre_update_inner)
if not result then
GamePrint(tostring(err))
end
util.tpcall(on_world_pre_update_inner)
end
function on_world_pre_update_inner()
if my_player == nil then return end
-- GamePrint( "Pre-update hook " .. tostring(GameGetFrameNum()) )
net.update()
@ -123,13 +127,25 @@ function on_world_pre_update_inner()
end
end
if ctx.is_host and GameGetFrameNum() % 4 == 3 then
local player_info = {}
for id, player_data in pairs(ctx.players) do
local entity = player_data.entity
local hp, max_hp = util.get_ent_health(entity)
player_info[id] = {hp, max_hp}
end
net.send_host_player_info(player_info)
end
if GameGetFrameNum() % 120 == 0 then
-- GamePrint("Serialize items")
local inventory_state = player_fns.serialize_items(my_player)
net.send_player_inventory(inventory_state)
if inventory_state ~= nil then
net.send_player_inventory(inventory_state)
end
local perk_data = perk_fns.get_my_perks()
-- print(pretty.table(perk_data))
net.send_player_perks(perk_data)
if perk_data ~= nil then
net.send_player_perks(perk_data)
end
end
end

View file

@ -4,8 +4,9 @@
- Общее хп
- Синхронизация хп
- Проверка окончания игры
- Удаление лишних клиентов при загрузке игры
- Улучшенная синхронизация снарядов
- Синхронизировать смерти противников
- Удаление лишних клиентов при загрузке игры
- Fix weird no gui mode