noita_entangled_worlds/files/src/item_sync.lua

131 lines
4.5 KiB
Lua
Raw Normal View History

2024-05-13 13:07:28 +03:00
local inventory_helper = dofile_once("mods/quant.ew/files/src/inventory_helper.lua")
local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua")
local util = dofile_once("mods/quant.ew/files/src/util.lua")
local item_sync = {}
2024-05-13 16:19:28 +03:00
function item_sync.ensure_notify_component(ent)
local notify = EntityGetFirstComponentIncludingDisabled(ent, "LuaComponent", "ew_notify_component")
2024-05-13 13:07:28 +03:00
if notify == nil then
EntityAddComponent2(ent, "LuaComponent", {
_tags = "enabled_in_world,enabled_in_hand,enabled_in_inventory,ew_notify_component",
script_throw_item = "mods/quant.ew/files/cbs/item_notify.lua",
script_item_picked_up = "mods/quant.ew/files/cbs/item_notify.lua",
-- script_kick = "mods/quant.ew/files/cbs/item_notify.lua",
})
end
2024-05-13 16:19:28 +03:00
end
local function mark_in_inventory(my_player)
local items = inventory_helper.get_all_inventory_items(my_player)
for _, ent in pairs(items) do
item_sync.ensure_notify_component(ent)
2024-05-13 13:07:28 +03:00
end
end
2024-05-13 15:18:52 +03:00
local function allocate_global_id()
local current = tonumber(GlobalsGetValue("ew_global_item_id", "1"))
GlobalsSetValue("ew_global_item_id", tostring(current+1))
return current
end
2024-05-13 13:07:28 +03:00
local function is_item_on_ground(item)
return EntityGetComponent(item, "SimplePhysicsComponent") ~= nil or EntityGetComponent(item, "PhysicsBodyComponent")
end
2024-05-13 15:18:52 +03:00
function item_sync.get_global_item_id(item)
local g_id = EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_global_item_id")
if g_id == nil then
GamePrint("Item has no g_id")
return 0
end
local ret = ComponentGetValue2(g_id, "value_int")
return ret or 0
end
function item_sync.remove_item_with_id(g_id)
local global_items = EntityGetWithTag("ew_global_item")
for _, item in ipairs(global_items) do
local i_g_id = item_sync.get_global_item_id(item)
if i_g_id == g_id then
EntityKill(item)
end
end
end
2024-05-13 16:19:28 +03:00
function item_sync.host_localize_item(gid, peer_id)
2024-05-13 16:52:29 +03:00
if ctx.item_prevent_localize[gid] then
GamePrint("Item localize for "..gid.." prevented")
end
ctx.item_prevent_localize[gid] = true
2024-05-13 15:18:52 +03:00
if peer_id ~= ctx.my_id then
2024-05-13 16:19:28 +03:00
item_sync.remove_item_with_id(gid)
2024-05-13 15:18:52 +03:00
end
2024-05-13 16:19:28 +03:00
ctx.lib.net.send_localize(peer_id, gid)
2024-05-13 15:18:52 +03:00
end
2024-05-13 13:07:28 +03:00
function item_sync.make_item_global(item)
2024-05-13 15:18:52 +03:00
local g_id = EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_global_item_id")
local id = ComponentGetValue2(g_id, "value_int")
if g_id == nil then
id = allocate_global_id()
EntityAddComponent2(item, "VariableStorageComponent", {
_tags = "enabled_in_world,enabled_in_hand,enabled_in_inventory,ew_global_item_id",
value_int = id,
})
end
2024-05-13 13:07:28 +03:00
local item_data = inventory_helper.serialize_single_item(item)
2024-05-13 15:18:52 +03:00
item_data.g_id = id
2024-05-13 16:52:29 +03:00
ctx.item_prevent_localize[id] = false
2024-05-13 13:07:28 +03:00
ctx.lib.net.send_make_global(item_data)
end
local function get_global_ent(key)
local val = tonumber(GlobalsGetValue(key, "0"))
GlobalsSetValue(key, "0")
if val ~= 0 then
return val
end
end
function item_sync.host_upload_items(my_player)
if GameGetFrameNum() % 5 == 4 then
mark_in_inventory(my_player)
end
local thrown_item = get_global_ent("ew_thrown")
if thrown_item ~= nil then
EntityAddTag(thrown_item, "ew_global_item")
item_sync.make_item_global(thrown_item)
end
2024-05-13 15:18:52 +03:00
local picked_item = get_global_ent("ew_picked")
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then
2024-05-13 16:19:28 +03:00
local g_id = item_sync.get_global_item_id(picked_item)
item_sync.host_localize_item(g_id, ctx.my_id)
end
end
function item_sync.client_tick(my_player)
2024-05-13 16:52:29 +03:00
if GameGetFrameNum() % 5 == 4 then
mark_in_inventory(my_player)
end
local thrown_item = get_global_ent("ew_thrown")
if thrown_item ~= nil then
ctx.lib.net.send_item_upload(inventory_helper.serialize_single_item(thrown_item))
EntityKill(thrown_item)
end
2024-05-13 16:19:28 +03:00
local picked_item = get_global_ent("ew_picked")
if picked_item ~= nil and EntityHasTag(picked_item, "ew_global_item") then
local gid = item_sync.get_global_item_id(picked_item)
ctx.lib.net.send_localize_request(gid)
2024-05-13 15:18:52 +03:00
end
2024-05-13 13:07:28 +03:00
end
2024-05-13 16:52:29 +03:00
function item_sync.upload(item_data)
local item = inventory_helper.deserialize_single_item(item_data)
EntityAddTag(item, "ew_global_item")
item_sync.ensure_notify_component(item)
item_sync.make_item_global(item)
end
2024-05-13 13:07:28 +03:00
return item_sync