fix: use *mut u8 in TeamArenaRef, add team_header_mut
Browse filesTeamArenaRef.base was *const u8 but team_header_mut() cast it to
*mut, which is unsound. Change base to *mut u8 so all mutable
access goes through legitimate mutable pointers.
blocks() now returns *mut TeamBlock. team_header_mut() no longer
needs a const-to-mut cast.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-core/src/engine/ddgame.rs
CHANGED
|
@@ -1898,7 +1898,7 @@ impl TeamArenaState {
|
|
| 1898 |
#[repr(transparent)]
|
| 1899 |
#[derive(Clone, Copy)]
|
| 1900 |
pub struct TeamArenaRef {
|
| 1901 |
-
base: *
|
| 1902 |
}
|
| 1903 |
|
| 1904 |
impl TeamArenaRef {
|
|
@@ -1909,7 +1909,7 @@ impl TeamArenaRef {
|
|
| 1909 |
#[inline]
|
| 1910 |
pub unsafe fn from_raw(base: u32) -> Self {
|
| 1911 |
Self {
|
| 1912 |
-
base: base as *
|
| 1913 |
}
|
| 1914 |
}
|
| 1915 |
|
|
@@ -1927,8 +1927,8 @@ impl TeamArenaRef {
|
|
| 1927 |
|
| 1928 |
/// Get pointer to the TeamBlock array base.
|
| 1929 |
#[inline]
|
| 1930 |
-
pub unsafe fn blocks(&self) -> *
|
| 1931 |
-
self.base.sub(offsets::ARENA_TO_BLOCKS) as *
|
| 1932 |
}
|
| 1933 |
|
| 1934 |
/// Get the team header (metadata) for a team.
|
|
@@ -1940,6 +1940,12 @@ impl TeamArenaRef {
|
|
| 1940 |
&(*self.blocks().add(team_idx + 1)).header.team
|
| 1941 |
}
|
| 1942 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1943 |
/// Get a playable worm entry by 1-indexed worm number (1..=8).
|
| 1944 |
///
|
| 1945 |
/// Uses raw pointer arithmetic matching the original WA code:
|
|
|
|
| 1898 |
#[repr(transparent)]
|
| 1899 |
#[derive(Clone, Copy)]
|
| 1900 |
pub struct TeamArenaRef {
|
| 1901 |
+
base: *mut u8,
|
| 1902 |
}
|
| 1903 |
|
| 1904 |
impl TeamArenaRef {
|
|
|
|
| 1909 |
#[inline]
|
| 1910 |
pub unsafe fn from_raw(base: u32) -> Self {
|
| 1911 |
Self {
|
| 1912 |
+
base: base as *mut u8,
|
| 1913 |
}
|
| 1914 |
}
|
| 1915 |
|
|
|
|
| 1927 |
|
| 1928 |
/// Get pointer to the TeamBlock array base.
|
| 1929 |
#[inline]
|
| 1930 |
+
pub unsafe fn blocks(&self) -> *mut TeamBlock {
|
| 1931 |
+
self.base.sub(offsets::ARENA_TO_BLOCKS) as *mut TeamBlock
|
| 1932 |
}
|
| 1933 |
|
| 1934 |
/// Get the team header (metadata) for a team.
|
|
|
|
| 1940 |
&(*self.blocks().add(team_idx + 1)).header.team
|
| 1941 |
}
|
| 1942 |
|
| 1943 |
+
/// Get a mutable team header for a team.
|
| 1944 |
+
#[inline]
|
| 1945 |
+
pub unsafe fn team_header_mut(&self, team_idx: usize) -> &mut TeamHeader {
|
| 1946 |
+
&mut (*self.blocks().add(team_idx + 1)).header.team
|
| 1947 |
+
}
|
| 1948 |
+
|
| 1949 |
/// Get a playable worm entry by 1-indexed worm number (1..=8).
|
| 1950 |
///
|
| 1951 |
/// Uses raw pointer arithmetic matching the original WA code:
|
crates/openwa-wormkit/src/replacements/weapon.rs
CHANGED
|
@@ -400,7 +400,6 @@ unsafe fn fire_weapon_special(
|
|
| 400 |
/// In game_version > 0x1C: toggles (set/clear). Otherwise: always sets.
|
| 401 |
unsafe fn fire_skip_go(worm: *const CTaskWorm, entry: *const WeaponEntry) {
|
| 402 |
use openwa_core::engine::ddgame::TeamArenaRef;
|
| 403 |
-
use openwa_core::engine::ddgame::TeamHeader;
|
| 404 |
use openwa_core::engine::DDGame;
|
| 405 |
|
| 406 |
let ddgame = (*worm).base.base.ddgame as *mut DDGame;
|
|
@@ -412,13 +411,13 @@ unsafe fn fire_skip_go(worm: *const CTaskWorm, entry: *const WeaponEntry) {
|
|
| 412 |
|
| 413 |
let arena_ptr = &raw mut (*ddgame).team_arena as u32;
|
| 414 |
let arena = TeamArenaRef::from_raw(arena_ptr);
|
| 415 |
-
let header = arena.
|
| 416 |
-
let flags =
|
| 417 |
|
| 418 |
if game_version > 0x1C && (flags & bit) != 0 {
|
| 419 |
-
|
| 420 |
} else {
|
| 421 |
-
|
| 422 |
}
|
| 423 |
}
|
| 424 |
|
|
|
|
| 400 |
/// In game_version > 0x1C: toggles (set/clear). Otherwise: always sets.
|
| 401 |
unsafe fn fire_skip_go(worm: *const CTaskWorm, entry: *const WeaponEntry) {
|
| 402 |
use openwa_core::engine::ddgame::TeamArenaRef;
|
|
|
|
| 403 |
use openwa_core::engine::DDGame;
|
| 404 |
|
| 405 |
let ddgame = (*worm).base.base.ddgame as *mut DDGame;
|
|
|
|
| 411 |
|
| 412 |
let arena_ptr = &raw mut (*ddgame).team_arena as u32;
|
| 413 |
let arena = TeamArenaRef::from_raw(arena_ptr);
|
| 414 |
+
let header = arena.team_header_mut(team_index);
|
| 415 |
+
let flags = header.turn_action_flags;
|
| 416 |
|
| 417 |
if game_version > 0x1C && (flags & bit) != 0 {
|
| 418 |
+
header.turn_action_flags = flags & !bit;
|
| 419 |
} else {
|
| 420 |
+
header.turn_action_flags = flags | bit;
|
| 421 |
}
|
| 422 |
}
|
| 423 |
|