mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
fix most of item sync, fix some theoretical minor bugs in inventory sync/enemy sync
This commit is contained in:
parent
b8e16e1f1f
commit
a60a1f7aff
3 changed files with 93 additions and 71 deletions
|
@ -49,6 +49,8 @@ local HpData = util.make_type({
|
||||||
f32 = {"hp", "max_hp"}
|
f32 = {"hp", "max_hp"}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local wait_1_frame = false
|
||||||
|
|
||||||
local FULL_TURN = math.pi * 2
|
local FULL_TURN = math.pi * 2
|
||||||
|
|
||||||
local frame = 0
|
local frame = 0
|
||||||
|
@ -358,12 +360,22 @@ function enemy_sync.on_world_update_host()
|
||||||
end
|
end
|
||||||
|
|
||||||
function enemy_sync.on_world_update_client()
|
function enemy_sync.on_world_update_client()
|
||||||
if GameGetFrameNum() % 10 == 1 then
|
if GameGetFrameNum() % 12 == 1 then
|
||||||
enemy_sync.client_cleanup()
|
if wait_1_frame then
|
||||||
|
async(function()
|
||||||
|
wait(1)
|
||||||
|
enemy_sync.client_cleanup()
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
enemy_sync.client_cleanup()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if GameGetFrameNum() % (60*60) == 1 then
|
if GameGetFrameNum() % (60*60) == 1 then
|
||||||
times_spawned_last_minute = {}
|
times_spawned_last_minute = {}
|
||||||
end
|
end
|
||||||
|
if wait_1_frame then
|
||||||
|
wait_1_frame = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function sync_enemy(enemy_info_raw, force_no_cull)
|
local function sync_enemy(enemy_info_raw, force_no_cull)
|
||||||
|
@ -676,6 +688,7 @@ function rpc.handle_enemy_data(enemy_data)
|
||||||
for _, enemy_info_raw in ipairs(enemy_data) do
|
for _, enemy_info_raw in ipairs(enemy_data) do
|
||||||
sync_enemy(enemy_info_raw, false)
|
sync_enemy(enemy_info_raw, false)
|
||||||
end
|
end
|
||||||
|
wait_1_frame = true
|
||||||
end
|
end
|
||||||
|
|
||||||
function rpc.handle_enemy_health(enemy_health_data)
|
function rpc.handle_enemy_health(enemy_health_data)
|
||||||
|
|
|
@ -18,6 +18,10 @@ local pickup_handlers = {}
|
||||||
|
|
||||||
local dead_entities = {}
|
local dead_entities = {}
|
||||||
|
|
||||||
|
local frame = {}
|
||||||
|
|
||||||
|
local gid_last_frame_updated = {}
|
||||||
|
|
||||||
function rpc.open_chest(gid)
|
function rpc.open_chest(gid)
|
||||||
local ent = item_sync.find_by_gid(gid)
|
local ent = item_sync.find_by_gid(gid)
|
||||||
if ent ~= nil then
|
if ent ~= nil then
|
||||||
|
@ -87,25 +91,7 @@ end
|
||||||
|
|
||||||
-- Try to guess if the item is in world.
|
-- Try to guess if the item is in world.
|
||||||
local function is_item_on_ground(item)
|
local function is_item_on_ground(item)
|
||||||
local has_physics = EntityGetComponent(item, "SimplePhysicsComponent") ~= nil or EntityGetComponent(item, "PhysicsBodyComponent") ~= nil
|
return EntityGetRootEntity(item) == item
|
||||||
if has_physics then
|
|
||||||
-- Has at least one of phys components enabled, definitely in world.
|
|
||||||
return true, "has physics"
|
|
||||||
end
|
|
||||||
-- What if it's a new wand?
|
|
||||||
local spec = EntityGetFirstComponent(item, "SpriteParticleEmitterComponent")
|
|
||||||
if spec == nil then
|
|
||||||
-- All disabled, certainly not in world.
|
|
||||||
return false, "no spec component"
|
|
||||||
end
|
|
||||||
-- Ones in starter wands don't have any tags, ukko rock and co do.
|
|
||||||
if ComponentHasTag(spec, "enabled_in_hand") then
|
|
||||||
return false, "spec tags enabled_in_hand"
|
|
||||||
end
|
|
||||||
if ComponentHasTag(spec, "enabled_in_inventory") then
|
|
||||||
return false, "spec tags enabled_in_inventory"
|
|
||||||
end
|
|
||||||
return true, "other "..spec
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function item_sync.get_global_item_id(item)
|
function item_sync.get_global_item_id(item)
|
||||||
|
@ -144,19 +130,14 @@ function item_sync.find_by_gid(gid)
|
||||||
end
|
end
|
||||||
|
|
||||||
function item_sync.remove_item_with_id_now(gid)
|
function item_sync.remove_item_with_id_now(gid)
|
||||||
local global_items = EntityGetWithTag("ew_global_item")
|
local item = item_sync.find_by_gid(gid)
|
||||||
for _, item in ipairs(global_items) do
|
if item ~= nil and is_item_on_ground(item) then
|
||||||
local i_gid = item_sync.get_global_item_id(item)
|
for _, audio in ipairs(EntityGetComponent(item, "AudioComponent") or {}) do
|
||||||
if i_gid == gid then
|
if string.sub(ComponentGetValue2(audio, "event_root"), 1, 10) == "collision/" then
|
||||||
--TODO properly note when actually was from a peer picking up a potion maybe
|
EntitySetComponentIsEnabled(item, audio, false)
|
||||||
for _, audio in ipairs(EntityGetComponent(item, "AudioComponent") or {}) do
|
|
||||||
if string.sub(ComponentGetValue2(audio, "event_root"), 1, 10) == "collision/" then
|
|
||||||
EntitySetComponentIsEnabled(item, audio, false)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
EntityKill(item)
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
|
EntityKill(item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -229,10 +210,6 @@ function item_sync.make_item_global(item, instant, give_authority_to)
|
||||||
|
|
||||||
if give_authority_to ~= nil then
|
if give_authority_to ~= nil then
|
||||||
local itemcom = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent")
|
local itemcom = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent")
|
||||||
if ComponentGetValue2(itemcom, "play_hover_animation") then
|
|
||||||
ComponentSetValue2(itemcom, "play_hover_animation", false)
|
|
||||||
ComponentSetValue2(itemcom, "play_spinning_animation", false)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
ctx.item_prevent_localize[gid] = false
|
ctx.item_prevent_localize[gid] = false
|
||||||
|
@ -312,35 +289,43 @@ function rpc.handle_death_data(death_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
|
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
|
||||||
EntityKill(enemy_id)
|
async(function()
|
||||||
|
wait(1)
|
||||||
|
EntityKill(enemy_id)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
::continue::
|
::continue::
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function send_item_positions()
|
local DISTANCE_LIMIT = 128 * 4
|
||||||
|
|
||||||
|
local function send_item_positions(all)
|
||||||
local position_data = {}
|
local position_data = {}
|
||||||
for _, item in ipairs(EntityGetWithTag("ew_global_item")) do
|
for _, item in ipairs(EntityGetWithTag("ew_global_item")) do
|
||||||
local gid = item_sync.get_global_item_id(item)
|
local gid = item_sync.get_global_item_id(item)
|
||||||
-- Only send info about items created by us.
|
-- Only send info about items created by us.
|
||||||
if is_my_item(gid) and is_item_on_ground(item) then
|
if is_my_item(gid) and is_item_on_ground(item) then
|
||||||
local x, y, r = EntityGetTransform(item)
|
|
||||||
local costcom = EntityGetFirstComponentIncludingDisabled(item, "ItemCostComponent")
|
|
||||||
local cost = 0
|
|
||||||
if costcom ~= nil then
|
|
||||||
cost = ComponentGetValue2(costcom, "cost")
|
|
||||||
local mx, my = GameGetCameraPos()
|
|
||||||
if math.abs(mx - x) < 1024 and math.abs(my - y) < 1024 and EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_try_stealable") then
|
|
||||||
ComponentSetValue2(costcom, "stealable", true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local phys_info = util.get_phys_info(item, true)
|
local phys_info = util.get_phys_info(item, true)
|
||||||
if phys_info ~= nil then
|
local x, y = EntityGetTransform(item)
|
||||||
position_data[gid] = {x, y, r, phys_info, cost}
|
if (phys_info[1][1] ~= nil or phys_info[2][1] ~= nil or all)
|
||||||
|
and (#EntityGetInRadiusWithTag(x, y, DISTANCE_LIMIT, "ew_peer") ~= 0
|
||||||
|
or #EntityGetInRadiusWithTag(x, y, DISTANCE_LIMIT, "polymorphed_player") ~= 0) then
|
||||||
|
local costcom = EntityGetFirstComponentIncludingDisabled(item, "ItemCostComponent")
|
||||||
|
local cost = 0
|
||||||
|
if costcom ~= nil then
|
||||||
|
cost = ComponentGetValue2(costcom, "cost")
|
||||||
|
local mx, my = GameGetCameraPos()
|
||||||
|
if math.abs(mx - x) < 1024 and math.abs(my - y) < 1024
|
||||||
|
and EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_try_stealable") then
|
||||||
|
ComponentSetValue2(costcom, "stealable", true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
position_data[gid] = {x, y, phys_info, cost}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
rpc.update_positions(position_data)
|
rpc.update_positions(position_data, all)
|
||||||
if #dead_entities > 0 then
|
if #dead_entities > 0 then
|
||||||
rpc.handle_death_data(dead_entities)
|
rpc.handle_death_data(dead_entities)
|
||||||
end
|
end
|
||||||
|
@ -396,17 +381,23 @@ function item_sync.on_world_update()
|
||||||
item_sync.remove_item_with_id_now(gid)
|
item_sync.remove_item_with_id_now(gid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if GameGetFrameNum() % 5 == 2 then
|
if GameGetFrameNum() % 60 == 35 then
|
||||||
for _, ent in ipairs(EntityGetWithTag("mimic_potion")) do
|
for _, ent in ipairs(EntityGetWithTag("mimic_potion")) do
|
||||||
if ctx.is_host and not EntityHasTag(ent, "polymorphed_player") then
|
if not EntityHasTag(ent, "polymorphed_player") and is_item_on_ground(ent) then
|
||||||
if not EntityHasTag(ent, "ew_global_item") then
|
if not EntityHasTag(ent, "ew_global_item") then
|
||||||
item_sync.make_item_global(ent)
|
if ctx.is_host then
|
||||||
|
item_sync.make_item_global(ent)
|
||||||
|
else
|
||||||
|
EntityKill(ent)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if GameGetFrameNum() % 5 == 3 then
|
if GameGetFrameNum() % 60 == 3 then
|
||||||
send_item_positions()
|
send_item_positions(true)
|
||||||
|
elseif GameGetFrameNum() % 5 == 3 then
|
||||||
|
send_item_positions(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -507,13 +498,6 @@ function rpc.item_globalize(item_data)
|
||||||
ComponentSetValue2(damage_component, "wait_for_kill_flag_on_death", true)
|
ComponentSetValue2(damage_component, "wait_for_kill_flag_on_death", true)
|
||||||
EntityAddComponent2(item, "LuaComponent", {_tags="ew_immortal", script_damage_about_to_be_received = "mods/quant.ew/files/resource/cbs/immortal.lua"})
|
EntityAddComponent2(item, "LuaComponent", {_tags="ew_immortal", script_damage_about_to_be_received = "mods/quant.ew/files/resource/cbs/immortal.lua"})
|
||||||
end
|
end
|
||||||
if not is_my_item(item_data.gid) then
|
|
||||||
local itemcom = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent")
|
|
||||||
if ComponentGetValue2(itemcom, "play_hover_animation") then
|
|
||||||
ComponentSetValue2(itemcom, "play_hover_animation", false)
|
|
||||||
ComponentSetValue2(itemcom, "play_spinning_animation", false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
rpc.opts_reliable()
|
rpc.opts_reliable()
|
||||||
|
@ -537,18 +521,36 @@ function rpc.item_localize_req(gid)
|
||||||
item_sync.host_localize_item(gid, ctx.rpc_peer_id)
|
item_sync.host_localize_item(gid, ctx.rpc_peer_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
function rpc.update_positions(position_data)
|
local function cleanup(peer)
|
||||||
local LIMIT = 128 * 3
|
for gid, num in pairs(gid_last_frame_updated[peer]) do
|
||||||
|
if frame[peer] > num then
|
||||||
|
local item = item_sync.find_by_gid(gid)
|
||||||
|
if is_item_on_ground(item) then
|
||||||
|
EntityKill(item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
gid_last_frame_updated[peer] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function rpc.update_positions(position_data, all)
|
||||||
|
if frame[ctx.rpc_peer_id] == nil or all then
|
||||||
|
frame[ctx.rpc_peer_id] = GameGetFrameNum()
|
||||||
|
if gid_last_frame_updated[ctx.rpc_peer_id] == nil then
|
||||||
|
gid_last_frame_updated[ctx.rpc_peer_id] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
local cx, cy = GameGetCameraPos()
|
local cx, cy = GameGetCameraPos()
|
||||||
for gid, el in pairs(position_data) do
|
for gid, el in pairs(position_data) do
|
||||||
local x, y, r = el[1], el[2], el[3]
|
local x, y = el[1], el[2]
|
||||||
local phys_info = el[4]
|
if math.abs(x - cx) < DISTANCE_LIMIT and math.abs(y - cy) < DISTANCE_LIMIT then
|
||||||
local price = el[5]
|
gid_last_frame_updated[ctx.rpc_peer_id][gid] = frame[ctx.rpc_peer_id]
|
||||||
if math.abs(x - cx) < LIMIT and math.abs(y - cy) < LIMIT then
|
local phys_info = el[3]
|
||||||
|
local price = el[4]
|
||||||
local item = item_sync.find_by_gid(gid)
|
local item = item_sync.find_by_gid(gid)
|
||||||
if item ~= nil then
|
if item ~= nil then
|
||||||
if not util.set_phys_info(item, phys_info) then
|
if not util.set_phys_info(item, phys_info) then
|
||||||
EntitySetTransform(item, x, y, r)
|
EntitySetTransform(item, x, y)
|
||||||
end
|
end
|
||||||
local costcom = EntityGetFirstComponentIncludingDisabled(item, "ItemCostComponent")
|
local costcom = EntityGetFirstComponentIncludingDisabled(item, "ItemCostComponent")
|
||||||
if costcom ~= nil then
|
if costcom ~= nil then
|
||||||
|
@ -569,6 +571,12 @@ function rpc.update_positions(position_data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if all then
|
||||||
|
async(function()
|
||||||
|
wait(1)
|
||||||
|
cleanup(ctx.rpc_peer_id)
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function rpc.request_send_again(gid)
|
function rpc.request_send_again(gid)
|
||||||
|
|
|
@ -310,7 +310,8 @@ local function on_world_pre_update_inner()
|
||||||
player_fns.respawn_if_necessary()
|
player_fns.respawn_if_necessary()
|
||||||
end
|
end
|
||||||
|
|
||||||
if ctx.events.new_player_just_connected or ctx.events.inventory_maybe_just_changed or (GameGetFrameNum() % 5 == 0 and inventory_helper.has_inventory_changed(ctx.my_player)) then
|
local sha_check = GameGetFrameNum() % 5 == 0 and inventory_helper.has_inventory_changed(ctx.my_player)
|
||||||
|
if ctx.events.new_player_just_connected or ctx.events.inventory_maybe_just_changed or sha_check then
|
||||||
local inventory_state = player_fns.serialize_items(ctx.my_player)
|
local inventory_state = player_fns.serialize_items(ctx.my_player)
|
||||||
if inventory_state ~= nil then
|
if inventory_state ~= nil then
|
||||||
net.send_player_inventory(inventory_state)
|
net.send_player_inventory(inventory_state)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue