Higher level component stuff

This commit is contained in:
IQuant 2024-11-25 21:21:18 +03:00
parent 61035d8b0c
commit 0f26126ad9
4 changed files with 43 additions and 9 deletions

View file

@ -1,4 +1,6 @@
use std::num::NonZero;
use std::{borrow::Cow, num::NonZero};
use eyre::{eyre, Context};
pub mod lua;
@ -12,10 +14,30 @@ pub struct Obj(pub usize);
pub struct Color(pub u32);
pub trait Component: From<ComponentID> {
const NAME_STR: &'static str;
}
noita_api_macro::generate_components!();
impl EntityID {
pub fn try_get_first_component<C: Component>(
self,
tag: Option<Cow<'_, str>>,
) -> eyre::Result<Option<C>> {
raw::entity_get_first_component(self, C::NAME_STR.into(), tag)
.map(|x| x.map(Into::into))
.wrap_err_with(|| eyre!("Failed to get first component {} for {self:?}", C::NAME_STR))
}
pub fn get_first_component<C: Component>(self, tag: Option<Cow<'_, str>>) -> eyre::Result<C> {
self.try_get_first_component(tag)?
.ok_or_else(|| eyre!("Entity {self:?} has no component {}", C::NAME_STR))
}
}
pub mod raw {
use eyre::Ok;
use eyre::eyre;
use eyre::Context;
use super::{Color, ComponentID, EntityID, Obj};
use crate::lua::LuaGetValue;
@ -37,7 +59,7 @@ pub mod raw {
lua.call(2, T::size_on_stack());
let ret = T::get(lua, -1);
lua.pop_last_n(T::size_on_stack());
ret
ret.wrap_err_with(|| eyre!("Getting {field} for {component:?}"))
}
pub(crate) fn component_set_value<T>(

View file

@ -68,7 +68,7 @@ impl LuaState {
let slice = unsafe { slice::from_raw_parts(buf as *const u8, size) };
Ok(String::from_utf8(slice.to_owned())
.context("Attempting to get lua string, expecting it to be utf-8")?)
.wrap_err("Attempting to get lua string, expecting it to be utf-8")?)
}
pub fn to_cfunction(&self, index: i32) -> lua_CFunction {

View file

@ -164,10 +164,22 @@ fn generate_code_for_component(com: Component) -> proc_macro2::TokenStream {
}
});
let com_name = com.name;
quote! {
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct #component_name(pub ComponentID);
impl Component for #component_name {
const NAME_STR: &'static str = #com_name;
}
impl From<ComponentID> for #component_name {
fn from(com: ComponentID) -> Self {
#component_name(com)
}
}
impl #component_name {
#(#impls)*
}

View file

@ -9,7 +9,10 @@ use addr_grabber::{grab_addrs, grabbed_fns, grabbed_globals};
use eyre::{bail, OptionExt};
use noita::{ntypes::Entity, pixel::NoitaPixelRun, ParticleWorldState};
use noita_api::lua::{lua_bindings::lua_State, LuaState, ValuesOnStack, LUA};
use noita_api::{
lua::{lua_bindings::lua_State, LuaState, ValuesOnStack, LUA},
DamageModelComponent,
};
use noita_api_macro::add_lua_fn;
pub mod noita;
@ -116,10 +119,7 @@ fn bench_fn(_lua: LuaState) -> eyre::Result<()> {
fn test_fn(_lua: LuaState) -> eyre::Result<()> {
let player = noita_api::raw::entity_get_closest_with_tag(0.0, 0.0, "player_unit".into())?
.ok_or_eyre("Entity not found")?;
let damage_model = noita_api::DamageModelComponent(
noita_api::raw::entity_get_first_component(player, "DamageModelComponent".into(), None)?
.ok_or_eyre("Could not find damage model")?,
);
let damage_model: DamageModelComponent = player.get_first_component(None)?;
let hp = damage_model.hp()?;
damage_model.set_hp(hp - 1.0)?;