Skip to content

Commit 5a27970

Browse files
committed
probably fix negative hp again, sync chest opens, dont dupe chests, maybe fix crash
1 parent 5816739 commit 5a27970

File tree

18 files changed

+118
-41
lines changed

18 files changed

+118
-41
lines changed

ewext/noita_api/src/lib.rs

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ impl EntityID {
4343
raw::entity_get_name(self).map(|s| s.to_string())
4444
}
4545

46-
pub fn handle_poly(&self) -> Option<Gid> {
46+
pub fn handle_poly(&self) -> eyre::Result<Option<Gid>> {
4747
for ent in self.children(None) {
4848
if let Ok(Some(effect)) =
4949
ent.try_get_first_component_including_disabled::<GameEffectComponent>(None)
5050
{
51-
let name = effect.effect().unwrap();
51+
let name = effect.effect()?;
5252
match name {
5353
GameEffectEnum::Polymorph
5454
| GameEffectEnum::PolymorphRandom
@@ -58,7 +58,7 @@ impl EntityID {
5858
raw::component_get_value::<Cow<str>>(effect.0, "mSerializedData")
5959
{
6060
if data.is_empty() {
61-
return None;
61+
return Ok(None);
6262
}
6363
if let Ok(data) =
6464
base64::engine::general_purpose::STANDARD.decode(data.to_string())
@@ -78,17 +78,17 @@ impl EntityID {
7878
break;
7979
}
8080
}
81-
return Some(Gid(gid.parse::<u64>().ok()?));
81+
return Ok(Some(Gid(gid.parse::<u64>()?)));
8282
}
8383
}
8484
}
85-
return None;
85+
return Ok(None);
8686
}
8787
_ => {}
8888
}
8989
}
9090
}
91-
None
91+
Ok(None)
9292
}
9393

9494
pub fn add_tag(self, tag: impl AsRef<str>) -> eyre::Result<()> {
@@ -108,9 +108,13 @@ impl EntityID {
108108

109109
pub fn kill(self) {
110110
// Shouldn't ever error.
111-
for id in raw::physics_body_id_get_from_entity(self, None).unwrap_or_default() {
112-
let n = 17000.0;
113-
let _ = raw::physics_body_id_set_transform(id, n, n, 0.0, 0.0, 0.0, 0.0);
111+
for (i, id) in raw::physics_body_id_get_from_entity(self, None)
112+
.unwrap_or_default()
113+
.iter()
114+
.enumerate()
115+
{
116+
let n = 17000.0 + (64.0 * (self.0.get() as usize + i) as f64);
117+
let _ = raw::physics_body_id_set_transform(*id, n, n, 0.0, 0.0, 0.0, 0.0);
114118
}
115119
let _ = raw::entity_kill(self);
116120
}
@@ -215,6 +219,11 @@ impl EntityID {
215219
raw::entity_add_component::<C>(self)?.ok_or_eyre("Couldn't create a component")
216220
}
217221

222+
pub fn add_lua_init_component<C: Component>(self, file: &str) -> eyre::Result<C> {
223+
raw::entity_add_lua_init_component::<C>(self, file)?
224+
.ok_or_eyre("Couldn't create a component")
225+
}
226+
218227
pub fn load(
219228
filename: impl AsRef<str>,
220229
pos_x: Option<f64>,
@@ -246,7 +255,7 @@ impl EntityID {
246255
.collect()
247256
}
248257

249-
pub fn get_game_effects(self) -> Vec<(GameEffectData, EntityID)> {
258+
pub fn get_game_effects(self) -> eyre::Result<Vec<(GameEffectData, EntityID)>> {
250259
let mut effects = Vec::new();
251260
let mut name_to_n: HashMap<String, i32> = HashMap::default();
252261
for ent in self.children(None) {
@@ -263,8 +272,7 @@ impl EntityID {
263272
} else if let Ok(Some(effect)) =
264273
ent.try_get_first_component_including_disabled::<GameEffectComponent>(None)
265274
{
266-
let name = effect.effect().unwrap();
267-
275+
let name = effect.effect()?;
268276
match name {
269277
GameEffectEnum::Custom => {
270278
if let Ok(file) = ent.filename() {
@@ -292,9 +300,9 @@ impl EntityID {
292300
}
293301
}
294302
}
295-
effects
303+
Ok(effects)
296304
}
297-
pub fn set_game_effects(self, game_effect: &[GameEffectData]) {
305+
pub fn set_game_effects(self, game_effect: &[GameEffectData]) -> eyre::Result<()> {
298306
fn set_frames(ent: EntityID) -> eyre::Result<()> {
299307
if let Some(effect) =
300308
ent.try_get_first_component_including_disabled::<GameEffectComponent>(None)?
@@ -312,7 +320,7 @@ impl EntityID {
312320
}
313321
Ok(())
314322
}
315-
let local_effects = self.get_game_effects();
323+
let local_effects = self.get_game_effects()?;
316324
for (i, (e1, ent)) in local_effects.iter().enumerate() {
317325
if let GameEffectData::Normal(e1) = e1 {
318326
if *e1 == GameEffectEnum::Polymorph
@@ -330,7 +338,7 @@ impl EntityID {
330338
}
331339
}
332340
}
333-
let local_effects = self.get_game_effects();
341+
let local_effects = self.get_game_effects()?;
334342
for effect in game_effect {
335343
if let Some(ent) =
336344
local_effects
@@ -376,7 +384,7 @@ impl EntityID {
376384
let _ = set_frames(ent);
377385
}
378386
}
379-
let local_effects = self.get_game_effects();
387+
let local_effects = self.get_game_effects()?;
380388
for (effect, ent) in local_effects {
381389
if game_effect.iter().all(|e| *e != effect) {
382390
ent.kill()
@@ -396,6 +404,7 @@ impl EntityID {
396404
let _ = damage.set_m_fire_probability(0);
397405
}
398406
}
407+
Ok(())
399408
}
400409
pub fn add_child(self, child: EntityID) {
401410
let _ = raw::entity_add_child(self.0.get() as i32, child.0.get() as i32);
@@ -623,11 +632,26 @@ pub mod raw {
623632

624633
pub fn entity_add_component<C: Component>(entity: EntityID) -> eyre::Result<Option<C>> {
625634
let lua = LuaState::current()?;
626-
lua.get_global(c"EntityAddComponent");
635+
lua.get_global(c"EntityAddComponent2");
627636
lua.push_integer(entity.raw());
628637
lua.push_string(C::NAME_STR);
629638
lua.call(2, 1)
630-
.wrap_err("Failed to call EntityAddComponent")?;
639+
.wrap_err("Failed to call EntityAddComponent2")?;
640+
let c = lua.to_integer(-1);
641+
lua.pop_last_n(1);
642+
Ok(NonZero::new(c).map(ComponentID).map(C::from))
643+
}
644+
645+
pub fn entity_add_lua_init_component<C: Component>(
646+
entity: EntityID,
647+
file: &str,
648+
) -> eyre::Result<Option<C>> {
649+
let lua = LuaState::current()?;
650+
lua.get_global(c"EwextAddInitLuaComponent");
651+
lua.push_integer(entity.raw());
652+
lua.push_string(file);
653+
lua.call(2, 1)
654+
.wrap_err("Failed to call EntityAddComponent2")?;
631655
let c = lua.to_integer(-1);
632656
lua.pop_last_n(1);
633657
Ok(NonZero::new(c).map(ComponentID).map(C::from))

ewext/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use noita_api::{
1818
use noita_api_macro::add_lua_fn;
1919
use rustc_hash::{FxHashMap, FxHashSet};
2020
use shared::des::Gid;
21-
use shared::{NoitaInbound, PeerId, ProxyKV};
21+
use shared::{des, NoitaInbound, NoitaOutbound, PeerId, ProxyKV};
2222
use std::num::NonZero;
2323
use std::{
2424
arch::asm,
@@ -184,7 +184,9 @@ fn netmanager_recv(_lua: LuaState) -> eyre::Result<Option<RawString>> {
184184
NoitaInbound::ProxyToDes(proxy_to_des) => ExtState::with_global(|state| {
185185
let _lock = IN_MODULE_LOCK.lock().unwrap();
186186
if let Some(entity_sync) = &mut state.modules.entity_sync {
187-
entity_sync.handle_proxytodes(proxy_to_des);
187+
if let Ok(Some(gid)) = entity_sync.handle_proxytodes(proxy_to_des) {
188+
state.dont_spawn.insert(gid);
189+
}
188190
}
189191
})?,
190192
NoitaInbound::RemoteMessage {
@@ -575,6 +577,9 @@ pub unsafe extern "C" fn luaopen_ewext0(lua: *mut lua_State) -> c_int {
575577
.ok_or_eyre("No entity sync module loaded")?;
576578
if let Some(gid) = entity_sync.register_chest(entity)? {
577579
state.dont_spawn.insert(gid);
580+
let mut temp = NETMANAGER.lock().unwrap();
581+
let net = temp.as_mut().ok_or_eyre("Netmanager not available")?;
582+
net.send(&NoitaOutbound::DesToProxy(des::DesToProxy::ChestOpen(gid)))?;
578583
}
579584
Ok(())
580585
})?

ewext/src/modules/entity_sync.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use diff_model::{entity_is_item, LocalDiffModel, RemoteDiffModel, DES_TAG};
1111
use eyre::{Context, OptionExt};
1212
use interest::InterestTracker;
1313
use noita_api::serialize::serialize_entity;
14-
use noita_api::{EntityID, ProjectileComponent, VariableStorageComponent};
14+
use noita_api::{EntityID, LuaComponent, ProjectileComponent, VariableStorageComponent};
1515
use rustc_hash::{FxHashMap, FxHashSet};
1616
use shared::{
1717
des::{
@@ -158,7 +158,7 @@ impl EntitySync {
158158
if !entity.is_alive() || self.dont_track.remove(&entity) {
159159
continue;
160160
}
161-
if let Some(gid) = entity.handle_poly() {
161+
if let Ok(Some(gid)) = entity.handle_poly() {
162162
self.dont_kill_by_gid.insert(gid);
163163
}
164164
if entity.has_tag(DES_TAG)
@@ -169,7 +169,7 @@ impl EntitySync {
169169
)?
170170
.find(|var| var.name().unwrap_or("".into()) == "ew_gid_lid")
171171
.map(|var| {
172-
if let Ok(n) = var.value_string().unwrap().parse::<u64>() {
172+
if let Ok(n) = var.value_string().unwrap_or("NA".into()).parse::<u64>() {
173173
!self.dont_kill_by_gid.remove(&Gid(n))
174174
} else {
175175
true
@@ -191,7 +191,10 @@ impl EntitySync {
191191
Ok(())
192192
}
193193

194-
pub(crate) fn handle_proxytodes(&mut self, proxy_to_des: shared::des::ProxyToDes) {
194+
pub(crate) fn handle_proxytodes(
195+
&mut self,
196+
proxy_to_des: shared::des::ProxyToDes,
197+
) -> eyre::Result<Option<Gid>> {
195198
match proxy_to_des {
196199
shared::des::ProxyToDes::GotAuthority(full_entity_data) => {
197200
self.local_diff_model.got_authority(full_entity_data);
@@ -204,7 +207,24 @@ impl EntitySync {
204207
shared::des::ProxyToDes::DeleteEntity(entity) => {
205208
EntityID(entity).kill();
206209
}
210+
shared::des::ProxyToDes::TriggerChest(gid) => {
211+
if let Some(ent) = self.find_by_gid(gid) {
212+
if let Some(file) = ent
213+
.iter_all_components_of_type_including_disabled::<LuaComponent>(None)?
214+
.find(|l| {
215+
!l.script_physics_body_modified()
216+
.unwrap_or("".into())
217+
.is_empty()
218+
})
219+
.map(|l| l.script_physics_body_modified().unwrap_or("".into()))
220+
{
221+
ent.add_lua_init_component::<LuaComponent>(&file)?;
222+
}
223+
}
224+
return Ok(Some(gid));
225+
}
207226
}
227+
Ok(None)
208228
}
209229

210230
pub(crate) fn handle_remotedes(&mut self, source: PeerId, remote_des: RemoteDes) {

ewext/src/modules/entity_sync/diff_model.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ impl LocalDiffModelTracker {
292292
}
293293

294294
info.game_effects = entity
295-
.get_game_effects()
295+
.get_game_effects()?
296296
.iter()
297297
.map(|(e, _)| e.clone())
298298
.collect::<Vec<GameEffectData>>();
@@ -1221,7 +1221,7 @@ impl RemoteDiffModel {
12211221
cost.set_cost(entity_info.cost)?;
12221222
}
12231223

1224-
entity.set_game_effects(&entity_info.game_effects);
1224+
entity.set_game_effects(&entity_info.game_effects)?;
12251225

12261226
entity.set_current_stains(entity_info.current_stains)?;
12271227

@@ -1356,7 +1356,7 @@ impl RemoteDiffModel {
13561356
if let Some(damage) = entity.try_get_first_component::<DamageModelComponent>(None)? {
13571357
damage.set_wait_for_kill_flag_on_death(false)?;
13581358
damage.set_ui_report_damage(false)?;
1359-
damage.set_hp(f64::MIN_POSITIVE)?;
1359+
damage.set_hp(f32::MIN_POSITIVE as f64)?;
13601360
noita_api::raw::entity_inflict_damage(
13611361
entity.raw() as i32,
13621362
damage.hp()? + 0.1,

noita-proxy/src/net.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@ impl NetManager {
429429
self.send(dest, &NetMsg::ForwardProxyToDes(msg), Reliability::Reliable);
430430
}
431431

432+
let des_broadcasts = state.des.pending_broadcasts();
433+
for msg in des_broadcasts {
434+
self.broadcast(&NetMsg::ForwardProxyToDes(msg), Reliability::Reliable);
435+
}
436+
432437
// Don't do excessive busy-waiting;
433438
let min_update_time = Duration::from_millis(1);
434439
let elapsed = last_iter.elapsed();

noita-proxy/src/net/des.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub(crate) struct DesManager {
2525
rtree: RTree<GeomWithData<[i64; 2], Gid>>,
2626
authority: FxHashMap<Gid, OmniPeerId>,
2727
pending_messages: Vec<(OmniPeerId, ProxyToDes)>,
28+
pending_broadcasts: Vec<ProxyToDes>,
2829
save_state: SaveState,
2930
}
3031

@@ -47,6 +48,7 @@ impl DesManager {
4748
rtree,
4849
authority: Default::default(),
4950
pending_messages: Vec::new(),
51+
pending_broadcasts: Vec::new(),
5052
save_state,
5153
is_host,
5254
}
@@ -85,6 +87,9 @@ impl DesManager {
8587
.push((source, ProxyToDes::DeleteEntity(ent)));
8688
}
8789
}
90+
DesToProxy::ChestOpen(gid) => {
91+
self.pending_broadcasts.push(ProxyToDes::TriggerChest(gid));
92+
}
8893
DesToProxy::ReleaseAuthority(gid) => {
8994
self.authority.remove(&gid);
9095
self.add_gid_to_tree(gid);
@@ -149,6 +154,10 @@ impl DesManager {
149154
mem::take(&mut self.pending_messages)
150155
}
151156

157+
pub(crate) fn pending_broadcasts(&mut self) -> Vec<ProxyToDes> {
158+
mem::take(&mut self.pending_broadcasts)
159+
}
160+
152161
pub(crate) fn reset(&mut self) {
153162
self.entity_storage = Default::default();
154163
self.rtree = RTree::default();

quant.ew/files/core/net_handling.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ function net_handling.proxy.end_run(_, _)
209209
local damage = ComponentGetValue2(entity, "DamageModelComponent")
210210
if damage ~= nil then
211211
ComponentSetValue2(damage, "ui_report_damage", false)
212-
ComponentSetValue2(damage, "hp", 2 ^ -128)
212+
ComponentSetValue2(damage, "hp", 2 ^ -38)
213213
end
214214
if entity ~= nil and EntityGetIsAlive(entity) and not EntityHasTag(entity, "ew_notplayer") then
215215
EntityInflictDamage(entity, 1000000, "DAMAGE_CURSE", "Run Ended", "NONE", 0, 0, GameGetWorldStateEntity())

quant.ew/files/resource/cbs/immortal.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ function damage_about_to_be_received(damage, x, y, entity_thats_responsible, cri
99
end
1010

1111
if entity_thats_responsible ~= GameGetWorldStateEntity() then
12-
return 2 ^ -128, 0
12+
return 2 ^ -38, 0
1313
end
1414

1515
if damage < 0 then
16-
return -2 ^ -128, 0
16+
return -2 ^ -38, 0
1717
end
1818

1919
return damage, 0

quant.ew/files/system/damage/damage.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ local function do_game_over(message)
4545
if damage_model ~= nil then
4646
ComponentSetValue2(damage_model, "wait_for_kill_flag_on_death", false)
4747
ComponentSetValue2(damage_model, "ui_report_damage", false)
48-
ComponentSetValue2(damage_model, "hp", 2 ^ -128)
48+
ComponentSetValue2(damage_model, "hp", 2 ^ -38)
4949
end
5050
EntityInflictDamage(ctx.my_player.entity, 1000000, "DAMAGE_CURSE", message, "NONE", 0, 0, GameGetWorldStateEntity())
5151
GameTriggerGameOver()

quant.ew/files/system/end_fight/end_fight.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ function end_fight.on_world_update()
168168
local damage = ComponentGetValue2(ctx.my_player.entity, "DamageModelComponent")
169169
if damage ~= nil then
170170
ComponentSetValue2(damage, "ui_report_damage", false)
171-
ComponentSetValue2(damage, "hp", 2 ^ -128)
171+
ComponentSetValue2(damage, "hp", 2 ^ -38)
172172
end
173173
EntityInflictDamage(
174174
ctx.my_player.entity,
@@ -189,7 +189,7 @@ function end_fight.on_world_update()
189189
local damage = ComponentGetValue2(ctx.my_player.entity, "DamageModelComponent")
190190
if damage ~= nil then
191191
ComponentSetValue2(damage, "ui_report_damage", false)
192-
ComponentSetValue2(damage, "hp", 2 ^ -128)
192+
ComponentSetValue2(damage, "hp", 2 ^ -38)
193193
end
194194
EntityInflictDamage(
195195
ctx.my_player.entity,

quant.ew/files/system/ending/ending.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function rpc.gather_and_do_ending(x, y, sx, sy)
3131
local damage = ComponentGetValue2(ctx.my_player.entity, "DamageModelComponent")
3232
if damage ~= nil then
3333
ComponentSetValue2(damage, "ui_report_damage", false)
34-
ComponentSetValue2(damage, "hp", 2 ^ -128)
34+
ComponentSetValue2(damage, "hp", 2 ^ -38)
3535
end
3636
EntityInflictDamage(
3737
ctx.my_player.entity,

0 commit comments

Comments
 (0)