diff --git a/ewext/noita_api/src/lib.rs b/ewext/noita_api/src/lib.rs index 616ffd64..2c8dacdc 100644 --- a/ewext/noita_api/src/lib.rs +++ b/ewext/noita_api/src/lib.rs @@ -219,6 +219,12 @@ impl EntityID { raw::entity_add_component::(self)?.ok_or_eyre("Couldn't create a component") } + pub fn get_var(self, name: &str) -> Option { + self.iter_all_components_of_type_including_disabled::(None) + .map(|mut i| i.find(|var| var.name().unwrap_or("".into()) == name)) + .unwrap_or(None) + } + pub fn add_lua_init_component(self, file: &str) -> eyre::Result { raw::entity_add_lua_init_component::(self, file)? .ok_or_eyre("Couldn't create a component") diff --git a/ewext/src/lib.rs b/ewext/src/lib.rs index b392e5e2..aeba347f 100644 --- a/ewext/src/lib.rs +++ b/ewext/src/lib.rs @@ -426,7 +426,7 @@ pub unsafe extern "C" fn luaopen_ewext0(lua: *mut lua_State) -> c_int { let entity = lua.to_string(1)?.parse::()?; let peer = PeerId::from_hex(&lua.to_string(2)?)?; let mut rng: u64 = - u32::from_ne_bytes(lua.to_string(3)?.parse::()?.to_ne_bytes()) as u64; + u32::from_le_bytes(lua.to_string(3)?.parse::()?.to_le_bytes()) as u64; if rng == 0 { rng = 1; } diff --git a/ewext/src/modules/entity_sync/diff_model.rs b/ewext/src/modules/entity_sync/diff_model.rs index 759d6737..a8a5d96d 100644 --- a/ewext/src/modules/entity_sync/diff_model.rs +++ b/ewext/src/modules/entity_sync/diff_model.rs @@ -298,7 +298,34 @@ impl LocalDiffModelTracker { .map(|(e, _)| e.clone()) .collect::>(); - info.current_stains = entity.get_current_stains()?; + let filename = entity.filename()?; + info.current_stains = if [ + "data/entities/items/pickup/physics_die.xml", + "data/entities/items/pickup/physics_die_greed.xml", + ] + .contains(&&*filename) + { + if entity + .get_var("rolling") + .map(|v| v.value_int().unwrap_or(0) < 8) + .unwrap_or(false) + && entity + .try_get_first_component::(Some("enable_in_world".into()))? + .map(|s| s.rect_animation().unwrap_or("".into()) == "roll") + .unwrap_or(false) + { + let rng = rand::random::(); + let var = entity.add_component::()?; + var.set_name("ew_rng".into())?; + var.set_value_int(rng)?; + let bytes = rng.to_le_bytes(); + u64::from_le_bytes([0, 0, 0, 0, bytes[0], bytes[1], bytes[2], bytes[3]]) + } else { + info.current_stains + } + } else { + entity.get_current_stains()? + }; let mut any = false; for ai in @@ -485,7 +512,7 @@ impl LocalDiffModel { let var = entity.add_component::()?; var.set_name("ew_gid_lid".into())?; var.set_value_string(gid.0.to_string().into())?; - var.set_value_int(i32::from_ne_bytes(lid.0.to_ne_bytes()))?; + var.set_value_int(i32::from_le_bytes(lid.0.to_le_bytes()))?; var.set_value_bool(true)?; if entity @@ -507,7 +534,10 @@ impl LocalDiffModel { let drops_gold = entity .iter_all_components_of_type::(None)? - .any(|lua| lua.script_death().ok() == Some("data/scripts/items/drop_money.lua".into())); + .any(|lua| lua.script_death().ok() == Some("data/scripts/items/drop_money.lua".into())) + && entity + .iter_all_components_of_type::(None)? + .all(|var| !var.has_tag("no_gold_drop")); self.entity_entries.insert( lid, @@ -1245,8 +1275,24 @@ impl RemoteDiffModel { entity.set_game_effects(&entity_info.game_effects)?; - entity.set_current_stains(entity_info.current_stains)?; - + let filename = entity.filename()?; + if [ + "data/entities/items/pickup/physics_die.xml", + "data/entities/items/pickup/physics_die_greed.xml", + ] + .contains(&&*filename) + { + if entity.iter_all_components_of_type_including_disabled::(None)?.all(|var| var.name().unwrap_or("".into()) != "ew_rng") { + let var = entity.add_component::()?; + var.set_name("ew_rng".into())?; + let bytes = entity_info.current_stains.to_le_bytes(); + let bytes: [u8; 4] = [bytes[4], bytes[5], bytes[6], bytes[7]]; + let rng = i32::from_le_bytes(bytes); + var.set_value_int(rng)?; + } + } else { + entity.set_current_stains(entity_info.current_stains)?; + } if let Some(ai) = entity .try_get_first_component_including_disabled::(None)? { @@ -1587,7 +1633,7 @@ pub fn init_remote_entity( if let Some(gid) = gid { var.set_value_string(gid.0.to_string().into())?; } - var.set_value_int(i32::from_ne_bytes(lid.0.to_ne_bytes()))?; + var.set_value_int(i32::from_le_bytes(lid.0.to_le_bytes()))?; var.set_value_bool(false)?; } Ok(()) diff --git a/quant.ew/files/core/util.lua b/quant.ew/files/core/util.lua index de190ed5..dcff4137 100644 --- a/quant.ew/files/core/util.lua +++ b/quant.ew/files/core/util.lua @@ -35,6 +35,18 @@ function util.print_error(error) print("---err end---") end +function util.prepend(file, target, text) + local content = ModTextFileGetContent(file) + local first, last = content:find(target, 0, true) + if not first then + return + end + local before = content:sub(1, first - 1) + local after = content:sub(last + 1) + local new = before .. text .. after + ModTextFileSetContent(file, new) +end + function util.tpcall(fn, ...) local res = { xpcall(fn, debug.traceback, ...) } if not res[1] then diff --git a/quant.ew/files/system/dice/dice.lua b/quant.ew/files/system/dice/dice.lua new file mode 100644 index 00000000..28ddfffb --- /dev/null +++ b/quant.ew/files/system/dice/dice.lua @@ -0,0 +1,17 @@ +util.prepend( + "data/scripts/items/greed_die_status.lua", + "SetRandomSeed( GameGetFrameNum(), pos_x + pos_y + entity_id )", + 'local function get_num() if get_variable_storage_component(entity_id, "ew_rng") then return ComponentGetValue2(get_variable_storage_component(entity_id, "ew_rng"), "value_int") else return 0 end end SetRandomSeed(get_num(), 0)' +) +util.prepend( + "data/scripts/items/die_status.lua", + "SetRandomSeed( GameGetFrameNum(), pos_x + pos_y + entity_id )", + 'local function get_num() if get_variable_storage_component(entity_id, "ew_rng") then return ComponentGetValue2(get_variable_storage_component(entity_id, "ew_rng"), "value_int") else return 0 end end SetRandomSeed(get_num(), 0)' +) +util.prepend( + "data/scripts/items/die_status.lua", + 'bullet_circle( "fungus", 8, 300 )', + 'if CrossCall("ew_do_i_own", entity_id) then bullet_circle("fungus", 8, 300) end' +) + +return {} diff --git a/quant.ew/init.lua b/quant.ew/init.lua index 201f5579..847a4d70 100755 --- a/quant.ew/init.lua +++ b/quant.ew/init.lua @@ -142,6 +142,7 @@ local function load_modules() ctx.load_system("wang_hooks") ctx.load_system("entity_sync_helper") ctx.load_system("telekenisis") + ctx.load_system("dice") end local function load_extra_modules() @@ -506,7 +507,12 @@ local function on_world_pre_update_inner() end 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 or cross_force_send_inventory then + if + ctx.events.new_player_just_connected + or ctx.events.inventory_maybe_just_changed + or sha_check + or cross_force_send_inventory + then cross_force_send_inventory = false local inventory_state, spells = player_fns.serialize_items(ctx.my_player) if inventory_state ~= nil then