sync enemys deaths even if they are out of range to be culled, fix mid biome shops being stealable sometimes, fix last nagles flush not working

This commit is contained in:
bgkillas 2024-10-12 10:20:54 -04:00
parent 5674263730
commit 803ecbd380
5 changed files with 210 additions and 194 deletions

View file

@ -162,7 +162,7 @@ function inventory_helper.deserialize_single_item(item_data)
ComponentSetValue2(item_cost_component, "stealable", false)
else
local mx, my = GameGetCameraPos()
if math.abs(mx - x) > 1024 or math.abs(my - y) > 1024 then
if (math.abs(mx - x) > 1024 or math.abs(my - y) > 1024) and ComponentGetValue2(item_cost_component, "stealable") then
EntityAddComponent2(item, "VariableStorageComponent", {_tags = "ew_try_stealable"})
ComponentSetValue2(item_cost_component, "stealable", false)
end

View file

@ -44,6 +44,8 @@ local wands = {}
local enemy_sync = {}
local unsynced_enemys = {}
local dead_entities = {}
--this basically never happens, doesn't seem that useful anymore. Perhaps should be removed to conserve memory.
--local confirmed_kills = {}
@ -304,9 +306,9 @@ end
function enemy_sync.client_cleanup()
local entities = get_sync_entities(true)
for i, enemy_id in ipairs(entities) do
for _, enemy_id in ipairs(entities) do
if not EntityHasTag(enemy_id, "ew_replicated") then
local filename = EntityGetFilename(enemy_id)
--local filename = EntityGetFilename(enemy_id)
--print("Despawning unreplicated "..enemy_id.." "..filename)
EntityKill(enemy_id)
elseif not spawned_by_us[enemy_id] then
@ -316,14 +318,13 @@ function enemy_sync.client_cleanup()
else
local cull = EntityGetFirstComponentIncludingDisabled(enemy_id, "VariableStorageComponent", "ew_cull")
if cull ~= nil and ComponentGetValue2(cull, "value_int") + 120 < GameGetFrameNum() then
print("culling "..enemy_id)
EntityKill(enemy_id)
end
end
end
local frame = GameGetFrameNum()
for remote_id, enemy_data in pairs(ctx.entity_by_remote_id) do
if frame - enemy_data.frame > 60*1 then
if frame - enemy_data.frame > 60*2 then
--print("Despawning stale "..remote_id.." "..enemy_data.id)
EntityKill(enemy_data.id)
ctx.entity_by_remote_id[remote_id] = nil
@ -356,96 +357,31 @@ function enemy_sync.on_world_update_client()
end
end
rpc.opts_reliable()
function rpc.handle_death_data(death_data)
for _, remote_data in ipairs(death_data) do
local remote_id = remote_data[1]
--[[if confirmed_kills[remote_id] then
GamePrint("Remote id has been killed already..?")
goto continue
end
confirmed_kills[remote_id] = true]]
local responsible_entity = 0
local peer_data = player_fns.peer_get_player_data(remote_data[2], true)
if peer_data ~= nil then
responsible_entity = peer_data.entity
elseif ctx.entity_by_remote_id[remote_data[2]] ~= nil then
responsible_entity = ctx.entity_by_remote_id[remote_data[2]]
end
local enemy_data = ctx.entity_by_remote_id[remote_id]
if enemy_data ~= nil and EntityGetIsAlive(enemy_data.id) then
local enemy_id = enemy_data.id
local immortal = EntityGetFirstComponentIncludingDisabled(enemy_id, "LuaComponent", "ew_immortal")
if immortal ~= 0 then
EntityRemoveComponent(enemy_id, immortal)
end
local protection_component_id = GameGetGameEffect(enemy_id, "PROTECTION_ALL")
if protection_component_id ~= 0 then
EntitySetComponentIsEnabled(enemy_id, protection_component_id, false)
end
local damage_component = EntityGetFirstComponentIncludingDisabled(enemy_id, "DamageModelComponent")
if damage_component and damage_component ~= 0 then
ComponentSetValue2(damage_component, "wait_for_kill_flag_on_death", false)
end
-- Enable explosion back
local expl_component = EntityGetFirstComponent(enemy_id, "ExplodeOnDamageComponent")
if expl_component ~= nil and expl_component ~= 0 then
ComponentSetValue2(expl_component, "explode_on_death_percent", 1)
end
local current_hp = util.get_ent_health(enemy_id)
local dmg = current_hp
if dmg > 0 then
EntityInflictDamage(enemy_id, dmg+0.1, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity)
end
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
local parent = EntityGetParent(enemy_id)
if parent ~= nil then
EntityKill(parent)
end
EntityKill(enemy_id)
end
if wands[remote_id] ~= nil then
table.remove(wands, remote_id)
end
::continue::
end
end
function rpc.send_wand(peer_id, remote_enemy_id, wand)
if ctx.my_id == peer_id and wand ~= nil then
wands[remote_enemy_id] = wand
end
end
function rpc.request_wand(peer_id, remote_enemy_id)
if ctx.my_id == ctx.host_id then
rpc.send_wand(peer_id, remote_enemy_id, wands[remote_enemy_id])
end
end
function rpc.handle_enemy_data(enemy_data)
for _, enemy_info_raw in ipairs(enemy_data) do
local function sync_enemy(enemy_info_raw, force_no_cull)
local filename = enemy_info_raw[1]
filename = constants.interned_index_to_filename[filename] or filename
local en_data = enemy_info_raw[2]
local dont_cull = enemy_info_raw[9]
local remote_enemy_id = en_data.enemy_id
local my_x, my_y = GameGetCameraPos()
local c_x, c_y = GameGetCameraPos()
local x, y = en_data.x, en_data.y
if not force_no_cull and not dont_cull then
local my_x, my_y = EntityGetTransform(ctx.my_player.entity)
local c_x, c_y = GameGetCameraPos()
local dx, dy = my_x - x, my_y - y
local cdx, cdy = c_x - x, c_y - y
if not dont_cull and dx * dx + dy * dy > DISTANCE_LIMIT * DISTANCE_LIMIT and cdx * cdx + cdy * cdy > DISTANCE_LIMIT * DISTANCE_LIMIT then
if dx * dx + dy * dy > DISTANCE_LIMIT * DISTANCE_LIMIT and cdx * cdx + cdy * cdy > DISTANCE_LIMIT * DISTANCE_LIMIT then
if ctx.entity_by_remote_id[remote_enemy_id] ~= nil then
EntityKill(ctx.entity_by_remote_id[remote_enemy_id])
ctx.entity_by_remote_id[remote_enemy_id] = nil
end
unsynced_enemys[remote_enemy_id] = enemy_info_raw
goto continue
else
unsynced_enemys[remote_enemy_id] = nil
end
else
unsynced_enemys[remote_enemy_id] = nil
end
local vx = 0
local vy = 0
@ -616,6 +552,86 @@ function rpc.handle_enemy_data(enemy_data)
::continue::
end
rpc.opts_reliable()
function rpc.handle_death_data(death_data)
for _, remote_data in ipairs(death_data) do
local remote_id = remote_data[1]
--[[if confirmed_kills[remote_id] then
GamePrint("Remote id has been killed already..?")
goto continue
end
confirmed_kills[remote_id] = true]]
local responsible_entity = 0
local peer_data = player_fns.peer_get_player_data(remote_data[2], true)
if peer_data ~= nil then
responsible_entity = peer_data.entity
elseif ctx.entity_by_remote_id[remote_data[2]] ~= nil then
responsible_entity = ctx.entity_by_remote_id[remote_data[2]]
end
if unsynced_enemys[remote_id] ~= nil then
sync_enemy(unsynced_enemys[remote_id], true)
end
local enemy_data = ctx.entity_by_remote_id[remote_id]
if enemy_data ~= nil and EntityGetIsAlive(enemy_data.id) then
local enemy_id = enemy_data.id
local immortal = EntityGetFirstComponentIncludingDisabled(enemy_id, "LuaComponent", "ew_immortal")
if immortal ~= 0 then
EntityRemoveComponent(enemy_id, immortal)
end
local protection_component_id = GameGetGameEffect(enemy_id, "PROTECTION_ALL")
if protection_component_id ~= 0 then
EntitySetComponentIsEnabled(enemy_id, protection_component_id, false)
end
local damage_component = EntityGetFirstComponentIncludingDisabled(enemy_id, "DamageModelComponent")
if damage_component and damage_component ~= 0 then
ComponentSetValue2(damage_component, "wait_for_kill_flag_on_death", false)
end
-- Enable explosion back
local expl_component = EntityGetFirstComponent(enemy_id, "ExplodeOnDamageComponent")
if expl_component ~= nil and expl_component ~= 0 then
ComponentSetValue2(expl_component, "explode_on_death_percent", 1)
end
local current_hp = util.get_ent_health(enemy_id)
local dmg = current_hp
if dmg > 0 then
EntityInflictDamage(enemy_id, dmg+0.1, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity)
end
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
local parent = EntityGetParent(enemy_id)
if parent ~= nil then
EntityKill(parent)
end
EntityKill(enemy_id)
end
if wands[remote_id] ~= nil then
table.remove(wands, remote_id)
end
::continue::
end
end
function rpc.send_wand(peer_id, remote_enemy_id, wand)
if ctx.my_id == peer_id and wand ~= nil then
wands[remote_enemy_id] = wand
end
end
function rpc.request_wand(peer_id, remote_enemy_id)
if ctx.my_id == ctx.host_id then
rpc.send_wand(peer_id, remote_enemy_id, wands[remote_enemy_id])
end
end
function rpc.handle_enemy_data(enemy_data)
for _, enemy_info_raw in ipairs(enemy_data) do
sync_enemy(enemy_info_raw, false)
end
end
function rpc.handle_enemy_health(enemy_health_data)

