mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
more forcefully fix item duplication, but it should be fixed outright anyways, try to fix notplayer holding double wands, if player tries to pick a slot with no items, request items again, revert some enemy sync stuff to hopefully fix some entity duplication
This commit is contained in:
parent
b8cb7eb998
commit
161e71fefc
7 changed files with 115 additions and 60 deletions
|
@ -420,11 +420,11 @@ function inventory_helper.set_item_data(item_data, player_data, local_ent)
|
|||
EntityAddComponent(item_entity, "LuaComponent", {
|
||||
script_throw_item = "mods/quant.ew/files/resource/cbs/throw_item.lua",
|
||||
})
|
||||
end
|
||||
local notify = EntityGetFirstComponentIncludingDisabled(item_entity, "LuaComponent", "ew_notify_component")
|
||||
if notify ~= nil then
|
||||
EntityRemoveComponent(item_entity, notify)
|
||||
end
|
||||
end
|
||||
--print("Deserialized wand #"..tostring(k).." - Active? "..tostring(wandInfo.active))
|
||||
|
||||
-- entity.SetVariable(item_entity, "arena_entity_id", itemInfo.id)
|
||||
|
|
|
@ -644,7 +644,7 @@ function player_fns.set_current_slot(slot_data, player_data)
|
|||
if (mActiveItem ~= item) then
|
||||
np.SetActiveHeldEntity(player_data.entity, item, false, false)
|
||||
end
|
||||
return
|
||||
return true
|
||||
end
|
||||
else
|
||||
print("something in inventory that is not an item")
|
||||
|
|
|
@ -402,7 +402,7 @@ function util.get_phys_info(entity, kill)
|
|||
local ret, info = pcall(serialize_phys_component, phys_component)
|
||||
if not ret and kill then
|
||||
EntityKill(entity)
|
||||
return nil
|
||||
return {{}, {}}
|
||||
end
|
||||
table.insert(phys_info, info)
|
||||
end
|
||||
|
@ -415,7 +415,7 @@ function util.get_phys_info(entity, kill)
|
|||
local ret, info = pcall(serialize_phys_component, phys_component)
|
||||
if not ret and kill then
|
||||
EntityKill(entity)
|
||||
return nil
|
||||
return {{}, {}}
|
||||
end
|
||||
table.insert(phys_info_2, info)
|
||||
else
|
||||
|
|
|
@ -49,8 +49,6 @@ local HpData = util.make_type({
|
|||
f32 = {"hp", "max_hp"}
|
||||
})
|
||||
|
||||
local wait_1_frame = false
|
||||
|
||||
local FULL_TURN = math.pi * 2
|
||||
|
||||
local frame = 0
|
||||
|
@ -361,14 +359,7 @@ end
|
|||
|
||||
function enemy_sync.on_world_update_client()
|
||||
if GameGetFrameNum() % 12 == 1 then
|
||||
if wait_1_frame then
|
||||
async(function()
|
||||
wait(1)
|
||||
enemy_sync.client_cleanup()
|
||||
end)
|
||||
else
|
||||
enemy_sync.client_cleanup()
|
||||
end
|
||||
end
|
||||
if GameGetFrameNum() % (60*60) == 1 then
|
||||
times_spawned_last_minute = {}
|
||||
|
@ -674,10 +665,7 @@ function rpc.handle_death_data(death_data)
|
|||
end
|
||||
|
||||
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
|
||||
async(function()
|
||||
wait(1)
|
||||
EntityKill(enemy_id)
|
||||
end)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
@ -688,7 +676,6 @@ function rpc.handle_enemy_data(enemy_data)
|
|||
for _, enemy_info_raw in ipairs(enemy_data) do
|
||||
sync_enemy(enemy_info_raw, false)
|
||||
end
|
||||
wait_1_frame = true
|
||||
end
|
||||
|
||||
function rpc.handle_enemy_health(enemy_health_data)
|
||||
|
|
|
@ -22,6 +22,8 @@ local frame = {}
|
|||
|
||||
local gid_last_frame_updated = {}
|
||||
|
||||
local wait_on_send = {}
|
||||
|
||||
function rpc.open_chest(gid)
|
||||
local ent = item_sync.find_by_gid(gid)
|
||||
if ent ~= nil then
|
||||
|
@ -46,7 +48,7 @@ end
|
|||
|
||||
util.add_cross_call("ew_chest_opened", function(chest_id)
|
||||
local gid = item_sync.get_global_item_id(chest_id)
|
||||
if gid ~= "unknown" then
|
||||
if gid ~= nil then
|
||||
rpc.open_chest(gid)
|
||||
end
|
||||
end)
|
||||
|
@ -97,10 +99,10 @@ end
|
|||
function item_sync.get_global_item_id(item)
|
||||
local gid = EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_global_item_id")
|
||||
if gid == nil then
|
||||
return "unknown"
|
||||
return nil
|
||||
end
|
||||
local ret = ComponentGetValue2(gid, "value_string")
|
||||
return ret or "unknown"
|
||||
return ret
|
||||
end
|
||||
|
||||
function item_sync.remove_item_with_id(gid)
|
||||
|
@ -110,7 +112,8 @@ end
|
|||
local find_by_gid_cache = {}
|
||||
function item_sync.find_by_gid(gid)
|
||||
if find_by_gid_cache[gid] ~= nil then
|
||||
if EntityGetIsAlive(find_by_gid_cache[gid]) and EntityHasTag(find_by_gid_cache[gid], "ew_global_item") then
|
||||
if EntityGetIsAlive(find_by_gid_cache[gid])
|
||||
and EntityHasTag(find_by_gid_cache[gid], "ew_global_item") and is_item_on_ground(find_by_gid_cache[gid]) then
|
||||
return find_by_gid_cache[gid]
|
||||
else
|
||||
find_by_gid_cache[gid] = nil
|
||||
|
@ -119,14 +122,19 @@ function item_sync.find_by_gid(gid)
|
|||
|
||||
--print("find_by_gid: searching")
|
||||
|
||||
local global_items = EntityGetWithTag("ew_global_item")
|
||||
for _, item in ipairs(global_items) do
|
||||
local candidate
|
||||
for _, item in ipairs(EntityGetWithTag("ew_global_item") or {}) do
|
||||
local i_gid = item_sync.get_global_item_id(item)
|
||||
find_by_gid_cache[i_gid] = item
|
||||
if i_gid == gid then
|
||||
if is_item_on_ground(item) then
|
||||
return item
|
||||
else
|
||||
candidate = item
|
||||
end
|
||||
end
|
||||
end
|
||||
return candidate
|
||||
end
|
||||
|
||||
function item_sync.remove_item_with_id_now(gid)
|
||||
|
@ -163,6 +171,11 @@ function item_sync.host_localize_item(gid, peer_id)
|
|||
item_sync.remove_item_with_id(gid)
|
||||
end
|
||||
rpc.item_localize(peer_id, gid)
|
||||
if peer_id == ctx.my_id then
|
||||
item_sync.take_authority(gid)
|
||||
else
|
||||
rpc.hand_authority_over_to(peer_id, gid)
|
||||
end
|
||||
end
|
||||
|
||||
local wait_for_gid = {}
|
||||
|
@ -205,6 +218,7 @@ local function make_global(item, give_authority_to)
|
|||
|
||||
ctx.item_prevent_localize[gid] = false
|
||||
rpc.item_globalize(item_data)
|
||||
wait_on_send[gid] = nil
|
||||
end
|
||||
|
||||
function item_sync.make_item_global(item, instant, give_authority_to)
|
||||
|
@ -238,6 +252,10 @@ local function remove_client_items_from_world()
|
|||
end
|
||||
end
|
||||
|
||||
local function is_peers_item(gid, peer)
|
||||
return string.sub(gid, 1, 16) == peer
|
||||
end
|
||||
|
||||
local function is_my_item(gid)
|
||||
return string.sub(gid, 1, 16) == ctx.my_id
|
||||
end
|
||||
|
@ -253,7 +271,9 @@ rpc.opts_everywhere()
|
|||
rpc.opts_reliable()
|
||||
function rpc.give_authority_to(gid, new_id)
|
||||
local item = item_sync.find_by_gid(gid)
|
||||
find_by_gid_cache[gid] = nil
|
||||
if item ~= nil then
|
||||
find_by_gid_cache[new_id] = item
|
||||
local var = EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_global_item_id")
|
||||
ComponentSetValue2(var, "value_string", new_id)
|
||||
end
|
||||
|
@ -316,10 +336,7 @@ function rpc.handle_death_data(death_data)
|
|||
end
|
||||
|
||||
EntityInflictDamage(enemy_id, 1000000000, "DAMAGE_CURSE", "", "NONE", 0, 0, responsible_entity) -- Just to be sure
|
||||
async(function()
|
||||
wait(1)
|
||||
EntityKill(enemy_id)
|
||||
end)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
@ -327,16 +344,18 @@ end
|
|||
|
||||
local DISTANCE_LIMIT = 128 * 4
|
||||
|
||||
local ignore = {}
|
||||
|
||||
local function send_item_positions(all)
|
||||
local position_data = {}
|
||||
local cx, cy = EntityGetTransform(ctx.my_player.entity)
|
||||
for _, item in ipairs(EntityGetWithTag("ew_global_item")) do
|
||||
local gid = item_sync.get_global_item_id(item)
|
||||
-- Only send info about items created by us.
|
||||
if is_my_item(gid) and is_item_on_ground(item) then
|
||||
if gid ~= nil and is_my_item(gid) and is_item_on_ground(item) then
|
||||
local x, y = EntityGetTransform(item)
|
||||
local dx, dy = x - cx, y - cy
|
||||
if dx * dx + dy * dy > 1024 * 1024 then
|
||||
if (ignore[gid] == nil or ignore[gid] < GameGetFrameNum()) and dx * dx + dy * dy > 4 * DISTANCE_LIMIT * DISTANCE_LIMIT then
|
||||
local ent = EntityGetClosestWithTag(x, y, "ew_peer")
|
||||
local nx, ny
|
||||
local ndx, ndy
|
||||
|
@ -351,6 +370,7 @@ local function send_item_positions(all)
|
|||
ndx, ndy = x - nx, y - ny
|
||||
end
|
||||
if ent == 0 or ndx * ndx + ndy * ndy > DISTANCE_LIMIT * DISTANCE_LIMIT then
|
||||
ignore[gid] = GameGetFrameNum() + 60
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
|
@ -358,11 +378,14 @@ local function send_item_positions(all)
|
|||
if data ~= nil then
|
||||
local peer = data.peer_id
|
||||
rpc.hand_authority_over_to(peer, gid)
|
||||
ignore[gid] = nil
|
||||
else
|
||||
ignore[gid] = GameGetFrameNum() + 60
|
||||
end
|
||||
else
|
||||
local phys_info = util.get_phys_info(item, true)
|
||||
if ((phys_info[1] ~= nil and phys_info[1][1] ~= nil)
|
||||
or (phys_info[2] ~= nil and phys_info[2][1] ~= nil)
|
||||
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
|
||||
|
@ -371,7 +394,7 @@ local function send_item_positions(all)
|
|||
if costcom ~= nil then
|
||||
cost = ComponentGetValue2(costcom, "cost")
|
||||
local mx, my = GameGetCameraPos()
|
||||
if math.abs(mx - x) < 1024 and math.abs(my - y) < 1024
|
||||
if math.abs(mx - x) < DISTANCE_LIMIT * 2 and math.abs(my - y) < DISTANCE_LIMIT * 2
|
||||
and EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_try_stealable") then
|
||||
ComponentSetValue2(costcom, "stealable", true)
|
||||
end
|
||||
|
@ -399,11 +422,9 @@ function item_sync.on_world_update_host()
|
|||
item_sync.make_item_global(thrown_item)
|
||||
end
|
||||
local picked_item = get_global_ent("ew_picked")
|
||||
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item")
|
||||
and EntityHasTag(EntityGetRootEntity(picked_item), "ew_peer") then
|
||||
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then
|
||||
local gid = item_sync.get_global_item_id(picked_item)
|
||||
item_sync.host_localize_item(gid, ctx.my_id)
|
||||
item_sync.take_authority(gid)
|
||||
end
|
||||
remove_client_items_from_world()
|
||||
end
|
||||
|
@ -419,11 +440,9 @@ function item_sync.on_world_update_client()
|
|||
end
|
||||
|
||||
local picked_item = get_global_ent("ew_picked")
|
||||
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item")
|
||||
and EntityHasTag(EntityGetRootEntity(picked_item), "ew_peer") then
|
||||
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then
|
||||
local gid = item_sync.get_global_item_id(picked_item)
|
||||
rpc.item_localize_req(gid)
|
||||
item_sync.take_authority(gid)
|
||||
end
|
||||
remove_client_items_from_world()
|
||||
end
|
||||
|
@ -471,9 +490,8 @@ function item_sync.on_should_send_updates()
|
|||
if not ctx.is_host then
|
||||
return
|
||||
end
|
||||
local global_items = EntityGetWithTag("ew_global_item")
|
||||
local item_list = {}
|
||||
for _, item in ipairs(global_items) do
|
||||
for _, item in ipairs(EntityGetWithTag("ew_global_item") or {}) do
|
||||
if is_item_on_ground(item) and not EntityHasTag(item, "mimic_potion") then
|
||||
local item_data = inventory_helper.serialize_single_item(item)
|
||||
local gid = item_sync.get_global_item_id(item)
|
||||
|
@ -548,7 +566,7 @@ function rpc.item_globalize(item_data)
|
|||
item_sync.remove_item_with_id_now(item_data.gid)
|
||||
end
|
||||
local n = item_sync.find_by_gid(item_data.gid)
|
||||
if n ~= nil and EntityGetRootEntity(n) == n then
|
||||
if n ~= nil then
|
||||
return
|
||||
end
|
||||
local item = inventory_helper.deserialize_single_item(item_data)
|
||||
|
@ -593,10 +611,24 @@ local function cleanup(peer)
|
|||
local item = item_sync.find_by_gid(gid)
|
||||
if is_item_on_ground(item) then
|
||||
EntityKill(item)
|
||||
gid_last_frame_updated[peer][gid] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
local is_duplicate = {}
|
||||
for _, item in ipairs(EntityGetWithTag("ew_global_item") or {}) do
|
||||
local gid = item_sync.get_global_item_id(item)
|
||||
if gid ~= nil and is_peers_item(gid, peer) then
|
||||
if (gid_last_frame_updated[peer] == nil or is_duplicate[gid]) and is_item_on_ground(item) then
|
||||
EntityKill(item)
|
||||
else
|
||||
if is_duplicate[gid] then
|
||||
EntityKill(is_duplicate[gid])
|
||||
end
|
||||
is_duplicate[gid] = item
|
||||
end
|
||||
end
|
||||
end
|
||||
gid_last_frame_updated[peer] = {}
|
||||
end
|
||||
|
||||
function rpc.update_positions(position_data, all)
|
||||
|
@ -628,20 +660,15 @@ function rpc.update_positions(position_data, all)
|
|||
ComponentSetValue2(costcom, "cost", price)
|
||||
end
|
||||
end
|
||||
else
|
||||
elseif wait_for_gid[gid] == nil then
|
||||
util.log("Requesting again "..gid)
|
||||
if wait_for_gid[gid] == nil then
|
||||
rpc.request_send_again(gid)
|
||||
wait_for_gid[gid] = GameGetFrameNum() + 300
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if all then
|
||||
async(function()
|
||||
wait(1)
|
||||
cleanup(ctx.rpc_peer_id)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -654,7 +681,10 @@ function rpc.request_send_again(gid)
|
|||
util.log("Requested to send item again, but this item wasn't found: "..gid)
|
||||
return
|
||||
end
|
||||
if wait_on_send[gid] == nil or wait_on_send[gid] < GameGetFrameNum() then
|
||||
wait_on_send[gid] = GameGetFrameNum() + 240
|
||||
item_sync.make_item_global(item)
|
||||
end
|
||||
end
|
||||
|
||||
ctx.cap.item_sync = {
|
||||
|
|
|
@ -205,6 +205,22 @@ local function show_death_message()
|
|||
end
|
||||
end
|
||||
|
||||
local function reset_cast_state_if_has_any_other_item(player_data)
|
||||
local inventory2Comp = EntityGetFirstComponentIncludingDisabled(player_data.entity, "Inventory2Component")
|
||||
if inventory2Comp == nil then
|
||||
return
|
||||
end
|
||||
local mActiveItem = ComponentGetValue2(inventory2Comp, "mActiveItem")
|
||||
|
||||
for k, item in ipairs(inventory_helper.get_inventory_items(player_data, "inventory_quick") or {}) do
|
||||
if item ~= mActiveItem then
|
||||
np.SetActiveHeldEntity(player_data.entity, item)
|
||||
np.SetActiveHeldEntity(player_data.entity, mActiveItem)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function player_died()
|
||||
if ctx.my_player.entity == nil then
|
||||
return
|
||||
|
@ -275,12 +291,13 @@ local function player_died()
|
|||
polymorph.switch_entity(ent + 1)
|
||||
|
||||
remove_healthbar_locally()
|
||||
inventory_helper.set_item_data(item_data, ctx.my_player, true)
|
||||
for _, child in ipairs(EntityGetAllChildren(ctx.my_player.entity) or {}) do
|
||||
if EntityGetName(child) == "cursor" or EntityGetName(child) == "notcursor" then
|
||||
EntitySetComponentIsEnabled(child, EntityGetFirstComponentIncludingDisabled(child, "SpriteComponent"), false)
|
||||
end
|
||||
end
|
||||
inventory_helper.set_item_data(item_data, ctx.my_player, true)
|
||||
reset_cast_state_if_has_any_other_item(ctx.my_player)
|
||||
remove_inventory_tags()
|
||||
perk_fns.update_perks_for_entity(perk_data, ctx.my_player.entity, allow_notplayer_perk)
|
||||
util.set_ent_health(ctx.my_player.entity, {max_hp, max_hp})
|
||||
|
|
|
@ -18,6 +18,22 @@ function rpc.send_money_and_ingestion(money, ingestion_size)
|
|||
end
|
||||
end
|
||||
|
||||
local wait_on_send = 0
|
||||
|
||||
function rpc.request_items(peer_id)
|
||||
if ctx.my_id == peer_id
|
||||
and wait_on_send < GameGetFrameNum() then
|
||||
wait_on_send = GameGetFrameNum() + 240
|
||||
inventory_helper.has_inventory_changed(ctx.my_player)
|
||||
local inventory_state = player_fns.serialize_items(ctx.my_player)
|
||||
if inventory_state ~= nil then
|
||||
net.send_player_inventory(inventory_state)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local wait_on_requst = {}
|
||||
|
||||
function rpc.player_update(input_data, pos_data, phys_info, current_slot, team)
|
||||
local peer_id = ctx.rpc_peer_id
|
||||
|
||||
|
@ -43,7 +59,12 @@ function rpc.player_update(input_data, pos_data, phys_info, current_slot, team)
|
|||
player_fns.deserialize_position(pos_data, phys_info, player_data)
|
||||
end
|
||||
if current_slot ~= nil then
|
||||
player_fns.set_current_slot(current_slot, player_data)
|
||||
if not player_fns.set_current_slot(current_slot, player_data)
|
||||
and (wait_on_requst[player_data.peer_id] == nil or wait_on_requst[player_data.peer_id] < GameGetFrameNum()) then
|
||||
print("slot empty, requesting items")
|
||||
wait_on_requst[player_data.peer_id] = GameGetFrameNum() + 300
|
||||
rpc.request_items(player_data.peer_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue