diff --git a/files/append/gun.lua b/files/append/gun.lua index 9ea056ee..82ccc717 100644 --- a/files/append/gun.lua +++ b/files/append/gun.lua @@ -2,7 +2,7 @@ local old_order_deck = order_deck order_deck = function() local oldSetRandomSeed = SetRandomSeed - SetRandomSeed = function() + SetRandomSeed = function() local shooter = EntityGetRootEntity(GetUpdatedEntityID()) @@ -12,11 +12,13 @@ order_deck = function() local seed = 0 if(EntityHasTag(shooter, "ew_client"))then - --GamePrint("2: shooter_rng_"..EntityGetName(shooter)) + -- GamePrint("2: ew_shooter_rng_"..EntityGetName(shooter)) + -- GamePrint(GlobalsGetValue("ew_shooter_rng_"..EntityGetName(shooter), "0")) seed = tonumber(GlobalsGetValue("ew_shooter_rng_"..EntityGetName(shooter), "0")) or 0 elseif(EntityHasTag(shooter, "player_unit"))then seed = Random(10, 10000000) GlobalsSetValue("ew_player_rng", tostring(seed)) + -- GamePrint(tostring(seed)) end oldSetRandomSeed(seed, seed) diff --git a/files/src/ctx.lua b/files/src/ctx.lua index 150688ca..04b8fc79 100644 --- a/files/src/ctx.lua +++ b/files/src/ctx.lua @@ -11,6 +11,8 @@ ctx.init = function() ctx.run_ended = false ctx.player_data_by_local_entity = {} ctx.item_prevent_localize = {} + ctx.events = {} + ctx.is_inventory_open = false end return ctx \ No newline at end of file diff --git a/files/src/inventory_helper.lua b/files/src/inventory_helper.lua index c410d41d..4078c3ae 100644 --- a/files/src/inventory_helper.lua +++ b/files/src/inventory_helper.lua @@ -261,5 +261,18 @@ function inventory_helper.set_item_data(item_data, player_data) end end +function inventory_helper.has_inventory_changed(player_data) + local prev_inventory = player_data.prev_inventory_hash + + local inventory_hash = 0 + for _, item in ipairs(GameGetAllInventoryItems(player_data.entity)) do + local item_comp = EntityGetFirstComponentIncludingDisabled(item, "ItemComponent") + local slot_x, slot_y = ComponentGetValue2(item_comp, "inventory_slot") + inventory_hash = (inventory_hash + (item % 1024 + slot_x + slot_y)) % (math.pow(2, 20) - 1) + end + player_data.prev_inventory_hash = inventory_hash + return inventory_hash ~= prev_inventory +end + return inventory_helper diff --git a/files/src/net.lua b/files/src/net.lua index 4b4688ad..f5d8b2ae 100644 --- a/files/src/net.lua +++ b/files/src/net.lua @@ -114,6 +114,10 @@ function net.send_player_perks(perk_data) net.send("perks", perk_data, true) end +function net.send_welcome() + net.send("welcome", nil, true) +end + function net.send_enemy_data(enemy_data) net.send("enemy", enemy_data) end diff --git a/files/src/net_handling.lua b/files/src/net_handling.lua index efde292c..87240b18 100644 --- a/files/src/net_handling.lua +++ b/files/src/net_handling.lua @@ -191,4 +191,8 @@ function net_handling.mod.item_upload(peer_id, item_data) item_sync.upload(item_data) end +function net_handling.mod.welcome(peer_id, _) + ctx.events.new_player_just_connected = true +end + return net_handling \ No newline at end of file diff --git a/files/src/player_fns.lua b/files/src/player_fns.lua index 459712ed..79291269 100644 --- a/files/src/player_fns.lua +++ b/files/src/player_fns.lua @@ -393,6 +393,9 @@ function player_fns.peer_has_player(peer_id) end function player_fns.peer_get_player_data(peer_id) + if not player_fns.peer_has_player(peer_id) then + player_fns.spawn_player_for(peer_id, ctx.initial_player_pos.x, ctx.initial_player_pos.y) + end return ctx.players[peer_id] end @@ -413,6 +416,7 @@ function player_fns.spawn_player_for(peer_id, x, y) end util.set_ent_firing_blocked(new, true) ctx.player_data_by_local_entity[new] = new_playerdata + ctx.events.new_player_just_spawned = true end function player_fns.is_inventory_open() diff --git a/init.lua b/init.lua index 6264add5..73043dae 100755 --- a/init.lua +++ b/init.lua @@ -17,6 +17,7 @@ local perk_fns = dofile_once("mods/quant.ew/files/src/perk_fns.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 item_sync = dofile_once("mods/quant.ew/files/src/item_sync.lua") +local inventory_helper = dofile_once("mods/quant.ew/files/src/inventory_helper.lua") ModLuaFileAppend("data/scripts/gun/gun.lua", "mods/quant.ew/files/append/gun.lua") ModLuaFileAppend("data/scripts/gun/gun_actions.lua", "mods/quant.ew/files/append/action_fix.lua") @@ -112,6 +113,14 @@ end function OnPlayerSpawned( player_entity ) -- This runs when player entity has been created GamePrint( "OnPlayerSpawned() - Player entity id: " .. tostring(player_entity) ) + for _, client in pairs(EntityGetWithTag("ew_client")) do + GamePrint("Removing previous client: "..client) + EntityKill(client) + end + + local x, y = EntityGetTransform(player_entity) + ctx.initial_player_pos = {x=x, y=y} + my_player = player_fns.make_playerdata_for(player_entity, ctx.my_id) GamePrint("My peer_id: "..ctx.my_id) ctx.players[ctx.my_id] = my_player @@ -150,6 +159,13 @@ local function on_world_pre_update_inner() net.update() + local inventory_gui_comp = EntityGetFirstComponentIncludingDisabled(my_player.entity, "InventoryGuiComponent") + local inventory_open = ComponentGetValue2(inventory_gui_comp, "mActive") + if ctx.is_inventory_open and not inventory_open then + ctx.events.inventory_maybe_just_changed = true + end + ctx.is_inventory_open = inventory_open + if ctx.is_host and not EntityGetIsAlive(my_player.entity) then if not ctx.run_ended then GamePrint("Notifying of run end") @@ -169,6 +185,10 @@ local function on_world_pre_update_inner() end end + if GameGetFrameNum() == 0 then + net.send_welcome() + end + -- Item sync if ctx.is_host then item_sync.host_upload_items(my_player) @@ -212,12 +232,18 @@ local function on_world_pre_update_inner() net.send_host_player_info(player_info) end + if ctx.events.new_player_just_connected or ctx.events.inventory_maybe_just_changed or GameGetFrameNum() % 20 == 0 then + if ctx.events.new_player_just_connected or inventory_helper.has_inventory_changed(my_player) then + local inventory_state = player_fns.serialize_items(my_player) + if inventory_state ~= nil then + GamePrint("Sending updated inventory") + net.send_player_inventory(inventory_state) + end + end + end + -- Inventory and perk sync if GameGetFrameNum() % 120 == 0 then - local inventory_state = player_fns.serialize_items(my_player) - if inventory_state ~= nil then - net.send_player_inventory(inventory_state) - end local perk_data = perk_fns.get_my_perks() if perk_data ~= nil then net.send_player_perks(perk_data) @@ -243,6 +269,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 = {} end diff --git a/todo.txt b/todo.txt index 38b2a26a..974397c0 100644 --- a/todo.txt +++ b/todo.txt @@ -9,7 +9,7 @@ + Sync shuffle k Синхронизировать смерти противников - Общее золото - - Удаление лишних клиентов при загрузке игры + + Удаление лишних клиентов при загрузке игры - intern pathnames in enemy sync + Fix bottles and other items duplicating when thrown (on host?) @@ -24,8 +24,9 @@ + Позволить менять сид мира - Никнеймы игроков k Лимит на длину сообщения - - Улучшеная синхронизация инвентаря и перков - + ...и текущего предмета + + Улучшеная синхронизация инвентаря + - ...и перков + + ...и текущего предмета + reliability + Сжатие пакетов + Перекидывание предметов @@ -37,4 +38,3 @@ - proxy: stop receiving connections before another start_game on game over, noita: try to reconnect to proxy. - sync traps - holy mountains are screwed up when clients enter it before host does - \ No newline at end of file