View file

@ -49,9 +49,9 @@ local function run_spawn_fn(fn_name, x, y, ...)
ComponentSetValue2(item_cost_component, "stealable", false)
else
local mx, my = GameGetCameraPos()
if math.abs(mx - x) > 1024 or math.abs(my - y) > 1024 then
EntityAddComponent2(eid, "VariableStorageComponent", {_tags = "ew_try_stealable"})
local item_cost_component = EntityGetFirstComponentIncludingDisabled(eid, "ItemCostComponent")
if (math.abs(mx - x) > 1024 or math.abs(my - y) > 1024 ) and ComponentGetValue2(item_cost_component, "stealable") then
EntityAddComponent2(eid, "VariableStorageComponent", {_tags = "ew_try_stealable"})
ComponentSetValue2(item_cost_component, "stealable", false)
end
end

View file

@ -364,7 +364,7 @@ function rpc.item_localize_req(gid)
end
function rpc.update_positions(position_data)
local LIMIT = 256
local LIMIT = 128 * 3
local cx, cy = GameGetCameraPos()
for gid, el in pairs(position_data) do
local x, y = el[1], el[2]

View file

@ -371,7 +371,7 @@ end
function OnWorldPostUpdate() -- This is called every time the game has finished updating the world
util.tpcall(on_world_post_update_inner)
ctx.events = {}
net.proxy_send("flush")
net.proxy_send("flush", "")
end
function register_localizations(translation_file, clear_count)