From 07dec1a025c5b8b51b74d17b77e6a672d74b0f27 Mon Sep 17 00:00:00 2001 From: bgkillas Date: Mon, 23 Jun 2025 22:23:33 -0400 Subject: [PATCH] use less noita_api::raw hooks in ewext --- ewext/noita_api/src/lib.rs | 69 ++++++++++++++++ ewext/src/modules/entity_sync.rs | 34 ++++---- ewext/src/modules/entity_sync/diff_model.rs | 89 ++++++++------------- 3 files changed, 119 insertions(+), 73 deletions(-) diff --git a/ewext/noita_api/src/lib.rs b/ewext/noita_api/src/lib.rs index 44f66027..1ef2fa8f 100644 --- a/ewext/noita_api/src/lib.rs +++ b/ewext/noita_api/src/lib.rs @@ -118,6 +118,22 @@ impl EntityID { Ok(true) } + pub fn get_physics_body_ids(self) -> eyre::Result> { + raw::physics_body_id_get_from_entity(self, None) + } + + pub fn set_static(self, is_static: bool) -> eyre::Result<()> { + raw::physics_set_static(self, is_static) + } + + pub fn create(name: Option>) -> eyre::Result { + match raw::entity_create_new(name) { + Ok(Some(n)) => Ok(n), + Err(s) => Err(s), + _ => Err(eyre!("ent not found")), + } + } + pub fn kill(self) { // Shouldn't ever error. if self.is_alive() @@ -546,6 +562,59 @@ impl EntityID { pub fn remove_component(self, component_id: ComponentID) -> eyre::Result<()> { raw::entity_remove_component(self, component_id) } + pub fn shoot_projectile( + self, + pos_x: f64, + pos_y: f64, + target_x: f64, + target_y: f64, + proj: EntityID, + ) -> eyre::Result<()> { + raw::game_shoot_projectile( + self.raw() as i32, + pos_x, + pos_y, + target_x, + target_y, + proj.raw() as i32, + None, + None, + ) + } + pub fn get_hotspot(self, hotspot: &str) -> eyre::Result<(f64, f64)> { + raw::entity_get_hotspot(self.raw() as i32, hotspot.into(), true, None) + } + pub fn get_closest_with_tag(x: f64, y: f64, tag: &str) -> eyre::Result { + match raw::entity_get_closest_with_tag(x, y, tag.into()) { + Ok(Some(n)) => Ok(n), + Err(s) => Err(s), + _ => Err(eyre!("ent not found")), + } + } + pub fn get_in_radius_with_tag( + x: f64, + y: f64, + r: f64, + tag: &str, + ) -> eyre::Result>> { + raw::entity_get_in_radius_with_tag(x, y, r, tag.into()) + } +} +impl PhysicsBodyID { + pub fn set_transform( + self, + x: f64, + y: f64, + r: f64, + vx: f64, + vy: f64, + av: f64, + ) -> eyre::Result<()> { + raw::physics_body_id_set_transform(self, x, y, r, vx, vy, av) + } + pub fn get_transform(self) -> eyre::Result> { + raw::physics_body_id_get_transform(self) + } } pub enum DamageType { diff --git a/ewext/src/modules/entity_sync.rs b/ewext/src/modules/entity_sync.rs index 9faaa4f2..8740406b 100644 --- a/ewext/src/modules/entity_sync.rs +++ b/ewext/src/modules/entity_sync.rs @@ -170,9 +170,12 @@ impl EntitySync { } Ok(()) } - pub(crate) fn spawn_once(&mut self, ctx: &mut super::ModuleCtx) -> eyre::Result<()> { + pub(crate) fn spawn_once( + &mut self, + ctx: &mut super::ModuleCtx, + frame_num: usize, + ) -> eyre::Result<()> { let (x, y) = noita_api::raw::game_get_camera_pos()?; - let frame_num = game_get_frame_num()? as usize; let len = self.spawn_once.len(); if len > 0 { let batch_size = (len / 20).max(1); @@ -187,9 +190,7 @@ impl EntitySync { let (x, y) = (pos.x as f64, pos.y as f64); match data { shared::SpawnOnce::Enemy(file, drops_gold, offending_peer) => { - if let Ok(Some(entity)) = - noita_api::raw::entity_load(file.into(), Some(x), Some(y)) - { + if let Ok(entity) = EntityID::load(file, Some(x), Some(y)) { entity.add_tag("ew_no_enemy_sync")?; diff_model::init_remote_entity( entity, @@ -242,9 +243,7 @@ impl EntitySync { } } shared::SpawnOnce::Chest(file, rx, ry) => { - if let Ok(Some(ent)) = - noita_api::raw::entity_load(file.into(), Some(x), Some(y)) - { + if let Ok(ent) = EntityID::load(file, Some(x), Some(y)) { ent.add_tag("ew_no_enemy_sync")?; if let Some(file) = ent .iter_all_components_of_type_including_disabled::( @@ -266,13 +265,12 @@ impl EntitySync { } } shared::SpawnOnce::BrokenWand => { - if let Some(ent) = noita_api::raw::entity_create_new(None)? { - ent.set_position(x as f32, y as f32, None)?; - ent.add_tag("broken_wand")?; - ent.add_lua_init_component::( - "data/scripts/buildings/forge_item_convert.lua", - )?; - } + let ent = EntityID::create(None)?; + ent.set_position(x as f32, y as f32, None)?; + ent.add_tag("broken_wand")?; + ent.add_lua_init_component::( + "data/scripts/buildings/forge_item_convert.lua", + )?; } } self.spawn_once.remove(i); @@ -358,9 +356,7 @@ impl EntitySync { if let Some(ent) = self.find_by_gid(gid) { ent.kill() } - if let Ok(Some(ent)) = - noita_api::raw::entity_load(file.into(), Some(x as f64), Some(y as f64)) - { + if let Ok(ent) = EntityID::load(file, Some(x as f64), Some(y as f64)) { ent.add_tag("ew_no_enemy_sync")?; if let Some(file) = ent .iter_all_components_of_type_including_disabled::(None)? @@ -769,7 +765,7 @@ impl Module for EntitySync { } } } - if let Err(s) = self.spawn_once(ctx) { + if let Err(s) = self.spawn_once(ctx, frame_num) { crate::print_error(s)?; } diff --git a/ewext/src/modules/entity_sync/diff_model.rs b/ewext/src/modules/entity_sync/diff_model.rs index 6e1d95c9..6abfda9d 100644 --- a/ewext/src/modules/entity_sync/diff_model.rs +++ b/ewext/src/modules/entity_sync/diff_model.rs @@ -1,8 +1,8 @@ use super::NetManager; use crate::{ephemerial, modules::ModuleCtx, my_peer_id, print_error}; use bimap::BiHashMap; -use eyre::{Context, ContextCompat, OptionExt, eyre}; -use noita_api::raw::{entity_create_new, game_get_frame_num, raytrace_platforms}; +use eyre::{Context, OptionExt, eyre}; +use noita_api::raw::{game_get_frame_num, raytrace_platforms}; use noita_api::serialize::{deserialize_entity, serialize_entity}; use noita_api::{ AIAttackComponent, AbilityComponent, AdvancedFishAIComponent, AnimalAIComponent, @@ -849,8 +849,7 @@ impl LocalDiffModel { let lid = self.alloc_lid(); let should_not_serialize = entity_manager .remove_all_components_of_type::(ComponentTag::None)? - || (entity.is_alive() && entity_manager.check_all_phys_init()? && noita_api::raw::physics_body_id_get_from_entity(entity, None) - .unwrap_or_default() + || (entity.is_alive() && entity_manager.check_all_phys_init()? && entity.get_physics_body_ids().unwrap_or_default() .len() == entity_manager .iter_all_components_of_type_including_disabled::(ComponentTag::None)? @@ -1017,16 +1016,14 @@ impl LocalDiffModel { for (entity, phys) in self.phys_later.drain(..) { entity_manager.set_current_entity(entity)?; if entity.is_alive() && entity_manager.check_all_phys_init()? { - let phys_bodies = noita_api::raw::physics_body_id_get_from_entity(entity, None) - .unwrap_or_default(); + let phys_bodies = entity.get_physics_body_ids().unwrap_or_default(); for (p, physics_body_id) in phys.iter().zip(phys_bodies.iter()) { let Some(p) = p else { continue; }; let (x, y) = noita_api::raw::game_pos_to_physics_pos(p.x.into(), Some(p.y.into()))?; - noita_api::raw::physics_body_id_set_transform( - *physics_body_id, + physics_body_id.set_transform( x, y, p.angle.into(), @@ -1056,7 +1053,7 @@ impl LocalDiffModel { .children(Some("protection".into())) .for_each(|ent| ent.kill()); entity_manager.add_tag(const { CachedTag::from_tag("boss_centipede_active") })?; - noita_api::raw::physics_set_static(entity, false)?; + entity.set_static(false)? } } Ok(()) @@ -1527,34 +1524,30 @@ impl LocalDiffModel { fn collect_phys_info(entity: EntityID) -> eyre::Result>> { if entity.is_alive() { - let phys_bodies = - noita_api::raw::physics_body_id_get_from_entity(entity, None).unwrap_or_default(); + let phys_bodies = entity.get_physics_body_ids().unwrap_or_default(); phys_bodies .into_iter() .map(|body| -> eyre::Result> { - Ok( - noita_api::raw::physics_body_id_get_transform(body)?.and_then(|data| { - let PhysData { - x, - y, - angle, - vx, - vy, - av, - } = data; - let (x, y) = - noita_api::raw::physics_pos_to_game_pos(x.into(), Some(y.into())) - .ok()?; - Some(PhysBodyInfo { - x: x as f32, - y: y as f32, - angle, - vx, - vy, - av, - }) - }), - ) + Ok(body.get_transform()?.and_then(|data| { + let PhysData { + x, + y, + angle, + vx, + vy, + av, + } = data; + let (x, y) = + noita_api::raw::physics_pos_to_game_pos(x.into(), Some(y.into())).ok()?; + Some(PhysBodyInfo { + x: x as f32, + y: y as f32, + angle, + vx, + vy, + av, + }) + })) }) .collect::>>() } else { @@ -1876,15 +1869,13 @@ impl RemoteDiffModel { } if !entity_info.phys.is_empty() && entity_manager.check_all_phys_init()? { - let phys_bodies = - noita_api::raw::physics_body_id_get_from_entity(entity, None).unwrap_or_default(); + let phys_bodies = entity.get_physics_body_ids().unwrap_or_default(); for (p, physics_body_id) in entity_info.phys.iter().zip(phys_bodies.iter()) { let Some(p) = p else { continue; }; let (x, y) = noita_api::raw::game_pos_to_physics_pos(p.x.into(), Some(p.y.into()))?; - noita_api::raw::physics_body_id_set_transform( - *physics_body_id, + physics_body_id.set_transform( x, y, p.angle.into(), @@ -1930,13 +1921,8 @@ impl RemoteDiffModel { }) } else if var.value_int()? == 8 { let (x, y) = entity.position()?; - if !noita_api::raw::entity_get_in_radius_with_tag( - x as f64, - y as f64, - 480.0, - "player_unit".into(), - )? - .is_empty() + if !EntityID::get_in_radius_with_tag(x as f64, y as f64, 480.0, "player_unit")? + .is_empty() { game_print("$item_die_roll"); } @@ -2211,15 +2197,12 @@ impl RemoteDiffModel { continue; }; - let _ = noita_api::raw::game_shoot_projectile( - shooter_entity.raw() as i32, + let _ = shooter_entity.shoot_projectile( projectile.position.0 as f64, projectile.position.1 as f64, projectile.target.0 as f64, projectile.target.1 as f64, - deserialized.raw() as i32, - None, - None, + deserialized, ); if let Ok(Some(vel)) = deserialized.try_get_first_component::(None) { if let Some((vx, vy)) = projectile.vel { @@ -2669,8 +2652,7 @@ fn give_wand( wand.kill() } if let Some(r) = r { - let (x, y) = - noita_api::raw::entity_get_hotspot(entity.raw() as i32, "hand".into(), true, None)?; + let (x, y) = entity.get_hotspot("hand")?; wand.set_position(x as f32, y as f32, Some(r))?; } } @@ -2698,8 +2680,7 @@ fn give_wand( }) { quick } else { - let quick = - entity_create_new(Some("inventory_quick".into()))?.wrap_err("unreachable")?; + let quick = EntityID::create(Some("inventory_quick".into()))?; entity.add_child(quick); quick };