mirror of
https://github.com/IntQuant/noita_entangled_worlds.git
synced 2025-10-19 07:03:16 +00:00
Merge branch 'master' of github.com:LuoTianOrange/noita_entangled_worlds
This commit is contained in:
commit
67a8538a64
14 changed files with 147 additions and 43 deletions
|
@ -27,7 +27,7 @@ Used by:
|
|||
## 'item_sync' capability
|
||||
|
||||
Functions:
|
||||
- `globalize(entity_id, instantly: bool)`
|
||||
- `globalize(entity_id, instantly: bool | nil, give_authority_to: PeerId | nil)`
|
||||
- `register_pickup_handler(fn(local_item_id))`
|
||||
|
||||
Provided by:
|
||||
|
|
|
@ -1,23 +1,12 @@
|
|||
//! Various common public types.
|
||||
|
||||
use std::{fmt::Display, time::Duration};
|
||||
use std::fmt::Display;
|
||||
|
||||
use bitcode::{Decode, Encode};
|
||||
|
||||
/// Per-peer settings. Peers that are connected to the same host, as well as the host itself, should have the same settings.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Settings {
|
||||
/// A single datagram will confirm at most this much messages. Default is 128.
|
||||
pub confirm_max_per_message: usize,
|
||||
/// How much time can elapse before another confirm is sent.
|
||||
/// Confirms are also sent when enough messages are awaiting confirm.
|
||||
/// Note that confirms also double as "heartbeats" and keep the connection alive, so this value should be much less than `connection_timeout`.
|
||||
/// Default: 1 second.
|
||||
pub confirm_max_period: Duration,
|
||||
/// Peers will be disconnected after this much time without any datagrams from them has passed.
|
||||
/// Default: 10 seconds.
|
||||
pub connection_timeout: Duration,
|
||||
}
|
||||
pub struct Settings {}
|
||||
|
||||
/// Tells how reliable a message is.
|
||||
#[derive(Encode, Decode, Clone, Copy, PartialEq, Debug)]
|
||||
|
@ -95,11 +84,7 @@ impl Display for PeerId {
|
|||
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
confirm_max_per_message: 128,
|
||||
confirm_max_period: Duration::from_secs(1),
|
||||
connection_timeout: Duration::from_secs(10),
|
||||
}
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use quinn::{
|
|||
pki_types::{CertificateDer, PrivatePkcs8KeyDer},
|
||||
},
|
||||
ClientConfig, ConnectError, Connecting, ConnectionError, Endpoint, Incoming, RecvStream,
|
||||
ServerConfig,
|
||||
ServerConfig, TransportConfig,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
@ -467,6 +467,10 @@ fn default_server_config() -> ServerConfig {
|
|||
let cert_der = CertificateDer::from(cert.cert);
|
||||
let priv_key = PrivatePkcs8KeyDer::from(cert.key_pair.serialize_der());
|
||||
|
||||
let config = ServerConfig::with_single_cert(vec![cert_der.clone()], priv_key.into()).unwrap();
|
||||
let mut config =
|
||||
ServerConfig::with_single_cert(vec![cert_der.clone()], priv_key.into()).unwrap();
|
||||
let mut transport_config = TransportConfig::default();
|
||||
transport_config.keep_alive_interval(Some(Duration::from_secs(10)));
|
||||
config.transport_config(Arc::new(transport_config));
|
||||
config
|
||||
}
|
||||
|
|
|
@ -159,8 +159,6 @@ mod test {
|
|||
async fn test_peer() {
|
||||
info!("Starting test_peer");
|
||||
let settings = Some(Settings {
|
||||
confirm_max_period: Duration::from_millis(100),
|
||||
connection_timeout: Duration::from_millis(1000),
|
||||
..Default::default()
|
||||
});
|
||||
let addr = "127.0.0.1:56001".parse().unwrap();
|
||||
|
@ -194,8 +192,6 @@ mod test {
|
|||
#[test_log::test(tokio::test)]
|
||||
async fn test_broadcast() {
|
||||
let settings = Some(Settings {
|
||||
confirm_max_period: Duration::from_millis(100),
|
||||
connection_timeout: Duration::from_millis(1000),
|
||||
..Default::default()
|
||||
});
|
||||
let addr = "127.0.0.1:56002".parse().unwrap();
|
||||
|
@ -233,8 +229,6 @@ mod test {
|
|||
#[test_log::test(tokio::test)]
|
||||
async fn test_host_has_conn() {
|
||||
let settings = Some(Settings {
|
||||
confirm_max_period: Duration::from_millis(100),
|
||||
connection_timeout: Duration::from_millis(1000),
|
||||
..Default::default()
|
||||
});
|
||||
let addr = "127.0.0.1:56003".parse().unwrap();
|
||||
|
|
|
@ -313,7 +313,7 @@ function enemy_sync.client_cleanup()
|
|||
local frame = GameGetFrameNum()
|
||||
for remote_id, enemy_data in pairs(ctx.entity_by_remote_id) do
|
||||
if frame - enemy_data.frame > 60*1 then
|
||||
print("Despawning stale "..remote_id.." "..enemy_data.id)
|
||||
--print("Despawning stale "..remote_id.." "..enemy_data.id)
|
||||
EntityKill(enemy_data.id)
|
||||
ctx.entity_by_remote_id[remote_id] = nil
|
||||
end
|
||||
|
|
|
@ -42,7 +42,11 @@ local function run_spawn_fn(fn_name, x, y, ...)
|
|||
-- Function returns item's entity id.
|
||||
if fn_info.kind == "item" then
|
||||
local eid = ret
|
||||
ctx.cap.item_sync.globalize(eid, false)
|
||||
ctx.cap.item_sync.globalize(eid, true, ctx.rpc_peer_id)
|
||||
-- Avoid item losing it's cost on host.
|
||||
local x, y = EntityGetTransform(eid)
|
||||
local minishop = EntityLoad("mods/quant.ew/files/system/gen_sync/tmp_shop_area.xml", x, y)
|
||||
EntityAddChild(eid, minishop)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
20
quant.ew/files/system/gen_sync/tmp_shop_area.xml
Normal file
20
quant.ew/files/system/gen_sync/tmp_shop_area.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Entity
|
||||
tags="shop" >
|
||||
|
||||
<HitboxComponent
|
||||
_tags="enabled_in_world"
|
||||
aabb_min_x="-5"
|
||||
aabb_min_y="-5"
|
||||
aabb_max_x="5"
|
||||
aabb_max_y="5"
|
||||
damage_multiplier="1"
|
||||
is_enemy="1"
|
||||
is_item="0"
|
||||
is_player="0"
|
||||
offset.x="0"
|
||||
offset.y="0"
|
||||
/>
|
||||
|
||||
<InheritTransformComponent _tags="enabled_in_world"/>
|
||||
<LuaComponent _tags="enabled_in_world" execute_every_n_frame="300" script_source_file="mods/quant.ew/files/system/gen_sync/tmp_shop_script.lua"/>
|
||||
</Entity>
|
7
quant.ew/files/system/gen_sync/tmp_shop_script.lua
Normal file
7
quant.ew/files/system/gen_sync/tmp_shop_script.lua
Normal file
|
@ -0,0 +1,7 @@
|
|||
-- Deletes the temporary shop entity after the world has been properly generated.
|
||||
|
||||
local ent = GetUpdatedEntityID()
|
||||
local x, y = EntityGetTransform(ent)
|
||||
if DoesWorldExistAt(x-5, y-5, x+5, y+5) then
|
||||
EntityKill(ent)
|
||||
end
|
|
@ -47,7 +47,6 @@ end
|
|||
function item_sync.get_global_item_id(item)
|
||||
local gid = EntityGetFirstComponentIncludingDisabled(item, "VariableStorageComponent", "ew_global_item_id")
|
||||
if gid == nil then
|
||||
GamePrint("Item has no gid")
|
||||
return "unknown"
|
||||
end
|
||||
local ret = ComponentGetValue2(gid, "value_string")
|
||||
|
@ -110,7 +109,7 @@ function item_sync.host_localize_item(gid, peer_id)
|
|||
rpc.item_localize(peer_id, gid)
|
||||
end
|
||||
|
||||
function item_sync.make_item_global(item, instant)
|
||||
function item_sync.make_item_global(item, instant, give_authority_to)
|
||||
EntityAddTag(item, "ew_global_item")
|
||||
async(function()
|
||||
if not instant then
|
||||
|
@ -126,6 +125,9 @@ function item_sync.make_item_global(item, instant)
|
|||
local gid
|
||||
if gid_component == nil then
|
||||
gid = allocate_global_id()
|
||||
if give_authority_to ~= nil then
|
||||
gid = give_authority_to..":"..gid
|
||||
end
|
||||
EntityAddComponent2(item, "VariableStorageComponent", {
|
||||
_tags = "enabled_in_world,enabled_in_hand,enabled_in_inventory,ew_global_item_id",
|
||||
value_string = gid,
|
||||
|
@ -317,7 +319,6 @@ end
|
|||
rpc.opts_reliable()
|
||||
function rpc.item_globalize(item_data)
|
||||
if is_safe_to_remove() then
|
||||
print("remove in globalize")
|
||||
item_sync.remove_item_with_id_now(item_data.gid)
|
||||
end
|
||||
local item = inventory_helper.deserialize_single_item(item_data)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<Entity>
|
||||
|
||||
<ParticleEmitterComponent
|
||||
emitted_material_name="spark_green"
|
||||
gravity.y="0.0"
|
||||
lifetime_min="2"
|
||||
lifetime_max="5"
|
||||
count_min="4"
|
||||
count_max="4"
|
||||
render_on_grid="1"
|
||||
fade_based_on_lifetime="1"
|
||||
area_circle_radius.min="0"
|
||||
area_circle_radius.max="0"
|
||||
cosmetic_force_create="0"
|
||||
airflow_force="0.251"
|
||||
airflow_time="1.01"
|
||||
airflow_scale="0.05"
|
||||
emission_interval_min_frames="1"
|
||||
emission_interval_max_frames="1"
|
||||
emit_cosmetic_particles="1"
|
||||
image_animation_file="data/particles/image_emitters/animated_emitter_large.png"
|
||||
image_animation_speed="3"
|
||||
image_animation_loop="0"
|
||||
is_emitting="1" >
|
||||
</ParticleEmitterComponent>
|
||||
|
||||
<LifetimeComponent
|
||||
lifetime="260" >
|
||||
</LifetimeComponent>
|
||||
|
||||
</Entity>
|
||||
|
|
@ -25,7 +25,7 @@ local function do_switch_effect(short)
|
|||
return
|
||||
end
|
||||
local x, y = EntityGetTransform(ctx.my_player.entity)
|
||||
rpc.switch_effect(x, y)
|
||||
rpc.switch_effect(x, y, short)
|
||||
if short then
|
||||
LoadGameEffectEntityTo(ctx.my_player.entity, "mods/quant.ew/files/system/local_health/notplayer/safe_effect2.xml")
|
||||
else
|
||||
|
@ -315,8 +315,12 @@ function rpc.send_status(status)
|
|||
end
|
||||
|
||||
rpc.opts_everywhere()
|
||||
function rpc.switch_effect(x, y)
|
||||
EntityLoad("data/entities/particles/image_emitters/magical_symbol_fast.xml", x, y)
|
||||
function rpc.switch_effect(x, y, to_normal_player)
|
||||
if to_normal_player then
|
||||
EntityLoad("mods/quant.ew/files/system/local_health/entities/magical_symbol_player.xml", x, y)
|
||||
else
|
||||
EntityLoad("data/entities/particles/image_emitters/magical_symbol_fast.xml", x, y)
|
||||
end
|
||||
end
|
||||
|
||||
return module
|
10
quant.ew/files/system/notplayer_ai/damage_tracker.lua
Normal file
10
quant.ew/files/system/notplayer_ai/damage_tracker.lua
Normal file
|
@ -0,0 +1,10 @@
|
|||
dofile_once("data/scripts/lib/utilities.lua")
|
||||
|
||||
function damage_received( damage, desc, entity_who_caused, is_fatal )
|
||||
local entity_id = GetUpdatedEntityID()
|
||||
local var = EntityGetFirstComponentIncludingDisabled(entity_id, "VariableStorageComponent", "ew_damage_tracker")
|
||||
if var ~= nil then
|
||||
local dtype = GetDamageDetails().damage_types
|
||||
ComponentSetValue2(var, "value_int", dtype)
|
||||
end
|
||||
end
|
|
@ -221,7 +221,7 @@ local function needs_douse(entity)
|
|||
if damage_model ~= nil then
|
||||
local hp = ComponentGetValue2(damage_model, "hp")
|
||||
local max_hp = ComponentGetValue2(damage_model, "max_hp")
|
||||
if hp / max_hp <= 0.02 then
|
||||
if hp / max_hp <= 0.05 then
|
||||
prot_toxic = true
|
||||
end
|
||||
end
|
||||
|
@ -451,7 +451,17 @@ local function init_state()
|
|||
control_a = false,
|
||||
control_w = false,
|
||||
control_d = false,
|
||||
|
||||
dtype = 0
|
||||
}
|
||||
EntityAddComponent2(ctx.my_player.entity, "LuaComponent", {
|
||||
script_damage_received = "mods/quant.ew/files/system/notplayer_ai/damage_tracker.lua"
|
||||
})
|
||||
EntityAddComponent2(ctx.my_player.entity, "VariableStorageComponent", {
|
||||
_tags = "ew_damage_tracker",
|
||||
name = "ew_damage_tracker",
|
||||
value_int = 0,
|
||||
})
|
||||
end
|
||||
|
||||
local target
|
||||
|
@ -598,6 +608,15 @@ local function choose_movement()
|
|||
give_space = 100
|
||||
end
|
||||
end
|
||||
GamePrint(state.dtype)
|
||||
if state.dtype == 32 then
|
||||
if (dist > 0 and did_hit_2) or (dist < 0 and did_hit_1) then
|
||||
give_space = give_space + 10
|
||||
else
|
||||
swap_side = true
|
||||
end
|
||||
state.control_w = false
|
||||
end
|
||||
end
|
||||
|
||||
local function position_to_area_number(x, y)
|
||||
|
@ -613,7 +632,7 @@ local function position_to_area_number(x, y)
|
|||
elseif y < 12975 and (x < 2726 or x > 4135 or y < 12800) then
|
||||
return 5
|
||||
else
|
||||
return 8
|
||||
return 6
|
||||
end
|
||||
elseif tonumber(SessionNumbersGetValue("NEW_GAME_PLUS_COUNT")) > 0 then
|
||||
if y < 1199 then
|
||||
|
@ -627,7 +646,7 @@ local function position_to_area_number(x, y)
|
|||
elseif y < 12975 and (x < 2726 or x > 4135 or y < 12800) then
|
||||
return 5
|
||||
else
|
||||
return 8
|
||||
return 6
|
||||
end
|
||||
else
|
||||
if y < 1199 then
|
||||
|
@ -1009,6 +1028,11 @@ end
|
|||
local kick_wait = 0
|
||||
|
||||
local function update()
|
||||
local var = EntityGetFirstComponentIncludingDisabled(ctx.my_player.entity, "VariableStorageComponent", "ew_damage_tracker")
|
||||
if GameGetFrameNum() % 30 == 0 then
|
||||
ComponentSetValue2(var, "value_int", 0)
|
||||
end
|
||||
state.dtype = ComponentGetValue2(var, "value_int")
|
||||
-- No taking control back, even after pressing esc.
|
||||
ComponentSetValue2(state.control_component, "enabled", false)
|
||||
|
||||
|
|
|
@ -24,6 +24,21 @@ local iter_slow = 0
|
|||
|
||||
local iter_slow_2 = 0
|
||||
|
||||
local function do_benchmark()
|
||||
local world_ffi = require("noitapatcher.nsew.world_ffi")
|
||||
local grid_world = world_ffi.get_grid_world()
|
||||
local chunk_map = grid_world.vtable.get_chunk_map(grid_world)
|
||||
local start = GameGetRealWorldTimeSinceStarted()
|
||||
local iters = 10000
|
||||
for i=1, iters do
|
||||
world.encode_area(chunk_map, 0, 0, 128, 128, encode_area)
|
||||
-- world_ffi.get_cell(chunk_map, 0, 0)
|
||||
end
|
||||
local end_time = GameGetRealWorldTimeSinceStarted()
|
||||
local elapsed = (end_time - start) * 1000 * 1000 * 1000 / (iters * 128 * 128)
|
||||
print("Benchmark:", elapsed, "ns/pixel")
|
||||
end
|
||||
|
||||
function world_sync.on_world_initialized()
|
||||
local c = 0
|
||||
while true do
|
||||
|
@ -53,14 +68,18 @@ local function send_chunks(cx, cy, chunk_map)
|
|||
end
|
||||
end
|
||||
|
||||
local function get_all_chunks(ocx, ocy, pos_data, priority)
|
||||
local function get_all_chunks(ocx, ocy, pos_data, priority, give_0)
|
||||
local grid_world = world_ffi.get_grid_world()
|
||||
local chunk_map = grid_world.vtable.get_chunk_map(grid_world)
|
||||
--local thread_impl = grid_world.mThreadImpl
|
||||
local int = 4 -- ctx.proxy_opt.world_sync_interval
|
||||
if GameGetFrameNum() % int == 0 then
|
||||
send_chunks(ocx, ocy, chunk_map)
|
||||
net.proxy_bin_send(KEY_WORLD_END, string.char(priority))
|
||||
local pri = priority
|
||||
if give_0 then
|
||||
pri = 0
|
||||
end
|
||||
net.proxy_bin_send(KEY_WORLD_END, string.char(pri))
|
||||
elseif GameGetFrameNum() % int == 2 then
|
||||
if iter_fast == 0 then
|
||||
send_chunks(ocx + 1, ocy, chunk_map)
|
||||
|
@ -163,16 +182,16 @@ function world_sync.on_world_update()
|
|||
local pos_data = ocx..":"..ocy..":"..cx..":"..cy
|
||||
if math.abs(cx - ocx) > 2 or math.abs(cy - ocy) > 2 then
|
||||
if GameGetFrameNum() % 3 ~= 2 then
|
||||
get_all_chunks(cx, cy, pos_data, 16)
|
||||
get_all_chunks(cx, cy, pos_data, 16, false)
|
||||
else
|
||||
get_all_chunks(ocx, ocy, pos_data, 16)
|
||||
get_all_chunks(ocx, ocy, pos_data, 16, true)
|
||||
end
|
||||
else
|
||||
local pri = 0
|
||||
if EntityHasTag(ctx.my_player.entity, "ew_notplayer") then
|
||||
pri = 16
|
||||
end
|
||||
get_all_chunks(ocx, ocy, pos_data, pri)
|
||||
get_all_chunks(ocx, ocy, pos_data, pri, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue