Skip to content

Commit

Permalink
Fix sprite owner array not being rebuilt on save loads
Browse files Browse the repository at this point in the history
While other sprite owner updating code caught most of the cases,
hidden units would lose their sprite owner on load. (Especially
when loading fresh from startup)
  • Loading branch information
neivv committed Oct 8, 2020
1 parent b7e8c4e commit 8846d32
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/bw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ pub fn give_ai(unit: bw_dat::Unit) {
unsafe { samase::give_ai(*unit) }
}

pub fn unit_array() -> (*mut Unit, usize) {
unsafe { samase::unit_array() }
}

whack_hooks!(stdcall, 0x00400000,
0x00488AF0 => increment_death_scores(@edi *mut Unit, @edx u8);
0x004465C0 => choose_placement_position(u32, u32, *mut Point, u32, @ecx *mut Unit) -> u32;
Expand Down
2 changes: 2 additions & 0 deletions src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub unsafe extern fn init_game() {
globals.iscript_state = iscript::IscriptState::from_script(&iscript);
iscript::set_as_bw_script(iscript);
*Globals::get("init") = globals;
iscript::rebuild_sprite_owners();
}

pub unsafe extern fn save(set_data: unsafe extern fn(*const u8, usize)) {
Expand Down Expand Up @@ -81,6 +82,7 @@ pub unsafe extern fn load(ptr: *const u8, len: usize) -> u32 {
let iscript = iscript::load_iscript(true);
iscript::set_as_bw_script(iscript);
*Globals::get("load") = data;
iscript::rebuild_sprite_owners();
1
}

Expand Down
24 changes: 24 additions & 0 deletions src/iscript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,30 @@ impl SpriteOwnerMap {
}
}

pub fn rebuild_sprite_owners() {
let mut map = SPRITE_OWNER_MAP.lock("rebuild_sprite_owners");
map.unit_mapping.clear();
map.bullet_mapping.clear();
unsafe {
let (units, len) = bw::unit_array();
for i in 0..len {
let unit = units.add(i);
let sprite = (*unit).sprite;
if !sprite.is_null() {
map.add_unit(Unit::from_ptr(unit).unwrap(), sprite);
}
}
let mut bullet = bw::first_active_bullet();
while !bullet.is_null() {
let sprite = (*bullet).sprite;
if !sprite.is_null() {
map.add_bullet(bullet, sprite);
}
bullet = (*bullet).next;
}
}
}

unsafe fn invalid_aice_command(iscript: *mut bw::Iscript, image: *mut bw::Image, offset: CodePos) {
let sprite_id = match Sprite::from_ptr((*image).parent) {
Some(sprite) => sprite.id().0,
Expand Down
9 changes: 9 additions & 0 deletions src/samase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ pub unsafe fn give_ai(unit: *mut bw::Unit) {
(GIVE_AI.0.unwrap())(unit)
}

static mut UNIT_ARRAY_LEN: GlobalFunc<extern fn(*mut *mut bw::Unit, *mut usize)> = GlobalFunc(None);
pub unsafe fn unit_array() -> (*mut bw::Unit, usize) {
let mut arr = null_mut();
let mut len = 0;
(UNIT_ARRAY_LEN.0.unwrap())(&mut arr, &mut len);
(arr, len)
}

pub struct SamaseBox {
data: NonNull<u8>,
len: usize,
Expand Down Expand Up @@ -267,6 +275,7 @@ pub unsafe extern fn samase_plugin_init(api: *const PluginApi) {
FINISH_UNIT_PRE.0 = Some(mem::transmute(((*api).finish_unit_pre)()));
FINISH_UNIT_POST.0 = Some(mem::transmute(((*api).finish_unit_post)()));
GIVE_AI.0 = Some(mem::transmute(((*api).give_ai)()));
UNIT_ARRAY_LEN.0 = Some(mem::transmute(((*api).unit_array_len)()));
let result = ((*api).extend_save)(
"aice\0".as_ptr(),
Some(crate::globals::save),
Expand Down

0 comments on commit 8846d32

Please sign in to comment.