From 301916024d3e178fb7b531d78d8135f0d2060796 Mon Sep 17 00:00:00 2001
From: asimon-1 <40246417+asimon-1@users.noreply.github.com>
Date: Wed, 13 Nov 2024 22:52:10 -0500
Subject: [PATCH] items.rs

---
 src/training/character_specific/items.rs | 66 +++++++++++++-----------
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/src/training/character_specific/items.rs b/src/training/character_specific/items.rs
index d93860e..faec5c9 100644
--- a/src/training/character_specific/items.rs
+++ b/src/training/character_specific/items.rs
@@ -1,3 +1,4 @@
+// TODO!() There's some crazy pointer magic happening in this file, we should try to refactor to avoid that
 use smash::app;
 use smash::app::lua_bind::*;
 use smash::app::ItemKind;
@@ -8,9 +9,11 @@ use smash::lib::lua_const::*;
 use crate::common::consts::*;
 use crate::common::*;
 use crate::offsets::OFFSET_GENERATE_ARTICLE_FOR_TARGET;
-use training_mod_sync::*;
 use crate::training::mash;
+use training_mod_sync::*;
 
+pub static TURNIP_CHOSEN: RwLock<Option<u32>> = RwLock::new(None);
+pub static TARGET_PLAYER: RwLock<Option<BattleObjectModuleAccessor>> = RwLock::new(None);
 pub struct CharItem {
     pub fighter_kind: LuaConst,
     pub item_kind: Option<LuaConst>,
@@ -327,9 +330,6 @@ pub const ALL_CHAR_ITEMS: [CharItem; 45] = [
     },
 ];
 
-pub static mut TURNIP_CHOSEN: Option<u32> = None;
-pub static mut TARGET_PLAYER: Option<*mut BattleObjectModuleAccessor> = None;
-
 unsafe fn apply_single_item(player_fighter_kind: i32, item: &CharItem) {
     let player_module_accessor = get_module_accessor(FighterId::Player);
     let cpu_module_accessor = get_module_accessor(FighterId::CPU);
@@ -378,25 +378,26 @@ unsafe fn apply_single_item(player_fighter_kind: i32, item: &CharItem) {
     });
 
     item.article_kind.as_ref().map(|article_kind| {
-        TURNIP_CHOSEN = if [*ITEM_VARIATION_PEACHDAIKON_8, *ITEM_VARIATION_DAISYDAIKON_8]
-            .contains(&variation)
-        {
-            Some(8)
-        } else if [*ITEM_VARIATION_PEACHDAIKON_7, *ITEM_VARIATION_DAISYDAIKON_7]
-            .contains(&variation)
-        {
-            Some(7)
-        } else if [*ITEM_VARIATION_PEACHDAIKON_6, *ITEM_VARIATION_DAISYDAIKON_6]
-            .contains(&variation)
-        {
-            Some(6)
-        } else if [*ITEM_VARIATION_PEACHDAIKON_1, *ITEM_VARIATION_DAISYDAIKON_1]
-            .contains(&variation)
-        {
-            Some(1)
-        } else {
-            None
-        };
+        assign_rwlock(
+            &TURNIP_CHOSEN,
+            if [*ITEM_VARIATION_PEACHDAIKON_8, *ITEM_VARIATION_DAISYDAIKON_8].contains(&variation) {
+                Some(8)
+            } else if [*ITEM_VARIATION_PEACHDAIKON_7, *ITEM_VARIATION_DAISYDAIKON_7]
+                .contains(&variation)
+            {
+                Some(7)
+            } else if [*ITEM_VARIATION_PEACHDAIKON_6, *ITEM_VARIATION_DAISYDAIKON_6]
+                .contains(&variation)
+            {
+                Some(6)
+            } else if [*ITEM_VARIATION_PEACHDAIKON_1, *ITEM_VARIATION_DAISYDAIKON_1]
+                .contains(&variation)
+            {
+                Some(1)
+            } else {
+                None
+            },
+        );
 
         let article_kind = **article_kind;
         if article_kind == FIGHTER_DIDDY_GENERATE_ARTICLE_ITEM_BANANA {
@@ -429,16 +430,18 @@ unsafe fn apply_single_item(player_fighter_kind: i32, item: &CharItem) {
                 false,
             );
         } else {
-            TARGET_PLAYER = Some(player_module_accessor); // set so we generate CPU article on the player (in dittos, items always belong to player, even if cpu item is chosen)
+            // Set the target player so we generate CPU article on the player during handle_generate_article_for_target
+            // (in dittos, items always belong to player, even if cpu item is chosen)
+            assign_rwlock(&TARGET_PLAYER, Some(*player_module_accessor));
             ArticleModule::generate_article(
                 generator_module_accessor, // we want CPU's article
                 article_kind,
                 false,
                 0,
             );
-            TARGET_PLAYER = None;
+            assign_rwlock(&TARGET_PLAYER, None);
         }
-        TURNIP_CHOSEN = None;
+        assign_rwlock(&TURNIP_CHOSEN, None);
     });
 }
 
@@ -480,9 +483,10 @@ macro_rules! daikon_replace {
             pub unsafe fn [<handle_ $char daikon_ $num _prob>]() -> f32 {
                 let orig = original!()();
                 if is_training_mode() {
-                    if TURNIP_CHOSEN == Some($num) {
+                    let turnip_chosen = read_rwlock(&TURNIP_CHOSEN);
+                    if turnip_chosen == Some($num) {
                         return 58.0;
-                    } else if TURNIP_CHOSEN != None {
+                    } else if turnip_chosen != None {
                         return 0.0;
                     }
                 }
@@ -513,14 +517,14 @@ daikon_replace!(DAISY, daisy, 1);
 // GenerateArticleForTarget for Peach/Diddy(/Link?) item creation
 #[skyline::hook(offset = *OFFSET_GENERATE_ARTICLE_FOR_TARGET)]
 pub unsafe fn handle_generate_article_for_target(
-    article_module_accessor: *mut BattleObjectModuleAccessor,
+    article_module_accessor: BattleObjectModuleAccessor,
     int_1: i32,
-    module_accessor: *mut BattleObjectModuleAccessor, // this is always 0x0 normally
+    module_accessor: BattleObjectModuleAccessor, // this is always 0x0 normally
     bool_1: bool,
     int_2: i32,
 ) -> u64 {
     // unknown return value, gets cast to an (Article *)
-    let target_module_accessor = TARGET_PLAYER.unwrap_or(module_accessor);
+    let target_module_accessor = read_rwlock(&TARGET_PLAYER).unwrap_or(module_accessor);
 
     original!()(
         article_module_accessor,