├── .gitignore ├── Cargo.toml ├── README.md ├── nro ├── Cargo.toml ├── build.ps1 ├── config_param.toml ├── install.ps1 └── src │ ├── data.rs │ ├── lib.rs │ └── plugin.rs └── src ├── hook.rs └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | **/*.py 3 | **/*.pyc 4 | Cargo.lock 5 | **/.vscode 6 | **/src/custom 7 | **/src/mario 8 | *.lnk 9 | .devcontainer/Dockerfile 10 | .devcontainer/Dockerfile 11 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "param_config" 3 | version = "6.0.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } 10 | skyline_smash = { git = "https://github.com/blu-dev/skyline-smash.git", features = ["weak_l2cvalue"] } 11 | smash_script = { git = "https://github.com/blu-dev/smash-script.git", branch = "development" } 12 | lazy_static = "1.4.0" 13 | toml = "0.5.2" 14 | serde = "1.0.136" 15 | serde_derive = "1.0.136" 16 | parking_lot = "0.11.2" 17 | hash40 = "1.3.0" 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lib_paramconfig (nro) 2 | 3 | **For end-users, go to the [releases tab](https://github.com/CSharpM7/lib_paramconfig/releases) and select the latest version. Make sure to disable the plugin when using other mods that hook param functions. For developers, keep reading.** 4 | 5 | A common problem across "single slot movesets"(SSMs) is that because they often hook the same functions, they will cause crashes when multiple SSMs are active at once. This plugin serves as a middleman between the source code and mods, so that even though multiple SSMs are active, this is the only plugin that actually hooks param functions. 6 | 7 | ## Dependencies 8 | [lib_nrohook](https://github.com/ultimate-research/nro-hook-plugin/releases) (install in your plugins folder, all end-users will need this as well) 9 | 10 | ## Caution! 11 | This can have adverse effects in casual modes, as well as with other external mechanics that attempt to edit parameters. This assumes you, and your target audience, are willing to risk the possibility of unintended consequences regarding SSMs, or have mitigated some of these possible unintended effects. This is also not compatible with any other gameplay modifying plugin that hooks param functions. Please make sure to disable this plugin before using such other mods/plugins. 12 | 13 | ## Usage 14 | All end-users will need to download an updated `libparam_config.nro` from the releases page (please do not bundle with your release as this plugin is still in its infancy). Create a file called `config_param.toml` and place it in the root of your mod (feel free to copy the one provided in the source code). Fill out the toml with the fighter kind of your mod, the slots that will be affected, and the common parameters you wish to modify. 15 | 16 | ## Limitations 17 | - This also can only change `int`, `float`, and `bool` values. For bools, please use a `param_int` object with a value of 0 or 1. 18 | - Not all params will work (usually floats). 19 | - Currently, this does not support editing all parameters featured in `vl.prc` files (namely parameters with several arrays like MinMin's arms), though it does support most of the basic ones. Changing information like ledgegrab boxes and hurtboxes has gone untested (ledgegrab boxes can be altered via smashline), as well as several other `vl.prc` parameters. 20 | - Does not work with pocketed items or copy abilities 21 | 22 | ## Toml Layout 23 | 24 | ``` 25 | kind = "mario" #~OPTIONAL~ The default kind for this toml. Any param that doesn't have a `kinds` value will default to this. This should be whatever comes after FIGHTER_KIND_. Ie "MARIO" or "mario" 26 | slots = [0,1,...] #~OPTIONAL~ The default list of effected slots (alt costume numbers). Use -1 to apply to all costumes. Any param that doesn't have a `slots` value will default to this list 27 | 28 | [[param_int]] 29 | param = "param_fireball" #the cracked hash name found when viewing in prceditor 30 | subparam = "life" #the cracked hash of the subcategory of this param. It might includes things like "life" or "angle" 31 | value = 99 32 | 33 | [[param_int]] #a second param you wish to edit 34 | param = "wall_jump_type" 35 | subparam = "" #note for fighter attributes, you often want to leave this blank 36 | value = 0 #if you are working with a bool, use 0 for false, and 1 for true 37 | 38 | [[attribute_mul]] #For fighter attributes (subparam=0) that are floats, you'll want to use a multiplier instead of setting the value directly 39 | param = "jump_y" 40 | subparam = "" 41 | value = 2.0 #This will make Dr Mario jump twice as high (regardless of his equipment) 42 | 43 | [[attribute_mul]] #you can also get rid of this category if you are not editing floats. Same goes for ints 44 | param = "0x607cd5541" #you can also use the raw hash version, as long as it begins with 0x 45 | subparam = "" 46 | value = 2.0 47 | 48 | [[param_float]] 49 | param = "param_fireball" 50 | subparam = "gravity_accel" 51 | value = 0.0 52 | kinds = ["mario","mario_fireball"] #~OPTIONAL~ For weapons, I recommend including their weapon kind in the list as well 53 | slots = [0,1,2] #~OPTIONAL~ 54 | 55 | [[param_int]] 56 | param = "article_use_type" #For changing the use type of an article. Usually used for allowing entry/victory articles to spawn in game 57 | value = 1 58 | kinds = ["mariod_capsuleblock"] 59 | 60 | [[param_int]] 61 | param = "kirby_cant_copy" #Prevents Kirby from copying the ability of a fighter `kind` if they are using a costume in `slots` 62 | value = 0 63 | 64 | [[param_int]] 65 | param = "villager_cant_pocket" #Prevents Villager, Isabelle, and Kirby from pocketing a weapon kind (denoted by `subparam`) if the weapon's owner is of `kind` and using a costume in `slot` 66 | subparam = "koopajr_cannonball" #Kind of weapon to prevent being pocketed. if you set this to "", then every weapon kind under the fighter/slot will be included 67 | value = 0 68 | ``` 69 | 70 | # lib_paramconfig 71 | 72 | lib_paramconfig also supports changes via your own skyline plugin. 73 | 74 | ## Setup 75 | Your `Cargo.toml` needs to include this dependency: 76 | `param_config = { git = "https://github.com/csharpm7/lib_paramconfig.git"}` 77 | 78 | ## Usage 79 | ``` 80 | param_config::update_int_2(kind: i32, slots: Vec,index: (u64,u64),value: i32); 81 | param_config::update_float_2(kind: i32, slots: Vec,index: (u64,u64),value: f32); 82 | param_config::update_attribute_mul_2(kind: i32, slots: Vec,index: (u64,u64),value: f32); 83 | ``` 84 | Kind: Fighter/Weapon kind, as commonly used like `*FIGHTER_KIND_MARIOD`. If it's a weapon, use a negative number. 85 | 86 | Slots: Vector Array of slots 87 | 88 | Index: (hash40(""),hash40("")) for param/subparam hashes. For common params, the second argument should be 0. 89 | 90 | Value: Value for the param. Keep in mind that the `_mul` functions will multiply the original rather than set a new value. 91 | 92 | ``` 93 | param_config::disable_villager_pocket(kind: i32, slots: Vec, weapon_kind: i32) 94 | param_config::disable_kirby_copy(kind: i32, slots: Vec) 95 | param_config::set_article_use_type(kind: i32, use_type: i32) 96 | ``` 97 | 98 | Weapon kind: Weapon Kind to prevent being pocketed. If this is 0, then all weapons spawned from kind/slots will be accounted for 99 | Use_type: USETYPE const (ie *ARTICLE_USETYPE_FINAL); -------------------------------------------------------------------------------- /nro/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "param_config_nro" 3 | version = "1.0.0" 4 | authors = ["C# <@CSharpM7>"] 5 | edition = "2018" 6 | 7 | [package.metadata.skyline] 8 | titleid = "01006A800016E000" 9 | 10 | [lib] 11 | name = "param_config" 12 | crate-type = ["cdylib"] 13 | 14 | [dependencies] 15 | param_config = { path = "../" } 16 | skyline = { git = "https://github.com/ultimate-research/skyline-rs.git" } 17 | skyline_smash = { git = "https://github.com/blu-dev/skyline-smash.git", features = ["weak_l2cvalue"] } 18 | smash_script = { git = "https://github.com/blu-dev/smash-script.git", branch = "development" } 19 | arcropolis-api = { git = "https://github.com/Raytwo/arcropolis_api"} 20 | once_cell = "1.12.0" 21 | toml = "0.5.2" 22 | serde = "1.0.136" 23 | serde_derive = "1.0.136" 24 | parking_lot = "0.11.2" 25 | 26 | [profile.dev] 27 | panic = "abort" 28 | 29 | [profile.release] 30 | opt-level = 'z' 31 | panic = "abort" 32 | lto = true 33 | codegen-units = 1 34 | 35 | [features] 36 | test = [] -------------------------------------------------------------------------------- /nro/build.ps1: -------------------------------------------------------------------------------- 1 | cargo skyline build --release 2 | Invoke-Item "target/aarch64-skyline-switch/release" -------------------------------------------------------------------------------- /nro/config_param.toml: -------------------------------------------------------------------------------- 1 | kind = "mariod" 2 | slots = [0,1,2] 3 | 4 | [[param_int]] 5 | param = "jump_squat_frame" 6 | subparam = "" 7 | value = 12 8 | 9 | [[param_int]] 10 | param = "wall_jump_type" 11 | subparam = "" 12 | value = 1 13 | 14 | [[attribute_mul]] 15 | param = "jump_initial_y" 16 | subparam = "" 17 | value = 2.0 18 | 19 | [[attribute_mul]] 20 | param = "jump_y" 21 | subparam = "" 22 | value = 2.0 23 | 24 | [[attribute_mul]] 25 | param = "jump_aerial_y" 26 | subparam = "" 27 | value = 2.0 28 | 29 | [[attribute_mul]] 30 | param = "mini_jump_y" 31 | subparam = "" 32 | value = 2.0 33 | 34 | [[attribute_mul]] 35 | param = "run_speed_max" 36 | subparam = "" 37 | value = 2.0 38 | 39 | [[param_float]] 40 | param = "param_drcapsule" 41 | subparam = "gravity_accel" 42 | value = 0.0 43 | kinds = ["mariod","mariod_drcapsule"] 44 | slots = [0,1,2] 45 | 46 | [[param_float]] 47 | param = "param_drcapsule" 48 | subparam = "angle" 49 | value = 0.0 50 | kinds = ["mariod","mariod_drcapsule"] 51 | slots = [0,1,2] 52 | 53 | [[param_float]] 54 | param = "param_special_lw" 55 | subparam = "buoyancy" 56 | value = 8.0 57 | 58 | [[param_float]] 59 | param = "param_special_lw" 60 | subparam = "buoyancy_max" 61 | value = 8.0 62 | 63 | [[param_int]] 64 | param = "article_use_type" 65 | value = 1 66 | kinds = ["mariod_capsuleblock"] 67 | 68 | [[param_int]] 69 | param = "kirby_cant_copy" 70 | value = 0 71 | 72 | [[param_int]] 73 | param = "villager_cant_pocket" 74 | subparam = "mariod_drcapsule" 75 | value = 0 -------------------------------------------------------------------------------- /nro/install.ps1: -------------------------------------------------------------------------------- 1 | function Get-TimeStamp { 2 | 3 | return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) 4 | 5 | } 6 | If ($args[0] -like "*dev*") { 7 | cargo skyline install --install-path rom:/smashline/development.nro 8 | Write-Output "$(Get-TimeStamp) Installed dev plugin" 9 | } 10 | else{ 11 | cargo skyline install --install-path rom:/skyline/plugins/libparam_config.nro 12 | Write-Output "$(Get-TimeStamp) Installed plugin" 13 | } -------------------------------------------------------------------------------- /nro/src/data.rs: -------------------------------------------------------------------------------- 1 | #![feature(proc_macro_hygiene)] 2 | use super::*; 3 | use std::{ 4 | sync::Mutex 5 | }; 6 | 7 | use once_cell::sync::Lazy; 8 | 9 | pub static FIGHTER_TABLE: Lazy>> = Lazy::new(|| {Mutex::new(HashMap::new())}); 10 | pub fn build_fighter_table() { 11 | FIGHTER_TABLE.lock().unwrap().insert("sonic","29"); 12 | FIGHTER_TABLE.lock().unwrap().insert("demon","5c"); 13 | FIGHTER_TABLE.lock().unwrap().insert("dolly","55"); 14 | FIGHTER_TABLE.lock().unwrap().insert("link","2"); 15 | FIGHTER_TABLE.lock().unwrap().insert("miienemys","4f"); 16 | FIGHTER_TABLE.lock().unwrap().insert("tantan","57"); 17 | FIGHTER_TABLE.lock().unwrap().insert("diddy","27"); 18 | FIGHTER_TABLE.lock().unwrap().insert("jack","52"); 19 | FIGHTER_TABLE.lock().unwrap().insert("sheik","10"); 20 | FIGHTER_TABLE.lock().unwrap().insert("purin","c"); 21 | FIGHTER_TABLE.lock().unwrap().insert("simon","43"); 22 | FIGHTER_TABLE.lock().unwrap().insert("pichu","13"); 23 | FIGHTER_TABLE.lock().unwrap().insert("koopag","4d"); 24 | FIGHTER_TABLE.lock().unwrap().insert("reflet","38"); 25 | FIGHTER_TABLE.lock().unwrap().insert("donkey","1"); 26 | FIGHTER_TABLE.lock().unwrap().insert("rosetta","33"); 27 | FIGHTER_TABLE.lock().unwrap().insert("elight","5b"); 28 | FIGHTER_TABLE.lock().unwrap().insert("plizardon","26"); 29 | FIGHTER_TABLE.lock().unwrap().insert("base_append_head","51"); 30 | FIGHTER_TABLE.lock().unwrap().insert("brave","53"); 31 | FIGHTER_TABLE.lock().unwrap().insert("zelda","11"); 32 | FIGHTER_TABLE.lock().unwrap().insert("none","ffffffff"); 33 | FIGHTER_TABLE.lock().unwrap().insert("duckhunt","3b"); 34 | FIGHTER_TABLE.lock().unwrap().insert("rockman","31"); 35 | FIGHTER_TABLE.lock().unwrap().insert("samus","3"); 36 | FIGHTER_TABLE.lock().unwrap().insert("pfushigisou","25"); 37 | FIGHTER_TABLE.lock().unwrap().insert("cloud","3e"); 38 | FIGHTER_TABLE.lock().unwrap().insert("packun","51"); 39 | FIGHTER_TABLE.lock().unwrap().insert("light","74"); 40 | FIGHTER_TABLE.lock().unwrap().insert("younglink","17"); 41 | FIGHTER_TABLE.lock().unwrap().insert("wiifit","32"); 42 | FIGHTER_TABLE.lock().unwrap().insert("buddy","54"); 43 | FIGHTER_TABLE.lock().unwrap().insert("robot","2d"); 44 | FIGHTER_TABLE.lock().unwrap().insert("littlemac","34"); 45 | FIGHTER_TABLE.lock().unwrap().insert("trail","5d"); 46 | FIGHTER_TABLE.lock().unwrap().insert("samusd","4"); 47 | FIGHTER_TABLE.lock().unwrap().insert("richter","44"); 48 | FIGHTER_TABLE.lock().unwrap().insert("pzenigame","24"); 49 | FIGHTER_TABLE.lock().unwrap().insert("snake","22"); 50 | FIGHTER_TABLE.lock().unwrap().insert("table_ex_term","76"); 51 | FIGHTER_TABLE.lock().unwrap().insert("edge","59"); 52 | FIGHTER_TABLE.lock().unwrap().insert("yoshi","5"); 53 | FIGHTER_TABLE.lock().unwrap().insert("ganon","18"); 54 | FIGHTER_TABLE.lock().unwrap().insert("ridley","42"); 55 | FIGHTER_TABLE.lock().unwrap().insert("ken","3d"); 56 | FIGHTER_TABLE.lock().unwrap().insert("mewtwo","19"); 57 | FIGHTER_TABLE.lock().unwrap().insert("wolf","2f"); 58 | FIGHTER_TABLE.lock().unwrap().insert("roy","1a"); 59 | FIGHTER_TABLE.lock().unwrap().insert("base_append_num","d"); 60 | FIGHTER_TABLE.lock().unwrap().insert("falco","14"); 61 | FIGHTER_TABLE.lock().unwrap().insert("base_head","0"); 62 | FIGHTER_TABLE.lock().unwrap().insert("toonlink","2e"); 63 | FIGHTER_TABLE.lock().unwrap().insert("zenigame","6f"); 64 | FIGHTER_TABLE.lock().unwrap().insert("murabito","30"); 65 | FIGHTER_TABLE.lock().unwrap().insert("miienemyf","4e"); 66 | FIGHTER_TABLE.lock().unwrap().insert("captain","b"); 67 | FIGHTER_TABLE.lock().unwrap().insert("kamui","3f"); 68 | FIGHTER_TABLE.lock().unwrap().insert("nana","4c"); 69 | FIGHTER_TABLE.lock().unwrap().insert("szerosuit","20"); 70 | FIGHTER_TABLE.lock().unwrap().insert("ptrainer","72"); 71 | FIGHTER_TABLE.lock().unwrap().insert("popo","4b"); 72 | FIGHTER_TABLE.lock().unwrap().insert("fushigisou","70"); 73 | FIGHTER_TABLE.lock().unwrap().insert("pikachu","8"); 74 | FIGHTER_TABLE.lock().unwrap().insert("gekkouga","35"); 75 | FIGHTER_TABLE.lock().unwrap().insert("other_tail","50"); 76 | FIGHTER_TABLE.lock().unwrap().insert("lucas","28"); 77 | FIGHTER_TABLE.lock().unwrap().insert("fox","7"); 78 | FIGHTER_TABLE.lock().unwrap().insert("palutena","36"); 79 | FIGHTER_TABLE.lock().unwrap().insert("dedede","2a"); 80 | FIGHTER_TABLE.lock().unwrap().insert("ice_climber","6e"); 81 | FIGHTER_TABLE.lock().unwrap().insert("wario","21"); 82 | FIGHTER_TABLE.lock().unwrap().insert("koopa","f"); 83 | FIGHTER_TABLE.lock().unwrap().insert("daisy","e"); 84 | FIGHTER_TABLE.lock().unwrap().insert("flame","73"); 85 | FIGHTER_TABLE.lock().unwrap().insert("lucina","16"); 86 | FIGHTER_TABLE.lock().unwrap().insert("mario","0"); 87 | FIGHTER_TABLE.lock().unwrap().insert("chrom","1b"); 88 | FIGHTER_TABLE.lock().unwrap().insert("kirby","6"); 89 | FIGHTER_TABLE.lock().unwrap().insert("pit","1e"); 90 | FIGHTER_TABLE.lock().unwrap().insert("eflame","5a"); 91 | FIGHTER_TABLE.lock().unwrap().insert("lucario","2c"); 92 | FIGHTER_TABLE.lock().unwrap().insert("marth","15"); 93 | FIGHTER_TABLE.lock().unwrap().insert("master","56"); 94 | FIGHTER_TABLE.lock().unwrap().insert("metaknight","1d"); 95 | FIGHTER_TABLE.lock().unwrap().insert("peach","d"); 96 | FIGHTER_TABLE.lock().unwrap().insert("table_ex_start","6d"); 97 | FIGHTER_TABLE.lock().unwrap().insert("pitb","1f"); 98 | FIGHTER_TABLE.lock().unwrap().insert("gamewatch","1c"); 99 | FIGHTER_TABLE.lock().unwrap().insert("other_num","4"); 100 | FIGHTER_TABLE.lock().unwrap().insert("luigi","9"); 101 | FIGHTER_TABLE.lock().unwrap().insert("miifighter","48"); 102 | FIGHTER_TABLE.lock().unwrap().insert("pacman","37"); 103 | FIGHTER_TABLE.lock().unwrap().insert("random","77"); 104 | FIGHTER_TABLE.lock().unwrap().insert("base_append_tail","5d"); 105 | FIGHTER_TABLE.lock().unwrap().insert("miigunner","4a"); 106 | FIGHTER_TABLE.lock().unwrap().insert("miienemyg","50"); 107 | FIGHTER_TABLE.lock().unwrap().insert("element","75"); 108 | FIGHTER_TABLE.lock().unwrap().insert("shizue","46"); 109 | FIGHTER_TABLE.lock().unwrap().insert("bayonetta","40"); 110 | FIGHTER_TABLE.lock().unwrap().insert("shulk","39"); 111 | FIGHTER_TABLE.lock().unwrap().insert("gaogaen","47"); 112 | FIGHTER_TABLE.lock().unwrap().insert("krool","45"); 113 | FIGHTER_TABLE.lock().unwrap().insert("other_head","4d"); 114 | FIGHTER_TABLE.lock().unwrap().insert("lizardon","71"); 115 | FIGHTER_TABLE.lock().unwrap().insert("base_tail","4c"); 116 | FIGHTER_TABLE.lock().unwrap().insert("ike","23"); 117 | FIGHTER_TABLE.lock().unwrap().insert("ryu","3c"); 118 | FIGHTER_TABLE.lock().unwrap().insert("mariod","12"); 119 | FIGHTER_TABLE.lock().unwrap().insert("pikmin","2b"); 120 | FIGHTER_TABLE.lock().unwrap().insert("base_num","4d"); 121 | FIGHTER_TABLE.lock().unwrap().insert("koopajr","3a"); 122 | FIGHTER_TABLE.lock().unwrap().insert("inkling","41"); 123 | FIGHTER_TABLE.lock().unwrap().insert("ness","a"); 124 | FIGHTER_TABLE.lock().unwrap().insert("pickel","58"); 125 | FIGHTER_TABLE.lock().unwrap().insert("miiswordsman","49"); 126 | FIGHTER_TABLE.lock().unwrap().insert("term","5e"); 127 | FIGHTER_TABLE.lock().unwrap().insert("all","5e"); 128 | } 129 | pub fn get_fighter_kind_from_string(target_kind: &str) -> i32 { 130 | 131 | let lowercased=target_kind.to_lowercase(); 132 | if let Some(hex) = FIGHTER_TABLE.lock().unwrap().get(lowercased.as_str()){ 133 | let int = i64::from_str_radix(hex, 16); 134 | return int.unwrap() as i32; 135 | } 136 | return 999; 137 | } 138 | 139 | pub static WEAPON_TABLE: Lazy>> = Lazy::new(|| {Mutex::new(HashMap::new()) 140 | }); 141 | pub fn build_weapon_table() { 142 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_bat","171"); 143 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_gomorrah","172"); 144 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_hair","173"); 145 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_specialn_bullet","16e"); 146 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_wickedweavearm","16f"); 147 | WEAPON_TABLE.lock().unwrap().insert("bayonetta_wickedweaveleg","170"); 148 | WEAPON_TABLE.lock().unwrap().insert("brave_blue","1fe"); 149 | WEAPON_TABLE.lock().unwrap().insert("brave_crash","1fc"); 150 | WEAPON_TABLE.lock().unwrap().insert("brave_deathball","1fb"); 151 | WEAPON_TABLE.lock().unwrap().insert("brave_explosion","1f9"); 152 | WEAPON_TABLE.lock().unwrap().insert("brave_fireball","1f5"); 153 | WEAPON_TABLE.lock().unwrap().insert("brave_flash","1fa"); 154 | WEAPON_TABLE.lock().unwrap().insert("brave_lightning","1f7"); 155 | WEAPON_TABLE.lock().unwrap().insert("brave_sleep","1fd"); 156 | WEAPON_TABLE.lock().unwrap().insert("brave_spark","1f6"); 157 | WEAPON_TABLE.lock().unwrap().insert("brave_tornado","1f8"); 158 | WEAPON_TABLE.lock().unwrap().insert("buddy_bigbird","202"); 159 | WEAPON_TABLE.lock().unwrap().insert("buddy_bigbirdbase","203"); 160 | WEAPON_TABLE.lock().unwrap().insert("buddy_bird","201"); 161 | WEAPON_TABLE.lock().unwrap().insert("buddy_bullet","204"); 162 | WEAPON_TABLE.lock().unwrap().insert("buddy_horn","207"); 163 | WEAPON_TABLE.lock().unwrap().insert("buddy_pad","1ff"); 164 | WEAPON_TABLE.lock().unwrap().insert("buddy_partner","200"); 165 | WEAPON_TABLE.lock().unwrap().insert("buddy_piece","205"); 166 | WEAPON_TABLE.lock().unwrap().insert("buddy_strings","206"); 167 | WEAPON_TABLE.lock().unwrap().insert("captain_bluefalcon","57"); 168 | WEAPON_TABLE.lock().unwrap().insert("captain_falconpunch","58"); 169 | WEAPON_TABLE.lock().unwrap().insert("chrom_sword","1b6"); 170 | WEAPON_TABLE.lock().unwrap().insert("cloud_wave","16c"); 171 | WEAPON_TABLE.lock().unwrap().insert("daisy_kassar","6a"); 172 | WEAPON_TABLE.lock().unwrap().insert("daisy_kinopio","6b"); 173 | WEAPON_TABLE.lock().unwrap().insert("daisy_kinopiospore","6c"); 174 | WEAPON_TABLE.lock().unwrap().insert("dedede_gordo","ad"); 175 | WEAPON_TABLE.lock().unwrap().insert("dedede_jethammer","aa"); 176 | WEAPON_TABLE.lock().unwrap().insert("dedede_mask","b1"); 177 | WEAPON_TABLE.lock().unwrap().insert("dedede_missile","b2"); 178 | WEAPON_TABLE.lock().unwrap().insert("dedede_newdededehammer","b0"); 179 | WEAPON_TABLE.lock().unwrap().insert("dedede_shrine","ae"); 180 | WEAPON_TABLE.lock().unwrap().insert("dedede_star","ac"); 181 | WEAPON_TABLE.lock().unwrap().insert("dedede_star_missile","ab"); 182 | WEAPON_TABLE.lock().unwrap().insert("dedede_waddledee","af"); 183 | WEAPON_TABLE.lock().unwrap().insert("demon_blaster","259"); 184 | WEAPON_TABLE.lock().unwrap().insert("demon_blasterchest","25b"); 185 | WEAPON_TABLE.lock().unwrap().insert("demon_blasterhead","25c"); 186 | WEAPON_TABLE.lock().unwrap().insert("demon_blasterwing","25d"); 187 | WEAPON_TABLE.lock().unwrap().insert("demon_demonp","25a"); 188 | WEAPON_TABLE.lock().unwrap().insert("diddy_barreljet","a3"); 189 | WEAPON_TABLE.lock().unwrap().insert("diddy_barreljets","a6"); 190 | WEAPON_TABLE.lock().unwrap().insert("diddy_bunshin","a7"); 191 | WEAPON_TABLE.lock().unwrap().insert("diddy_dkbarrel","a8"); 192 | WEAPON_TABLE.lock().unwrap().insert("diddy_explosion","a5"); 193 | WEAPON_TABLE.lock().unwrap().insert("diddy_gun","a2"); 194 | WEAPON_TABLE.lock().unwrap().insert("diddy_lock_on_cursor","a9"); 195 | WEAPON_TABLE.lock().unwrap().insert("diddy_peanuts","a4"); 196 | WEAPON_TABLE.lock().unwrap().insert("dolly_burst","209"); 197 | WEAPON_TABLE.lock().unwrap().insert("dolly_cap","20a"); 198 | WEAPON_TABLE.lock().unwrap().insert("dolly_fire","20b"); 199 | WEAPON_TABLE.lock().unwrap().insert("dolly_wave","208"); 200 | WEAPON_TABLE.lock().unwrap().insert("donkey_dkbarrel","1c"); 201 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_can","121"); 202 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_clay","120"); 203 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalbird","128"); 204 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalcan","12a"); 205 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finaldog","127"); 206 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalduck","124"); 207 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalenemy","126"); 208 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalgrass","129"); 209 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_finalgunman","125"); 210 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_grass","12b"); 211 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_gunman","11e"); 212 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_gunmanbullet","11f"); 213 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_kurofukuhat","123"); 214 | WEAPON_TABLE.lock().unwrap().insert("duckhunt_reticle","122"); 215 | WEAPON_TABLE.lock().unwrap().insert("edge_background","24b"); 216 | WEAPON_TABLE.lock().unwrap().insert("edge_fire","246"); 217 | WEAPON_TABLE.lock().unwrap().insert("edge_flare1","248"); 218 | WEAPON_TABLE.lock().unwrap().insert("edge_flare2","249"); 219 | WEAPON_TABLE.lock().unwrap().insert("edge_flaredummy","24a"); 220 | WEAPON_TABLE.lock().unwrap().insert("edge_flash","247"); 221 | WEAPON_TABLE.lock().unwrap().insert("eflame_blazepillar","24e"); 222 | WEAPON_TABLE.lock().unwrap().insert("eflame_esword","24c"); 223 | WEAPON_TABLE.lock().unwrap().insert("eflame_firepillar","24d"); 224 | WEAPON_TABLE.lock().unwrap().insert("eflame_windummy","24f"); 225 | WEAPON_TABLE.lock().unwrap().insert("eflame_winsword","250"); 226 | WEAPON_TABLE.lock().unwrap().insert("element_changer","1cf"); 227 | WEAPON_TABLE.lock().unwrap().insert("element_diver","1d0"); 228 | WEAPON_TABLE.lock().unwrap().insert("elight_beam","256"); 229 | WEAPON_TABLE.lock().unwrap().insert("elight_bunshin","252"); 230 | WEAPON_TABLE.lock().unwrap().insert("elight_esword","251"); 231 | WEAPON_TABLE.lock().unwrap().insert("elight_exprosiveshot","253"); 232 | WEAPON_TABLE.lock().unwrap().insert("elight_meteor","255"); 233 | WEAPON_TABLE.lock().unwrap().insert("elight_spreadbullet","254"); 234 | WEAPON_TABLE.lock().unwrap().insert("elight_windummy","257"); 235 | WEAPON_TABLE.lock().unwrap().insert("elight_winsword","258"); 236 | WEAPON_TABLE.lock().unwrap().insert("enemy_yellowdevil_beam","1c7"); 237 | WEAPON_TABLE.lock().unwrap().insert("falco_arwing","87"); 238 | WEAPON_TABLE.lock().unwrap().insert("falco_arwingshot","89"); 239 | WEAPON_TABLE.lock().unwrap().insert("falco_blaster","84"); 240 | WEAPON_TABLE.lock().unwrap().insert("falco_blaster_bullet","85"); 241 | WEAPON_TABLE.lock().unwrap().insert("falco_illusion","86"); 242 | WEAPON_TABLE.lock().unwrap().insert("falco_reticle","88"); 243 | WEAPON_TABLE.lock().unwrap().insert("fox_arwing","5c"); 244 | WEAPON_TABLE.lock().unwrap().insert("fox_arwingshot","5e"); 245 | WEAPON_TABLE.lock().unwrap().insert("fox_blaster","59"); 246 | WEAPON_TABLE.lock().unwrap().insert("fox_blaster_bullet","5a"); 247 | WEAPON_TABLE.lock().unwrap().insert("fox_illusion","5b"); 248 | WEAPON_TABLE.lock().unwrap().insert("fox_reticle","5d"); 249 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_bomb","80"); 250 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_breath","7e"); 251 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_entry","7f"); 252 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_food","77"); 253 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_normal_weapon","7d"); 254 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_octopus","7c"); 255 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_oil","7b"); 256 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_panel","7a"); 257 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_parachute","79"); 258 | WEAPON_TABLE.lock().unwrap().insert("gamewatch_rescue","78"); 259 | WEAPON_TABLE.lock().unwrap().insert("ganon_beast","82"); 260 | WEAPON_TABLE.lock().unwrap().insert("ganon_ganond","83"); 261 | WEAPON_TABLE.lock().unwrap().insert("ganon_sword","81"); 262 | WEAPON_TABLE.lock().unwrap().insert("gaogaen_championbelt","1bb"); 263 | WEAPON_TABLE.lock().unwrap().insert("gaogaen_monsterball","1bc"); 264 | WEAPON_TABLE.lock().unwrap().insert("gaogaen_rope","1ba"); 265 | WEAPON_TABLE.lock().unwrap().insert("gaogaen_rope2","1bd"); 266 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_bunshin","13c"); 267 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_gekkougas","13d"); 268 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_monsterball","13b"); 269 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_moon","13a"); 270 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_shuriken","137"); 271 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_tatami","139"); 272 | WEAPON_TABLE.lock().unwrap().insert("gekkouga_water","138"); 273 | WEAPON_TABLE.lock().unwrap().insert("ike_sword","b3"); 274 | WEAPON_TABLE.lock().unwrap().insert("inkling_blaster","18b"); 275 | WEAPON_TABLE.lock().unwrap().insert("inkling_brush","18a"); 276 | WEAPON_TABLE.lock().unwrap().insert("inkling_copy_inklinggun","18f"); 277 | WEAPON_TABLE.lock().unwrap().insert("inkling_copy_inklingtank","190"); 278 | WEAPON_TABLE.lock().unwrap().insert("inkling_inkbullet","185"); 279 | WEAPON_TABLE.lock().unwrap().insert("inkling_megaphonelaser","18e"); 280 | WEAPON_TABLE.lock().unwrap().insert("inkling_roller","188"); 281 | WEAPON_TABLE.lock().unwrap().insert("inkling_rollerink","189"); 282 | WEAPON_TABLE.lock().unwrap().insert("inkling_slosher","18c"); 283 | WEAPON_TABLE.lock().unwrap().insert("inkling_splash","18d"); 284 | WEAPON_TABLE.lock().unwrap().insert("inkling_splashbomb","186"); 285 | WEAPON_TABLE.lock().unwrap().insert("inkling_squid","187"); 286 | WEAPON_TABLE.lock().unwrap().insert("jack_background","1f4"); 287 | WEAPON_TABLE.lock().unwrap().insert("jack_bus","1f3"); 288 | WEAPON_TABLE.lock().unwrap().insert("jack_doyle","1ec"); 289 | WEAPON_TABLE.lock().unwrap().insert("jack_fire","1ed"); 290 | WEAPON_TABLE.lock().unwrap().insert("jack_fire2","1ee"); 291 | WEAPON_TABLE.lock().unwrap().insert("jack_mona","1ef"); 292 | WEAPON_TABLE.lock().unwrap().insert("jack_windummy","1f2"); 293 | WEAPON_TABLE.lock().unwrap().insert("jack_wing","1f0"); 294 | WEAPON_TABLE.lock().unwrap().insert("jack_wirerope","1f1"); 295 | WEAPON_TABLE.lock().unwrap().insert("kamui_dragonhand","175"); 296 | WEAPON_TABLE.lock().unwrap().insert("kamui_ryusensya","174"); 297 | WEAPON_TABLE.lock().unwrap().insert("kamui_spearhand","176"); 298 | WEAPON_TABLE.lock().unwrap().insert("kamui_waterdragon","177"); 299 | WEAPON_TABLE.lock().unwrap().insert("kamui_waterstream","178"); 300 | WEAPON_TABLE.lock().unwrap().insert("ken_hadoken","15e"); 301 | WEAPON_TABLE.lock().unwrap().insert("ken_shinkuhadoken","15f"); 302 | WEAPON_TABLE.lock().unwrap().insert("ken_shinryuken","160"); 303 | WEAPON_TABLE.lock().unwrap().insert("kirby_finalcutter","4b"); 304 | WEAPON_TABLE.lock().unwrap().insert("kirby_finalcuttershot","3d"); 305 | WEAPON_TABLE.lock().unwrap().insert("kirby_hammer","3c"); 306 | WEAPON_TABLE.lock().unwrap().insert("kirby_hat","3f"); 307 | WEAPON_TABLE.lock().unwrap().insert("kirby_miipartshead","45"); 308 | WEAPON_TABLE.lock().unwrap().insert("kirby_reserve","43"); 309 | WEAPON_TABLE.lock().unwrap().insert("kirby_rosettaticomissile","46"); 310 | WEAPON_TABLE.lock().unwrap().insert("kirby_simple","44"); 311 | WEAPON_TABLE.lock().unwrap().insert("kirby_simple2l","49"); 312 | WEAPON_TABLE.lock().unwrap().insert("kirby_simple2r","48"); 313 | WEAPON_TABLE.lock().unwrap().insert("kirby_starmissile","3e"); 314 | WEAPON_TABLE.lock().unwrap().insert("kirby_stone","47"); 315 | WEAPON_TABLE.lock().unwrap().insert("kirby_ultrasword","40"); 316 | WEAPON_TABLE.lock().unwrap().insert("kirby_ultraswordhat","41"); 317 | WEAPON_TABLE.lock().unwrap().insert("kirby_warpstar","42"); 318 | WEAPON_TABLE.lock().unwrap().insert("kirby_windummy","4a"); 319 | WEAPON_TABLE.lock().unwrap().insert("koopag_breath","1b9"); 320 | WEAPON_TABLE.lock().unwrap().insert("koopajr_batten","133"); 321 | WEAPON_TABLE.lock().unwrap().insert("koopajr_cannonball","12f"); 322 | WEAPON_TABLE.lock().unwrap().insert("koopajr_hammer","12c"); 323 | WEAPON_TABLE.lock().unwrap().insert("koopajr_kart","130"); 324 | WEAPON_TABLE.lock().unwrap().insert("koopajr_magichand","12e"); 325 | WEAPON_TABLE.lock().unwrap().insert("koopajr_picopicohammer","12d"); 326 | WEAPON_TABLE.lock().unwrap().insert("koopajr_remainclown","131"); 327 | WEAPON_TABLE.lock().unwrap().insert("koopajr_shadowmario","132"); 328 | WEAPON_TABLE.lock().unwrap().insert("koopa_breath","6d"); 329 | WEAPON_TABLE.lock().unwrap().insert("koopa_koopag","6e"); 330 | WEAPON_TABLE.lock().unwrap().insert("krool_backpack","1a0"); 331 | WEAPON_TABLE.lock().unwrap().insert("krool_blunderbuss","1a3"); 332 | WEAPON_TABLE.lock().unwrap().insert("krool_crown","1a1"); 333 | WEAPON_TABLE.lock().unwrap().insert("krool_ironball","1a4"); 334 | WEAPON_TABLE.lock().unwrap().insert("krool_piratehat","1a2"); 335 | WEAPON_TABLE.lock().unwrap().insert("krool_spitball","1a5"); 336 | WEAPON_TABLE.lock().unwrap().insert("link_ancient_bow","22"); 337 | WEAPON_TABLE.lock().unwrap().insert("link_ancient_bowarrow","23"); 338 | WEAPON_TABLE.lock().unwrap().insert("link_boomerang","1d"); 339 | WEAPON_TABLE.lock().unwrap().insert("link_bow","1e"); 340 | WEAPON_TABLE.lock().unwrap().insert("link_bowarrow","1f"); 341 | WEAPON_TABLE.lock().unwrap().insert("link_navy","20"); 342 | WEAPON_TABLE.lock().unwrap().insert("link_parasail","24"); 343 | WEAPON_TABLE.lock().unwrap().insert("link_sword_beam","21"); 344 | WEAPON_TABLE.lock().unwrap().insert("littlemac_championbelt","f6"); 345 | WEAPON_TABLE.lock().unwrap().insert("littlemac_doclouis","f3"); 346 | WEAPON_TABLE.lock().unwrap().insert("littlemac_littlemacg","f7"); 347 | WEAPON_TABLE.lock().unwrap().insert("littlemac_sweatlittlemac","f4"); 348 | WEAPON_TABLE.lock().unwrap().insert("littlemac_throwsweat","f5"); 349 | WEAPON_TABLE.lock().unwrap().insert("lucario_auraball","b4"); 350 | WEAPON_TABLE.lock().unwrap().insert("lucario_lucariom","b6"); 351 | WEAPON_TABLE.lock().unwrap().insert("lucario_qigong","b5"); 352 | WEAPON_TABLE.lock().unwrap().insert("lucas_bonnie","16a"); 353 | WEAPON_TABLE.lock().unwrap().insert("lucas_doseitable","167"); 354 | WEAPON_TABLE.lock().unwrap().insert("lucas_himohebi","165"); 355 | WEAPON_TABLE.lock().unwrap().insert("lucas_himohebi2","166"); 356 | WEAPON_TABLE.lock().unwrap().insert("lucas_kumatora","169"); 357 | WEAPON_TABLE.lock().unwrap().insert("lucas_needle","168"); 358 | WEAPON_TABLE.lock().unwrap().insert("lucas_pk_fire","162"); 359 | WEAPON_TABLE.lock().unwrap().insert("lucas_pk_freeze","161"); 360 | WEAPON_TABLE.lock().unwrap().insert("lucas_pk_starstorm","164"); 361 | WEAPON_TABLE.lock().unwrap().insert("lucas_pk_thunder","163"); 362 | WEAPON_TABLE.lock().unwrap().insert("lucina_mask","e3"); 363 | WEAPON_TABLE.lock().unwrap().insert("luigi_dokan","54"); 364 | WEAPON_TABLE.lock().unwrap().insert("luigi_fireball","53"); 365 | WEAPON_TABLE.lock().unwrap().insert("luigi_obakyumu","55"); 366 | WEAPON_TABLE.lock().unwrap().insert("luigi_plunger","56"); 367 | WEAPON_TABLE.lock().unwrap().insert("mariod_capsuleblock","db"); 368 | WEAPON_TABLE.lock().unwrap().insert("mariod_drcapsule","d7"); 369 | WEAPON_TABLE.lock().unwrap().insert("mariod_drmantle","d8"); 370 | WEAPON_TABLE.lock().unwrap().insert("mariod_huge_capsule","da"); 371 | WEAPON_TABLE.lock().unwrap().insert("mariod_stethoscope","d9"); 372 | WEAPON_TABLE.lock().unwrap().insert("mario_cappy","1b"); 373 | WEAPON_TABLE.lock().unwrap().insert("mario_dokan","1a"); 374 | WEAPON_TABLE.lock().unwrap().insert("mario_fireball","15"); 375 | WEAPON_TABLE.lock().unwrap().insert("mario_huge_flame","19"); 376 | WEAPON_TABLE.lock().unwrap().insert("mario_mantle","16"); 377 | WEAPON_TABLE.lock().unwrap().insert("mario_pump","17"); 378 | WEAPON_TABLE.lock().unwrap().insert("mario_pump_water","18"); 379 | WEAPON_TABLE.lock().unwrap().insert("master_arrow1","20e"); 380 | WEAPON_TABLE.lock().unwrap().insert("master_arrow2","20f"); 381 | WEAPON_TABLE.lock().unwrap().insert("master_axe","20c"); 382 | WEAPON_TABLE.lock().unwrap().insert("master_background","213"); 383 | WEAPON_TABLE.lock().unwrap().insert("master_baton","212"); 384 | WEAPON_TABLE.lock().unwrap().insert("master_bow","20d"); 385 | WEAPON_TABLE.lock().unwrap().insert("master_spear","210"); 386 | WEAPON_TABLE.lock().unwrap().insert("master_sword","211"); 387 | WEAPON_TABLE.lock().unwrap().insert("master_sword2","214"); 388 | WEAPON_TABLE.lock().unwrap().insert("master_swordflare","215"); 389 | WEAPON_TABLE.lock().unwrap().insert("metaknight_bunshin","8e"); 390 | WEAPON_TABLE.lock().unwrap().insert("metaknight_fourwings","8f"); 391 | WEAPON_TABLE.lock().unwrap().insert("metaknight_mantle","8d"); 392 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_bindball","156"); 393 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_escapeairdummy","15a"); 394 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_mewtwom","157"); 395 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_psychobreak","159"); 396 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_search","158"); 397 | WEAPON_TABLE.lock().unwrap().insert("mewtwo_shadowball","155"); 398 | WEAPON_TABLE.lock().unwrap().insert("miienemyg_attackairf_bullet","1c8"); 399 | WEAPON_TABLE.lock().unwrap().insert("miienemyg_rapidshot_bullet","1c9"); 400 | WEAPON_TABLE.lock().unwrap().insert("miifighter_hat","0"); 401 | WEAPON_TABLE.lock().unwrap().insert("miifighter_ironball","1"); 402 | WEAPON_TABLE.lock().unwrap().insert("miigunner_attackairf_bullet","12"); 403 | WEAPON_TABLE.lock().unwrap().insert("miigunner_bottomshoot","10"); 404 | WEAPON_TABLE.lock().unwrap().insert("miigunner_flamepillar","d"); 405 | WEAPON_TABLE.lock().unwrap().insert("miigunner_fullthrottle","14"); 406 | WEAPON_TABLE.lock().unwrap().insert("miigunner_grenadelauncher","c"); 407 | WEAPON_TABLE.lock().unwrap().insert("miigunner_groundbomb","11"); 408 | WEAPON_TABLE.lock().unwrap().insert("miigunner_gunnercharge","9"); 409 | WEAPON_TABLE.lock().unwrap().insert("miigunner_hat","7"); 410 | WEAPON_TABLE.lock().unwrap().insert("miigunner_laser","13"); 411 | WEAPON_TABLE.lock().unwrap().insert("miigunner_miimissile","a"); 412 | WEAPON_TABLE.lock().unwrap().insert("miigunner_rapidshot_bullet","8"); 413 | WEAPON_TABLE.lock().unwrap().insert("miigunner_stealthbomb","e"); 414 | WEAPON_TABLE.lock().unwrap().insert("miigunner_stealthbomb_s","f"); 415 | WEAPON_TABLE.lock().unwrap().insert("miigunner_supermissile","b"); 416 | WEAPON_TABLE.lock().unwrap().insert("miiswordsman_chakram","4"); 417 | WEAPON_TABLE.lock().unwrap().insert("miiswordsman_hat","2"); 418 | WEAPON_TABLE.lock().unwrap().insert("miiswordsman_lightshuriken","3"); 419 | WEAPON_TABLE.lock().unwrap().insert("miiswordsman_tornadoshot","5"); 420 | WEAPON_TABLE.lock().unwrap().insert("miiswordsman_wave","6"); 421 | WEAPON_TABLE.lock().unwrap().insert("murabito_balloon","100"); 422 | WEAPON_TABLE.lock().unwrap().insert("murabito_beetle","10e"); 423 | WEAPON_TABLE.lock().unwrap().insert("murabito_bowling_ball","fa"); 424 | WEAPON_TABLE.lock().unwrap().insert("murabito_bullet","fd"); 425 | WEAPON_TABLE.lock().unwrap().insert("murabito_butterflynet","ff"); 426 | WEAPON_TABLE.lock().unwrap().insert("murabito_clayrocket","101"); 427 | WEAPON_TABLE.lock().unwrap().insert("murabito_firework","fb"); 428 | WEAPON_TABLE.lock().unwrap().insert("murabito_flowerpot","f8"); 429 | WEAPON_TABLE.lock().unwrap().insert("murabito_furniture","10c"); 430 | WEAPON_TABLE.lock().unwrap().insert("murabito_helmet","107"); 431 | WEAPON_TABLE.lock().unwrap().insert("murabito_house","10b"); 432 | WEAPON_TABLE.lock().unwrap().insert("murabito_moneybag","10d"); 433 | WEAPON_TABLE.lock().unwrap().insert("murabito_seed","102"); 434 | WEAPON_TABLE.lock().unwrap().insert("murabito_slingshot","fc"); 435 | WEAPON_TABLE.lock().unwrap().insert("murabito_sprinkling_water","106"); 436 | WEAPON_TABLE.lock().unwrap().insert("murabito_sprout","103"); 437 | WEAPON_TABLE.lock().unwrap().insert("murabito_stump","105"); 438 | WEAPON_TABLE.lock().unwrap().insert("murabito_timmy","10a"); 439 | WEAPON_TABLE.lock().unwrap().insert("murabito_tommy","109"); 440 | WEAPON_TABLE.lock().unwrap().insert("murabito_tomnook","108"); 441 | WEAPON_TABLE.lock().unwrap().insert("murabito_tree","104"); 442 | WEAPON_TABLE.lock().unwrap().insert("murabito_umbrella","f9"); 443 | WEAPON_TABLE.lock().unwrap().insert("murabito_weeds","fe"); 444 | WEAPON_TABLE.lock().unwrap().insert("ness_paula","63"); 445 | WEAPON_TABLE.lock().unwrap().insert("ness_pk_fire","60"); 446 | WEAPON_TABLE.lock().unwrap().insert("ness_pk_flash","5f"); 447 | WEAPON_TABLE.lock().unwrap().insert("ness_pk_starstorm","62"); 448 | WEAPON_TABLE.lock().unwrap().insert("ness_pk_thunder","61"); 449 | WEAPON_TABLE.lock().unwrap().insert("ness_poo","64"); 450 | WEAPON_TABLE.lock().unwrap().insert("ness_yoyo","65"); 451 | WEAPON_TABLE.lock().unwrap().insert("ness_yoyo_head","66"); 452 | WEAPON_TABLE.lock().unwrap().insert("none","ffffffff"); 453 | WEAPON_TABLE.lock().unwrap().insert("packun_bosspackun","1eb"); 454 | WEAPON_TABLE.lock().unwrap().insert("packun_mario","1ea"); 455 | WEAPON_TABLE.lock().unwrap().insert("packun_poisonbreath","1e9"); 456 | WEAPON_TABLE.lock().unwrap().insert("packun_spikeball","1e8"); 457 | WEAPON_TABLE.lock().unwrap().insert("pacman_artisticpoint","143"); 458 | WEAPON_TABLE.lock().unwrap().insert("pacman_bigpacman","142"); 459 | WEAPON_TABLE.lock().unwrap().insert("pacman_esa","13e"); 460 | WEAPON_TABLE.lock().unwrap().insert("pacman_fairy","144"); 461 | WEAPON_TABLE.lock().unwrap().insert("pacman_firehydrant","140"); 462 | WEAPON_TABLE.lock().unwrap().insert("pacman_firehydrant_water","141"); 463 | WEAPON_TABLE.lock().unwrap().insert("pacman_trampoline","13f"); 464 | WEAPON_TABLE.lock().unwrap().insert("palutena_autoaimbullet","112"); 465 | WEAPON_TABLE.lock().unwrap().insert("palutena_autoreticle","113"); 466 | WEAPON_TABLE.lock().unwrap().insert("palutena_beam","116"); 467 | WEAPON_TABLE.lock().unwrap().insert("palutena_blackhole","115"); 468 | WEAPON_TABLE.lock().unwrap().insert("palutena_explosiveflame","110"); 469 | WEAPON_TABLE.lock().unwrap().insert("palutena_explosiveflame_reserve","111"); 470 | WEAPON_TABLE.lock().unwrap().insert("palutena_gate","117"); 471 | WEAPON_TABLE.lock().unwrap().insert("palutena_godwing","10f"); 472 | WEAPON_TABLE.lock().unwrap().insert("palutena_reflectionboard","114"); 473 | WEAPON_TABLE.lock().unwrap().insert("peach_kassar","67"); 474 | WEAPON_TABLE.lock().unwrap().insert("peach_kinopio","68"); 475 | WEAPON_TABLE.lock().unwrap().insert("peach_kinopiospore","69"); 476 | WEAPON_TABLE.lock().unwrap().insert("pfushigisou_leafcutter","183"); 477 | WEAPON_TABLE.lock().unwrap().insert("pfushigisou_seed","182"); 478 | WEAPON_TABLE.lock().unwrap().insert("pfushigisou_vine","184"); 479 | WEAPON_TABLE.lock().unwrap().insert("pichu_cloud","df"); 480 | WEAPON_TABLE.lock().unwrap().insert("pichu_dengeki","dd"); 481 | WEAPON_TABLE.lock().unwrap().insert("pichu_dengekidama","dc"); 482 | WEAPON_TABLE.lock().unwrap().insert("pichu_kaminari","de"); 483 | WEAPON_TABLE.lock().unwrap().insert("pichu_monsterball","e1"); 484 | WEAPON_TABLE.lock().unwrap().insert("pichu_specialupdummy","e2"); 485 | WEAPON_TABLE.lock().unwrap().insert("pichu_vortex","e0"); 486 | WEAPON_TABLE.lock().unwrap().insert("pickel_axe","23b"); 487 | WEAPON_TABLE.lock().unwrap().insert("pickel_building","237"); 488 | WEAPON_TABLE.lock().unwrap().insert("pickel_crack","230"); 489 | WEAPON_TABLE.lock().unwrap().insert("pickel_entryobject","23f"); 490 | WEAPON_TABLE.lock().unwrap().insert("pickel_fence","242"); 491 | WEAPON_TABLE.lock().unwrap().insert("pickel_fire","243"); 492 | WEAPON_TABLE.lock().unwrap().insert("pickel_fishingrod","240"); 493 | WEAPON_TABLE.lock().unwrap().insert("pickel_forge","238"); 494 | WEAPON_TABLE.lock().unwrap().insert("pickel_maskfinal","244"); 495 | WEAPON_TABLE.lock().unwrap().insert("pickel_melt","241"); 496 | WEAPON_TABLE.lock().unwrap().insert("pickel_pick","23c"); 497 | WEAPON_TABLE.lock().unwrap().insert("pickel_plate","233"); 498 | WEAPON_TABLE.lock().unwrap().insert("pickel_pushfinal","245"); 499 | WEAPON_TABLE.lock().unwrap().insert("pickel_pushobject","23e"); 500 | WEAPON_TABLE.lock().unwrap().insert("pickel_rail","232"); 501 | WEAPON_TABLE.lock().unwrap().insert("pickel_scarier","239"); 502 | WEAPON_TABLE.lock().unwrap().insert("pickel_shovel","23d"); 503 | WEAPON_TABLE.lock().unwrap().insert("pickel_stone","234"); 504 | WEAPON_TABLE.lock().unwrap().insert("pickel_stuff","236"); 505 | WEAPON_TABLE.lock().unwrap().insert("pickel_sword","23a"); 506 | WEAPON_TABLE.lock().unwrap().insert("pickel_table","235"); 507 | WEAPON_TABLE.lock().unwrap().insert("pickel_trolley","231"); 508 | WEAPON_TABLE.lock().unwrap().insert("pickel_wing","22f"); 509 | WEAPON_TABLE.lock().unwrap().insert("pikachu_cloud","4f"); 510 | WEAPON_TABLE.lock().unwrap().insert("pikachu_dengeki","4d"); 511 | WEAPON_TABLE.lock().unwrap().insert("pikachu_dengekidama","4c"); 512 | WEAPON_TABLE.lock().unwrap().insert("pikachu_kaminari","4e"); 513 | WEAPON_TABLE.lock().unwrap().insert("pikachu_monsterball","51"); 514 | WEAPON_TABLE.lock().unwrap().insert("pikachu_specialupdummy","52"); 515 | WEAPON_TABLE.lock().unwrap().insert("pikachu_vortex","50"); 516 | WEAPON_TABLE.lock().unwrap().insert("pikmin_dolfin","9e"); 517 | WEAPON_TABLE.lock().unwrap().insert("pikmin_pikmin","9d"); 518 | WEAPON_TABLE.lock().unwrap().insert("pikmin_win1","9f"); 519 | WEAPON_TABLE.lock().unwrap().insert("pikmin_win2","a0"); 520 | WEAPON_TABLE.lock().unwrap().insert("pikmin_win3","a1"); 521 | WEAPON_TABLE.lock().unwrap().insert("pitb_bow","e4"); 522 | WEAPON_TABLE.lock().unwrap().insert("pitb_bowarrow","e5"); 523 | WEAPON_TABLE.lock().unwrap().insert("pit_bow","90"); 524 | WEAPON_TABLE.lock().unwrap().insert("pit_bowarrow","91"); 525 | WEAPON_TABLE.lock().unwrap().insert("pit_chariot","92"); 526 | WEAPON_TABLE.lock().unwrap().insert("pit_chariotsight","94"); 527 | WEAPON_TABLE.lock().unwrap().insert("pit_horse","93"); 528 | WEAPON_TABLE.lock().unwrap().insert("plizardon_breath","ce"); 529 | WEAPON_TABLE.lock().unwrap().insert("plizardon_daimonji","d0"); 530 | WEAPON_TABLE.lock().unwrap().insert("plizardon_explosion","cf"); 531 | WEAPON_TABLE.lock().unwrap().insert("popo_blizzard","17a"); 532 | WEAPON_TABLE.lock().unwrap().insert("popo_condor","179"); 533 | WEAPON_TABLE.lock().unwrap().insert("popo_iceberg","17d"); 534 | WEAPON_TABLE.lock().unwrap().insert("popo_iceberg_hit","17f"); 535 | WEAPON_TABLE.lock().unwrap().insert("popo_iceberg_wind","17e"); 536 | WEAPON_TABLE.lock().unwrap().insert("popo_iceshot","17c"); 537 | WEAPON_TABLE.lock().unwrap().insert("popo_rubber","17b"); 538 | WEAPON_TABLE.lock().unwrap().insert("popo_whitebear","180"); 539 | WEAPON_TABLE.lock().unwrap().insert("ptrainer_mball","1cb"); 540 | WEAPON_TABLE.lock().unwrap().insert("ptrainer_pfushigisou","1cd"); 541 | WEAPON_TABLE.lock().unwrap().insert("ptrainer_plizardon","1ce"); 542 | WEAPON_TABLE.lock().unwrap().insert("ptrainer_ptrainer","1ca"); 543 | WEAPON_TABLE.lock().unwrap().insert("ptrainer_pzenigame","1cc"); 544 | WEAPON_TABLE.lock().unwrap().insert("purin_cap","d5"); 545 | WEAPON_TABLE.lock().unwrap().insert("purin_monsterball","d6"); 546 | WEAPON_TABLE.lock().unwrap().insert("pzenigame_water","181"); 547 | WEAPON_TABLE.lock().unwrap().insert("reflet_book","118"); 548 | WEAPON_TABLE.lock().unwrap().insert("reflet_chrom","11d"); 549 | WEAPON_TABLE.lock().unwrap().insert("reflet_elwind","11b"); 550 | WEAPON_TABLE.lock().unwrap().insert("reflet_gigafire","11c"); 551 | WEAPON_TABLE.lock().unwrap().insert("reflet_thunder","11a"); 552 | WEAPON_TABLE.lock().unwrap().insert("reflet_window","119"); 553 | WEAPON_TABLE.lock().unwrap().insert("richter_axe","1bf"); 554 | WEAPON_TABLE.lock().unwrap().insert("richter_coffin","1c1"); 555 | WEAPON_TABLE.lock().unwrap().insert("richter_cross","1c0"); 556 | WEAPON_TABLE.lock().unwrap().insert("richter_crystal","1c2"); 557 | WEAPON_TABLE.lock().unwrap().insert("richter_stake","1c6"); 558 | WEAPON_TABLE.lock().unwrap().insert("richter_whip","1be"); 559 | WEAPON_TABLE.lock().unwrap().insert("richter_whip2","1c3"); 560 | WEAPON_TABLE.lock().unwrap().insert("richter_whiphand","1c4"); 561 | WEAPON_TABLE.lock().unwrap().insert("richter_whipwire","1c5"); 562 | WEAPON_TABLE.lock().unwrap().insert("ridley_breath","1b7"); 563 | WEAPON_TABLE.lock().unwrap().insert("ridley_gunship","1b8"); 564 | WEAPON_TABLE.lock().unwrap().insert("robot_beam","b9"); 565 | WEAPON_TABLE.lock().unwrap().insert("robot_final_beam","ba"); 566 | WEAPON_TABLE.lock().unwrap().insert("robot_gyro","b7"); 567 | WEAPON_TABLE.lock().unwrap().insert("robot_gyro_holder","b8"); 568 | WEAPON_TABLE.lock().unwrap().insert("robot_hominglaser","bf"); 569 | WEAPON_TABLE.lock().unwrap().insert("robot_homingtarget","c0"); 570 | WEAPON_TABLE.lock().unwrap().insert("robot_hugebeam","bb"); 571 | WEAPON_TABLE.lock().unwrap().insert("robot_mainlaser","be"); 572 | WEAPON_TABLE.lock().unwrap().insert("robot_narrowbeam","bc"); 573 | WEAPON_TABLE.lock().unwrap().insert("robot_widebeam","bd"); 574 | WEAPON_TABLE.lock().unwrap().insert("rockman_airshooter","154"); 575 | WEAPON_TABLE.lock().unwrap().insert("rockman_blackhole","14b"); 576 | WEAPON_TABLE.lock().unwrap().insert("rockman_bruce","150"); 577 | WEAPON_TABLE.lock().unwrap().insert("rockman_chargeshot","149"); 578 | WEAPON_TABLE.lock().unwrap().insert("rockman_crashbomb","146"); 579 | WEAPON_TABLE.lock().unwrap().insert("rockman_forte","151"); 580 | WEAPON_TABLE.lock().unwrap().insert("rockman_hardknuckle","14a"); 581 | WEAPON_TABLE.lock().unwrap().insert("rockman_leafshield","148"); 582 | WEAPON_TABLE.lock().unwrap().insert("rockman_leftarm","152"); 583 | WEAPON_TABLE.lock().unwrap().insert("rockman_rightarm","153"); 584 | WEAPON_TABLE.lock().unwrap().insert("rockman_rockbuster","145"); 585 | WEAPON_TABLE.lock().unwrap().insert("rockman_rockmandash","14d"); 586 | WEAPON_TABLE.lock().unwrap().insert("rockman_rockmanexe","14e"); 587 | WEAPON_TABLE.lock().unwrap().insert("rockman_rockmanx","14c"); 588 | WEAPON_TABLE.lock().unwrap().insert("rockman_rushcoil","147"); 589 | WEAPON_TABLE.lock().unwrap().insert("rockman_shootingstarrockman","14f"); 590 | WEAPON_TABLE.lock().unwrap().insert("rosetta_meteor","eb"); 591 | WEAPON_TABLE.lock().unwrap().insert("rosetta_pointer","e9"); 592 | WEAPON_TABLE.lock().unwrap().insert("rosetta_powerstar","ea"); 593 | WEAPON_TABLE.lock().unwrap().insert("rosetta_ring","e8"); 594 | WEAPON_TABLE.lock().unwrap().insert("rosetta_starpiece","e7"); 595 | WEAPON_TABLE.lock().unwrap().insert("rosetta_tico","e6"); 596 | WEAPON_TABLE.lock().unwrap().insert("roy_sword","16b"); 597 | WEAPON_TABLE.lock().unwrap().insert("ryu_hadoken","15b"); 598 | WEAPON_TABLE.lock().unwrap().insert("ryu_sack","15d"); 599 | WEAPON_TABLE.lock().unwrap().insert("ryu_shinkuhadoken","15c"); 600 | WEAPON_TABLE.lock().unwrap().insert("samusd_bomb","2f"); 601 | WEAPON_TABLE.lock().unwrap().insert("samusd_bunshin","37"); 602 | WEAPON_TABLE.lock().unwrap().insert("samusd_cshot","2e"); 603 | WEAPON_TABLE.lock().unwrap().insert("samusd_gbeam","36"); 604 | WEAPON_TABLE.lock().unwrap().insert("samusd_gun","33"); 605 | WEAPON_TABLE.lock().unwrap().insert("samusd_laser","31"); 606 | WEAPON_TABLE.lock().unwrap().insert("samusd_laser2","32"); 607 | WEAPON_TABLE.lock().unwrap().insert("samusd_missile","30"); 608 | WEAPON_TABLE.lock().unwrap().insert("samusd_supermissile","34"); 609 | WEAPON_TABLE.lock().unwrap().insert("samusd_transportation","35"); 610 | WEAPON_TABLE.lock().unwrap().insert("samus_bomb","26"); 611 | WEAPON_TABLE.lock().unwrap().insert("samus_cshot","25"); 612 | WEAPON_TABLE.lock().unwrap().insert("samus_gbeam","2d"); 613 | WEAPON_TABLE.lock().unwrap().insert("samus_gun","2a"); 614 | WEAPON_TABLE.lock().unwrap().insert("samus_laser","28"); 615 | WEAPON_TABLE.lock().unwrap().insert("samus_laser2","29"); 616 | WEAPON_TABLE.lock().unwrap().insert("samus_missile","27"); 617 | WEAPON_TABLE.lock().unwrap().insert("samus_supermissile","2b"); 618 | WEAPON_TABLE.lock().unwrap().insert("samus_transportation","2c"); 619 | WEAPON_TABLE.lock().unwrap().insert("sheik_fusin","75"); 620 | WEAPON_TABLE.lock().unwrap().insert("sheik_knife","76"); 621 | WEAPON_TABLE.lock().unwrap().insert("sheik_needle","73"); 622 | WEAPON_TABLE.lock().unwrap().insert("sheik_needlehave","74"); 623 | WEAPON_TABLE.lock().unwrap().insert("shizue_balloon","1d7"); 624 | WEAPON_TABLE.lock().unwrap().insert("shizue_broom","1e0"); 625 | WEAPON_TABLE.lock().unwrap().insert("shizue_bucket","1e2"); 626 | WEAPON_TABLE.lock().unwrap().insert("shizue_bullet","1d6"); 627 | WEAPON_TABLE.lock().unwrap().insert("shizue_butterflynet","1d8"); 628 | WEAPON_TABLE.lock().unwrap().insert("shizue_clayrocket","1e5"); 629 | WEAPON_TABLE.lock().unwrap().insert("shizue_cracker","1e1"); 630 | WEAPON_TABLE.lock().unwrap().insert("shizue_fishingline","1e7"); 631 | WEAPON_TABLE.lock().unwrap().insert("shizue_fishingrod","1e6"); 632 | WEAPON_TABLE.lock().unwrap().insert("shizue_furniture","1dd"); 633 | WEAPON_TABLE.lock().unwrap().insert("shizue_moneybag","1de"); 634 | WEAPON_TABLE.lock().unwrap().insert("shizue_office","1d9"); 635 | WEAPON_TABLE.lock().unwrap().insert("shizue_picopicohammer","1df"); 636 | WEAPON_TABLE.lock().unwrap().insert("shizue_pompon","1e3"); 637 | WEAPON_TABLE.lock().unwrap().insert("shizue_pot","1d1"); 638 | WEAPON_TABLE.lock().unwrap().insert("shizue_slingshot","1d5"); 639 | WEAPON_TABLE.lock().unwrap().insert("shizue_swing","1e4"); 640 | WEAPON_TABLE.lock().unwrap().insert("shizue_timmy","1dc"); 641 | WEAPON_TABLE.lock().unwrap().insert("shizue_tommy","1db"); 642 | WEAPON_TABLE.lock().unwrap().insert("shizue_tomnook","1da"); 643 | WEAPON_TABLE.lock().unwrap().insert("shizue_trafficsign","1d4"); 644 | WEAPON_TABLE.lock().unwrap().insert("shizue_umbrella","1d2"); 645 | WEAPON_TABLE.lock().unwrap().insert("shizue_weeds","1d3"); 646 | WEAPON_TABLE.lock().unwrap().insert("shulk_dunban","134"); 647 | WEAPON_TABLE.lock().unwrap().insert("shulk_fiora","136"); 648 | WEAPON_TABLE.lock().unwrap().insert("shulk_riki","135"); 649 | WEAPON_TABLE.lock().unwrap().insert("simon_axe","1ae"); 650 | WEAPON_TABLE.lock().unwrap().insert("simon_coffin","1b0"); 651 | WEAPON_TABLE.lock().unwrap().insert("simon_cross","1af"); 652 | WEAPON_TABLE.lock().unwrap().insert("simon_crystal","1b1"); 653 | WEAPON_TABLE.lock().unwrap().insert("simon_stake","1b5"); 654 | WEAPON_TABLE.lock().unwrap().insert("simon_whip","1ad"); 655 | WEAPON_TABLE.lock().unwrap().insert("simon_whip2","1b2"); 656 | WEAPON_TABLE.lock().unwrap().insert("simon_whiphand","1b3"); 657 | WEAPON_TABLE.lock().unwrap().insert("simon_whipwire","1b4"); 658 | WEAPON_TABLE.lock().unwrap().insert("snake_c4","197"); 659 | WEAPON_TABLE.lock().unwrap().insert("snake_c4_switch","198"); 660 | WEAPON_TABLE.lock().unwrap().insert("snake_cypher","196"); 661 | WEAPON_TABLE.lock().unwrap().insert("snake_flare_grenades","19a"); 662 | WEAPON_TABLE.lock().unwrap().insert("snake_grenade","199"); 663 | WEAPON_TABLE.lock().unwrap().insert("snake_lock_on_cursor","19d"); 664 | WEAPON_TABLE.lock().unwrap().insert("snake_lock_on_cursor_ready","19e"); 665 | WEAPON_TABLE.lock().unwrap().insert("snake_missile","19f"); 666 | WEAPON_TABLE.lock().unwrap().insert("snake_nikita","194"); 667 | WEAPON_TABLE.lock().unwrap().insert("snake_nikita_missile","195"); 668 | WEAPON_TABLE.lock().unwrap().insert("snake_reticle","19b"); 669 | WEAPON_TABLE.lock().unwrap().insert("snake_reticle_cursor","19c"); 670 | WEAPON_TABLE.lock().unwrap().insert("snake_rpg7","191"); 671 | WEAPON_TABLE.lock().unwrap().insert("snake_trenchmortar","192"); 672 | WEAPON_TABLE.lock().unwrap().insert("snake_trenchmortar_bullet","193"); 673 | WEAPON_TABLE.lock().unwrap().insert("sonic_chaosemerald","d4"); 674 | WEAPON_TABLE.lock().unwrap().insert("sonic_gimmickjump","d2"); 675 | WEAPON_TABLE.lock().unwrap().insert("sonic_homingtarget","d1"); 676 | WEAPON_TABLE.lock().unwrap().insert("sonic_supersonic","d3"); 677 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_gunship","99"); 678 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_laser","9b"); 679 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_paralyzer","97"); 680 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_paralyzer_bullet","95"); 681 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_reticle","9a"); 682 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_samusp","98"); 683 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_whip","96"); 684 | WEAPON_TABLE.lock().unwrap().insert("szerosuit_whip2","9c"); 685 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally1","21d"); 686 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally2","21e"); 687 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally3","21f"); 688 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally4","220"); 689 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally5","221"); 690 | WEAPON_TABLE.lock().unwrap().insert("tantan_ally6","222"); 691 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarm1","223"); 692 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarm2","224"); 693 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarm3","225"); 694 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarm5","226"); 695 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarm6","227"); 696 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarmbullet1","228"); 697 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarmbullet2","229"); 698 | WEAPON_TABLE.lock().unwrap().insert("tantan_allyarmbullet3","22a"); 699 | WEAPON_TABLE.lock().unwrap().insert("tantan_beam","21c"); 700 | WEAPON_TABLE.lock().unwrap().insert("tantan_gongfinal","22c"); 701 | WEAPON_TABLE.lock().unwrap().insert("tantan_punch1","218"); 702 | WEAPON_TABLE.lock().unwrap().insert("tantan_punch2","219"); 703 | WEAPON_TABLE.lock().unwrap().insert("tantan_punch3","21a"); 704 | WEAPON_TABLE.lock().unwrap().insert("tantan_ring","21b"); 705 | WEAPON_TABLE.lock().unwrap().insert("tantan_spiralleft","216"); 706 | WEAPON_TABLE.lock().unwrap().insert("tantan_spiralleftloupe","22d"); 707 | WEAPON_TABLE.lock().unwrap().insert("tantan_spiralright","217"); 708 | WEAPON_TABLE.lock().unwrap().insert("tantan_spiralrightloupe","22e"); 709 | WEAPON_TABLE.lock().unwrap().insert("tantan_spiralsimple","22b"); 710 | WEAPON_TABLE.lock().unwrap().insert("term","267"); 711 | WEAPON_TABLE.lock().unwrap().insert("toonlink_boomerang","c1"); 712 | WEAPON_TABLE.lock().unwrap().insert("toonlink_bow","c2"); 713 | WEAPON_TABLE.lock().unwrap().insert("toonlink_bowarrow","c3"); 714 | WEAPON_TABLE.lock().unwrap().insert("toonlink_fairy","c6"); 715 | WEAPON_TABLE.lock().unwrap().insert("toonlink_hookshot","c4"); 716 | WEAPON_TABLE.lock().unwrap().insert("toonlink_hookshot_hand","c5"); 717 | WEAPON_TABLE.lock().unwrap().insert("toonlink_pig","c8"); 718 | WEAPON_TABLE.lock().unwrap().insert("toonlink_takt","c7"); 719 | WEAPON_TABLE.lock().unwrap().insert("wario_garlic","8b"); 720 | WEAPON_TABLE.lock().unwrap().insert("wario_wariobike","8a"); 721 | WEAPON_TABLE.lock().unwrap().insert("wario_warioman","8c"); 722 | WEAPON_TABLE.lock().unwrap().insert("wiifit_balanceboard","ee"); 723 | WEAPON_TABLE.lock().unwrap().insert("wiifit_hulahoop","ec"); 724 | WEAPON_TABLE.lock().unwrap().insert("wiifit_silhouette","f1"); 725 | WEAPON_TABLE.lock().unwrap().insert("wiifit_silhouettel","f2"); 726 | WEAPON_TABLE.lock().unwrap().insert("wiifit_sunbullet","ed"); 727 | WEAPON_TABLE.lock().unwrap().insert("wiifit_towel","f0"); 728 | WEAPON_TABLE.lock().unwrap().insert("wiifit_wiibo","ef"); 729 | WEAPON_TABLE.lock().unwrap().insert("wolf_blaster","c9"); 730 | WEAPON_TABLE.lock().unwrap().insert("wolf_blaster_bullet","ca"); 731 | WEAPON_TABLE.lock().unwrap().insert("wolf_illusion","cb"); 732 | WEAPON_TABLE.lock().unwrap().insert("wolf_reticle","cd"); 733 | WEAPON_TABLE.lock().unwrap().insert("wolf_wolfen","cc"); 734 | WEAPON_TABLE.lock().unwrap().insert("yoshi_star","38"); 735 | WEAPON_TABLE.lock().unwrap().insert("yoshi_tamago","39"); 736 | WEAPON_TABLE.lock().unwrap().insert("yoshi_yoshibg01","3b"); 737 | WEAPON_TABLE.lock().unwrap().insert("yoshi_yoshimob","3a"); 738 | WEAPON_TABLE.lock().unwrap().insert("younglink_boomerang","1a6"); 739 | WEAPON_TABLE.lock().unwrap().insert("younglink_bow","1a7"); 740 | WEAPON_TABLE.lock().unwrap().insert("younglink_bowarrow","1a8"); 741 | WEAPON_TABLE.lock().unwrap().insert("younglink_hookshot","1a9"); 742 | WEAPON_TABLE.lock().unwrap().insert("younglink_hookshot_hand","1aa"); 743 | WEAPON_TABLE.lock().unwrap().insert("younglink_milk","1ac"); 744 | WEAPON_TABLE.lock().unwrap().insert("younglink_navy","1ab"); 745 | WEAPON_TABLE.lock().unwrap().insert("zelda_dein","6f"); 746 | WEAPON_TABLE.lock().unwrap().insert("zelda_dein_s","70"); 747 | WEAPON_TABLE.lock().unwrap().insert("zelda_phantom","71"); 748 | WEAPON_TABLE.lock().unwrap().insert("zelda_triforce","72"); 749 | } 750 | pub fn get_weapon_kind_from_string(target_kind: &str) -> i32 { 751 | 752 | let lowercased=target_kind.to_lowercase(); 753 | if let Some(hex) = WEAPON_TABLE.lock().unwrap().get(lowercased.as_str()){ 754 | let int = i64::from_str_radix(hex, 16); 755 | let result = (int.unwrap()*-1) as i32; 756 | //println!("{} > {}",target_kind,result); 757 | return result; 758 | } 759 | return -999; 760 | } -------------------------------------------------------------------------------- /nro/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | #![feature( 3 | concat_idents, 4 | proc_macro_hygiene 5 | )] 6 | #![allow( 7 | non_snake_case, 8 | unused, 9 | warnings 10 | )] 11 | #![deny( 12 | deprecated 13 | )] 14 | 15 | use once_cell::sync::Lazy; 16 | 17 | use param_config::{ 18 | * 19 | }; 20 | use smash::{ 21 | hash40, 22 | app::{lua_bind::*, *}, 23 | lib::lua_const::*, 24 | phx::*, 25 | }; 26 | use std::{ 27 | collections::HashMap, 28 | sync::Arc, 29 | arch::asm, 30 | }; 31 | 32 | pub mod data; 33 | pub mod plugin; 34 | 35 | #[skyline::main(name = "libparam_config")] 36 | pub fn main() { 37 | println!("[libparam_config::nro] Loading..."); 38 | if !plugin::install() { 39 | println!("[libparam_config::nro] No param data found"); 40 | } 41 | else{ 42 | println!("[libparam_config::nro] Loaded"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nro/src/plugin.rs: -------------------------------------------------------------------------------- 1 | #![feature(proc_macro_hygiene)] 2 | use super::*; 3 | use super::data::*; 4 | use std::{ 5 | path::Path, 6 | convert::TryInto, 7 | str::FromStr, 8 | fs, 9 | thread::{self}, 10 | sync::Mutex 11 | }; 12 | 13 | use once_cell::sync::Lazy; 14 | 15 | use serde_derive::Deserialize; 16 | use toml; 17 | 18 | const IDENTIFIER: &str = "config_param.toml"; 19 | 20 | // Top level struct to hold the TOML data. 21 | #[derive(Deserialize)] 22 | struct ConfigToml { 23 | kind: Option::, 24 | slots: Option::>, 25 | param_int: Option::>, 26 | param_float: Option::>, 27 | attribute_mul: Option::>, 28 | param_int_mul: Option::>, 29 | } 30 | 31 | #[derive(Deserialize)] 32 | struct param_int { 33 | param: String, 34 | subparam: Option::, 35 | value: i32, 36 | kinds: Option::>, 37 | slots: Option::>, 38 | } 39 | #[derive(Deserialize)] 40 | struct param_float { 41 | param: String, 42 | subparam: Option::, 43 | value: f32, 44 | kinds: Option::>, 45 | slots: Option::>, 46 | } 47 | #[derive(Deserialize)] 48 | struct attribute_mul { 49 | param: String, 50 | subparam: Option::, 51 | value: f32, 52 | kinds: Option::>, 53 | slots: Option::>, 54 | } 55 | #[derive(Deserialize)] 56 | struct param_int_mul { 57 | param: String, 58 | subparam: Option::, 59 | value: f32, 60 | kinds: Option::>, 61 | slots: Option::>, 62 | } 63 | 64 | pub unsafe fn update_param( 65 | mainKind: &String, mainSlots: &Vec, 66 | p_param: String, p_subparam: Option::, 67 | p_value_i: i32,p_value_f: f32,p_value_type: i32, 68 | p_kinds: Option::>,p_slots: Option::>, 69 | ) -> bool 70 | { 71 | let mut kinds:Vec = Vec::new(); 72 | let mut slots:Vec = Vec::new(); 73 | if p_kinds.is_some() { 74 | kinds = p_kinds.unwrap(); 75 | } 76 | else if mainKind != "" { 77 | kinds.push(mainKind.clone()); 78 | } 79 | if kinds.len() < 1 { 80 | println!("[libparam_config::nro::plugin] Entry has no fighters"); 81 | return false; 82 | } 83 | 84 | if p_slots.is_some(){ 85 | slots = p_slots.unwrap(); 86 | } 87 | else if mainSlots.len() > 0 { 88 | slots = mainSlots.clone(); 89 | } 90 | if slots.len() < 1 { 91 | println!("[libparam_config::nro::plugin] Entry has no slots"); 92 | return false; 93 | } 94 | 95 | let subparam = 0; 96 | let mut subparam_string = match p_subparam { 97 | Some(h) => h, 98 | None => String::from("") 99 | }; 100 | if p_value_type == param_config::PARAM_TYPE_INT { 101 | if p_param == "article_use_type" { 102 | subparam_string = String::from(""); 103 | } 104 | else if p_param == "kirby_cant_copy" { 105 | subparam_string = String::from(""); 106 | } 107 | } 108 | 109 | let subparam_str = subparam_string.as_str(); 110 | let mut subparam_hash = 0; 111 | if p_param == "villager_cant_pocket" { 112 | if hash_str_to_u64(&subparam_string) != 0 { 113 | subparam_hash = (get_weapon_kind_from_string(&subparam_string).abs()) as u64; 114 | if subparam_hash == 999 { 115 | println!("[libparam_config::nro::plugin] {} is an invalid weapon",&subparam_string); 116 | return false; 117 | } 118 | } 119 | } 120 | else { 121 | subparam_hash = hash_str_to_u64(subparam_str); 122 | }; 123 | let index = (hash_str_to_u64(p_param.as_str()),subparam_hash); 124 | 125 | let mut validKinds = false; 126 | let use_int = p_value_type == param_config::PARAM_TYPE_INT; 127 | 128 | for kind in &kinds { 129 | let isFighter = !(kind.contains("_") && kind != "ice_climber"); 130 | let kind_i32 = if isFighter {get_fighter_kind_from_string(&kind)} else {get_weapon_kind_from_string(&kind)}; 131 | if kind_i32 == 999 { 132 | println!("[libparam_config::nro::plugin] {} is an invalid fighter",kind); 133 | continue; 134 | } 135 | if kind_i32 == -999 { 136 | println!("[libparam_config::nro::plugin] {} is an invalid weapon",kind); 137 | continue; 138 | } 139 | validKinds = true; 140 | match p_value_type { 141 | param_config::PARAM_TYPE_FLOAT => {param_config::update_float(kind_i32,slots.clone(),index,p_value_f);} 142 | param_config::PARAM_TYPE_ATTR_MUL => {param_config::update_attribute_mul(kind_i32,slots.clone(),index,p_value_f);} 143 | param_config::PARAM_TYPE_INT_MUL => {param_config::update_int_mul(kind_i32,slots.clone(),index,p_value_f);} 144 | _ => {param_config::update_int(kind_i32,slots.clone(),index,p_value_i);} 145 | } 146 | 147 | //manager.update_int(kind_i32,slots.clone(),index,p_value); 148 | } 149 | print!("["); 150 | for kind in &kinds { 151 | print!("{},",kind.as_str()); 152 | } 153 | if !validKinds {return false;} 154 | 155 | let p_value_str = if use_int {p_value_i.to_string()} else {p_value_f.to_string()}; 156 | if p_param == "article_use_type" { 157 | print!("] article use type: {}",p_value_str); 158 | } 159 | else if p_param == "kirby_cant_copy" { 160 | print!("] kirby cant copy"); 161 | } 162 | else if p_param == "villager_cant_pocket" { 163 | print!("{}",format!("] villager cant pocket: {} ({})",subparam_string,index.1)); 164 | } 165 | else{ 166 | print!("("); 167 | for slot in slots { 168 | print!("{slot},"); 169 | } 170 | print!(")] {}({}): {}",p_param,subparam_str,p_value_str); 171 | } 172 | println!(""); 173 | return true; 174 | } 175 | pub unsafe fn read_config(config_file: String) -> bool 176 | { 177 | let mut hasContent = false; 178 | let contents = match fs::read_to_string(config_file.as_str()) { 179 | Ok(c) => c, 180 | Err(_) => { 181 | println!("[libparam_config::nro::plugin] `{}`", config_file.as_str()); 182 | return false; 183 | } 184 | }; 185 | let data: ConfigToml = match toml::from_str(&contents) { 186 | Ok(d) => d, 187 | Err(_) => { 188 | println!("[libparam_config::nro::plugin] Unable to load data from `{}`", config_file.as_str()); 189 | return false; 190 | } 191 | }; 192 | println!("[libparam_config::nro::plugin] Found file: {}",config_file.as_str()); 193 | println!("[libparam_config::nro::plugin] Loading params:"); 194 | let mut mainKind = String::from(""); 195 | let mut mainSlots = Vec::new(); 196 | if data.kind.is_some(){ 197 | mainKind = data.kind.unwrap(); 198 | } 199 | if data.slots.is_some(){ 200 | mainSlots = data.slots.unwrap(); 201 | } 202 | //let mut manager = PARAM_MANAGER.write(); 203 | 204 | if data.param_int.is_some(){ 205 | println!("[libparam_config::nro::plugin] Ints:"); 206 | for param in data.param_int.unwrap() { 207 | //println!("{}?",param.param); 208 | hasContent = update_param(&mainKind,&mainSlots, 209 | param.param,param.subparam, 210 | param.value,0.0,param_config::PARAM_TYPE_INT, 211 | param.kinds,param.slots) || hasContent; 212 | } 213 | } 214 | if data.param_float.is_some(){ 215 | println!(""); 216 | println!("[libparam_config::nro::plugin] Floats:"); 217 | for param in data.param_float.unwrap() { 218 | //println!("{}?",param.param); 219 | hasContent = update_param(&mainKind,&mainSlots, 220 | param.param,param.subparam, 221 | 0,param.value,param_config::PARAM_TYPE_FLOAT, 222 | param.kinds,param.slots) || hasContent; 223 | } 224 | } 225 | if data.attribute_mul.is_some(){ 226 | println!(""); 227 | println!("[libparam_config::nro::plugin] Attribute Muls:"); 228 | for param in data.attribute_mul.unwrap() { 229 | //println!("{}?",param.param); 230 | hasContent = update_param(&mainKind,&mainSlots, 231 | param.param,param.subparam, 232 | 0,param.value,param_config::PARAM_TYPE_ATTR_MUL, 233 | param.kinds,param.slots) || hasContent; 234 | } 235 | } 236 | if data.param_int_mul.is_some(){ 237 | println!(""); 238 | println!("[libparam_config::nro::plugin] Int Muls:"); 239 | for param in data.param_int_mul.unwrap() { 240 | //println!("{}?",param.param); 241 | hasContent = update_param(&mainKind,&mainSlots, 242 | param.param,param.subparam, 243 | 0,param.value,param_config::PARAM_TYPE_INT_MUL, 244 | param.kinds,param.slots) || hasContent; 245 | } 246 | } 247 | #[cfg(not(feature = "test"))] 248 | println!("[libparam_config::nro::plugin] Finished!"); 249 | println!(""); 250 | 251 | return hasContent; 252 | } 253 | 254 | #[cfg(not(feature = "test"))] 255 | use arcropolis_api; 256 | pub fn find_folders() ->bool { 257 | #[cfg(not(feature = "test"))] 258 | unsafe { 259 | let mut folders_found = false; 260 | for entry in std::fs::read_dir("sd:/ultimate/mods").unwrap() { 261 | let entry = entry.unwrap(); 262 | let mut path = entry.path(); 263 | if path.is_dir() { 264 | path.push(IDENTIFIER); 265 | if Path::new(&path).exists() { 266 | path.pop(); 267 | 268 | let folder = format!("{}",path.display()); 269 | 270 | let is_enabled = arcropolis_api::is_mod_enabled(arcropolis_api::hash40(folder.as_str()).as_u64()); 271 | if is_enabled { 272 | folders_found = folders_found | read_config(format!("{}/{}", folder.as_str(),IDENTIFIER)); 273 | } 274 | } 275 | } 276 | } 277 | return folders_found; 278 | } 279 | return true; 280 | } 281 | 282 | pub fn install() -> bool { 283 | 284 | let folder_thread = std::thread::Builder::new() 285 | .stack_size(32*512*256) 286 | .spawn(|| { 287 | data::build_fighter_table(); 288 | data::build_weapon_table(); 289 | find_folders() 290 | }) 291 | .unwrap() 292 | .join(); 293 | 294 | return folder_thread.unwrap(); 295 | } -------------------------------------------------------------------------------- /src/hook.rs: -------------------------------------------------------------------------------- 1 | use { 2 | smash::{ 3 | hash40, 4 | app::{lua_bind::*, *}, 5 | lib::lua_const::* 6 | } 7 | }; 8 | use super::*; 9 | use skyline::hooks::{ 10 | getRegionAddress, 11 | Region, 12 | InlineCtx 13 | }; 14 | 15 | 16 | static INT_OFFSET: usize = 0x4e53a0; // 13.0.2 17 | static FLOAT_OFFSET: usize = 0x4e53e0; // 13.0.2 18 | 19 | #[skyline::hook(offset=INT_OFFSET)] 20 | pub unsafe fn get_param_int_hook(module: u64, param_type: u64, param_hash: u64) -> i32 { 21 | let original_value = original!()(module, param_type, param_hash); 22 | 23 | let mut module_accessor = *((module as *mut u64).offset(1)) as *mut BattleObjectModuleAccessor; 24 | let module_accessor_reference = &mut *module_accessor; 25 | let id = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as usize; 26 | let mut slot = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 27 | 28 | let mut fighter_kind = utility::get_kind(module_accessor_reference); 29 | if utility::get_category(module_accessor_reference) == *BATTLE_OBJECT_CATEGORY_WEAPON { 30 | fighter_kind *= -1; 31 | let owner_id = WorkModule::get_int(module_accessor, *WEAPON_INSTANCE_WORK_ID_INT_ACTIVATE_FOUNDER_ID) as u32; 32 | if sv_battle_object::is_active(owner_id) { 33 | slot = WorkModule::get_int(sv_battle_object::module_accessor(owner_id), *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 34 | } 35 | } 36 | 37 | if FighterParamModule::has_kind(fighter_kind) 38 | { 39 | if let Some(mult) = FighterParamModule::get_int_param_mul(fighter_kind, slot,param_type, param_hash){ 40 | let temp = (original_value as f32) * mult; 41 | return temp as i32; 42 | } 43 | else if let Some(new_param) = FighterParamModule::get_int_param(fighter_kind, slot,param_type, param_hash){ 44 | return new_param; 45 | } 46 | } 47 | 48 | return original_value; 49 | } 50 | 51 | 52 | #[skyline::hook(offset=FLOAT_OFFSET)] 53 | pub unsafe fn get_param_float_hook(module: u64, param_type: u64, param_hash: u64) -> f32 { 54 | let original_value = original!()(module, param_type, param_hash); 55 | 56 | let mut module_accessor = *((module as *mut u64).offset(1)) as *mut BattleObjectModuleAccessor; 57 | let module_accessor_reference = &mut *module_accessor; 58 | let id = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_ENTRY_ID) as usize; 59 | let mut slot = WorkModule::get_int(module_accessor, *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 60 | 61 | let mut fighter_kind = utility::get_kind(module_accessor_reference); 62 | if utility::get_category(module_accessor_reference) == *BATTLE_OBJECT_CATEGORY_WEAPON { 63 | fighter_kind *= -1; 64 | let owner_id = WorkModule::get_int(module_accessor, *WEAPON_INSTANCE_WORK_ID_INT_ACTIVATE_FOUNDER_ID) as u32; 65 | if sv_battle_object::is_active(owner_id) { 66 | slot = WorkModule::get_int(sv_battle_object::module_accessor(owner_id), *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 67 | } 68 | } 69 | 70 | if FighterParamModule::has_kind(fighter_kind) 71 | { 72 | if let Some(mult) = FighterParamModule::get_attribute_mul(fighter_kind, slot,param_type, param_hash) { 73 | return original_value*mult; 74 | } 75 | else if let Some(new_param) = FighterParamModule::get_float_param(fighter_kind, slot,param_type, param_hash) { 76 | return new_param; 77 | } 78 | } 79 | 80 | return original_value; 81 | } 82 | 83 | 84 | #[skyline::hook(offset = 0x3a6670)] 85 | unsafe fn get_article_use_type_mask(weapon_kind: i32, entry_id: i32) -> u8 { 86 | if FighterParamModule::has_kind(-weapon_kind) { 87 | if let Some(new_type) = FighterParamModule::get_article_use_type(-weapon_kind){ 88 | return new_type as u8; 89 | } 90 | } 91 | call_original!(weapon_kind, entry_id) 92 | } 93 | 94 | #[skyline::from_offset(0xb96770)] 95 | fn copy_ability_reset(fighter: *mut Fighter, some_miifighter_bool: bool); 96 | 97 | unsafe fn kirby_cant_copy(fighter: &mut Fighter) { 98 | let module_accessor = fighter.battle_object.module_accessor; 99 | let status_kind = StatusModule::status_kind(module_accessor); 100 | 101 | if status_kind != *FIGHTER_KIRBY_STATUS_KIND_SPECIAL_N_DRINK { 102 | return; 103 | } 104 | if WorkModule::is_flag(module_accessor, *FIGHTER_KIRBY_STATUS_SPECIAL_N_FLAG_DRINK_WEAPON) { 105 | return; 106 | } 107 | if WorkModule::is_flag(module_accessor, *FIGHTER_KIRBY_STATUS_SPECIAL_N_FLAG_SPIT_END) 108 | && WorkModule::get_int(module_accessor, *FIGHTER_KIRBY_INSTANCE_WORK_ID_INT_COPY_CHARA) != *FIGHTER_KIND_KIRBY { 109 | let opponent_id = WorkModule::get_int64(module_accessor, *FIGHTER_KIRBY_STATUS_SPECIAL_N_WORK_INT_TARGET_TASK) as u32; 110 | if opponent_id != *BATTLE_OBJECT_ID_INVALID as u32 && sv_battle_object::is_active(opponent_id) { 111 | let opp = sv_battle_object::module_accessor(opponent_id); 112 | let opp_slot = WorkModule::get_int(opp, *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 113 | let opp_kind = utility::get_kind(&mut *opp); 114 | 115 | if FighterParamModule::has_kind(opp_kind) { 116 | if !FighterParamModule::can_kirby_copy(opp_kind,opp_slot) { 117 | copy_ability_reset(fighter, false); 118 | let star_id = WorkModule::get_int(module_accessor, *FIGHTER_KIRBY_INSTANCE_WORK_ID_INT_WN_STAR_TASK_ID) as u32; 119 | if sv_battle_object::is_active(star_id) { 120 | let star = sv_battle_object::module_accessor(star_id); 121 | WorkModule::set_int(star, *FIGHTER_KIND_KIRBY, *WEAPON_KIRBY_STARMISSILE_STATUS_WORK_INT_KIND); 122 | } 123 | } 124 | } 125 | } 126 | } 127 | } 128 | 129 | const KIRBY_VTABLE_PER_FIGHTER_FRAME_OFFSET: usize = 0xb97b30; 130 | #[skyline::hook(offset = KIRBY_VTABLE_PER_FIGHTER_FRAME_OFFSET)] 131 | unsafe extern "C" fn kirby_opff(vtable: u64, fighter: &mut Fighter) -> u64 { 132 | if *super::IS_HOOKED_KIRBY.read() { 133 | kirby_cant_copy(fighter); 134 | } 135 | if *super::IS_HOOKED_VILLAGER.read() { 136 | villager_cant_pocket(fighter,true); 137 | } 138 | original!()(vtable, fighter) 139 | } 140 | 141 | fn get_weapon_common_from_accessor<'a>(boma: &'a mut BattleObjectModuleAccessor) -> &'a mut smash::common::root::lua2cpp::L2CWeaponCommon { 142 | unsafe { 143 | let lua_module = *(boma as *mut BattleObjectModuleAccessor as *mut u64).add(0x190 / 8); 144 | std::mem::transmute(*((lua_module + 0x1D8) as *mut *mut smash::common::root::lua2cpp::L2CWeaponCommon)) 145 | } 146 | } 147 | 148 | const VILLAGER_VTABLE_ONCE_PER_FIGHTER_FRAME_OFFSET: usize = 0xdbb940; 149 | #[skyline::hook(offset = VILLAGER_VTABLE_ONCE_PER_FIGHTER_FRAME_OFFSET)] 150 | pub unsafe extern "C" fn villager_opff(_vtable: u64, fighter: &mut Fighter) { 151 | let module_accessor = fighter.battle_object.module_accessor; 152 | let kind = fighter.battle_object.kind; 153 | if kind == *FIGHTER_KIND_MURABITO as u32 || kind == *FIGHTER_KIND_SHIZUE as u32 { 154 | villager_cant_pocket(fighter,false); 155 | } 156 | } 157 | 158 | unsafe fn check_pockets(fighter: &mut Fighter, object_id: u32) -> bool { 159 | let object_boma = sv_battle_object::module_accessor(object_id); 160 | let object_cat = utility::get_category(&mut *object_boma); 161 | let object_kind = utility::get_kind(&mut *object_boma); 162 | if object_cat == *BATTLE_OBJECT_CATEGORY_WEAPON { 163 | 164 | let owner_id = WorkModule::get_int(object_boma, *WEAPON_INSTANCE_WORK_ID_INT_ACTIVATE_FOUNDER_ID) as u32; 165 | let owner_boma = sv_battle_object::module_accessor(owner_id); 166 | let owner_kind = utility::get_kind(&mut *owner_boma); 167 | let owner_slot = WorkModule::get_int(owner_boma, *FIGHTER_INSTANCE_WORK_ID_INT_COLOR); 168 | 169 | //if owner_kind is found in table 170 | if FighterParamModule::has_kind(owner_kind) { 171 | if !FighterParamModule::can_villager_pocket(owner_kind,owner_slot,object_kind) { 172 | let pos = *PostureModule::pos(object_boma); 173 | EffectModule::req( 174 | object_boma, 175 | Hash40::new("sys_erace_smoke"), 176 | &Vector3f{x:pos.x,y:pos.y+2.0,z:pos.z}, 177 | &Vector3f{x:0.0,y:0.0,z:0.0}, 178 | 0.625, 179 | 0, 180 | -1, 181 | false, 182 | 0 183 | ); 184 | 185 | use smash_script::*; 186 | let weapon = get_weapon_common_from_accessor(&mut *object_boma); 187 | smash_script::notify_event_msc_cmd!(weapon, Hash40::new_raw(0x199c462b5d)); 188 | 189 | return true; 190 | } 191 | } 192 | } 193 | return false; 194 | } 195 | 196 | unsafe fn villager_cant_pocket(fighter: &mut Fighter, is_kirby: bool) { 197 | let module_accessor = fighter.battle_object.module_accessor; 198 | let status = StatusModule::status_kind(module_accessor); 199 | let mut object_id = *BATTLE_OBJECT_ID_INVALID as u32; 200 | let mut next_status = *FIGHTER_MURABITO_STATUS_KIND_SPECIAL_N_FAILURE; 201 | if !is_kirby { 202 | if status == *FIGHTER_MURABITO_STATUS_KIND_SPECIAL_N_SEARCH { 203 | object_id = WorkModule::get_int(module_accessor, *FIGHTER_MURABITO_INSTANCE_WORK_ID_INT_TARGET_OBJECT_ID) as u32; 204 | } 205 | } 206 | else { 207 | if status == *FIGHTER_KIRBY_STATUS_KIND_MURABITO_SPECIAL_N_SEARCH { 208 | object_id = WorkModule::get_int(module_accessor, *FIGHTER_MURABITO_INSTANCE_WORK_ID_INT_TARGET_OBJECT_ID) as u32; 209 | next_status = *FIGHTER_KIRBY_STATUS_KIND_MURABITO_SPECIAL_N_FAILURE; 210 | } 211 | else if status == *FIGHTER_KIRBY_STATUS_KIND_SHIZUE_SPECIAL_N_SEARCH { 212 | object_id = WorkModule::get_int(module_accessor, *FIGHTER_MURABITO_INSTANCE_WORK_ID_INT_TARGET_OBJECT_ID) as u32; 213 | next_status = *FIGHTER_KIRBY_STATUS_KIND_SHIZUE_SPECIAL_N_FAILURE; 214 | } 215 | } 216 | if object_id != BATTLE_OBJECT_ID_INVALID && object_id != 0 { 217 | let object_id = WorkModule::get_int(module_accessor, *FIGHTER_MURABITO_INSTANCE_WORK_ID_INT_TARGET_OBJECT_ID) as u32; 218 | if check_pockets(fighter,object_id) { 219 | WorkModule::set_int(module_accessor, *BATTLE_OBJECT_ID_INVALID, *FIGHTER_MURABITO_INSTANCE_WORK_ID_INT_TARGET_OBJECT_ID); 220 | StatusModule::change_status_request_from_script(module_accessor, next_status, false); 221 | } 222 | } 223 | } 224 | 225 | // Only used to set if we're in game 226 | #[skyline::hook(offset = 0x1a2625c, inline)] 227 | unsafe fn read_melee_mode(ctx: &mut skyline::hooks::InlineCtx) { 228 | *super::IN_GAME.write() = true; 229 | } 230 | 231 | pub fn install_params() { 232 | super::set_hash_any(); 233 | if super::can_hook_params() { 234 | println!("[libparam_config] Hooking GetParam functions"); 235 | skyline::install_hooks!( 236 | get_param_int_hook, 237 | get_param_float_hook, 238 | //read_melee_mode 239 | ); 240 | *super::IS_HOOKED_PARAMS.write() = true; 241 | } 242 | } 243 | pub fn install_articles() { 244 | if super::can_hook_articles() { 245 | println!("[libparam_config] Hooking Article Use Type function"); 246 | skyline::install_hooks!( 247 | get_article_use_type_mask 248 | ); 249 | *super::IS_HOOKED_ARTICLES.write() = true; 250 | } 251 | } 252 | pub fn install_kirby() { 253 | if super::can_hook_kirby() || super::can_hook_villager() { 254 | println!("[libparam_config] Hooking Kirby Frame vtable"); 255 | skyline::install_hooks!( 256 | kirby_opff 257 | ); 258 | *super::IS_HOOKED_KIRBY.write() = true; 259 | } 260 | } 261 | pub fn install_villager() { 262 | if super::can_hook_villager() { 263 | println!("[libparam_config] Hooking Villager Status Change vtable"); 264 | skyline::install_hooks!( 265 | villager_opff 266 | ); 267 | *super::IS_HOOKED_VILLAGER.write() = true; 268 | 269 | install_kirby(); 270 | } 271 | } -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![crate_name = "param_config"] 2 | #![feature( 3 | concat_idents, 4 | proc_macro_hygiene 5 | )] 6 | #![allow( 7 | non_snake_case, 8 | unused, 9 | warnings 10 | )] 11 | #![deny( 12 | deprecated 13 | )] 14 | 15 | #[macro_use] 16 | extern crate lazy_static; 17 | 18 | 19 | use smash::{ 20 | hash40, 21 | app::{lua_bind::*, *}, 22 | lib::lua_const::*, 23 | phx::*, 24 | }; 25 | use std::{ 26 | collections::HashMap, 27 | sync::Arc, 28 | arch::asm, 29 | }; 30 | use parking_lot::RwLock; 31 | use lazy_static::lazy_static; 32 | mod hook; 33 | 34 | pub fn hash_str_to_u64(param: &str) -> u64 35 | { 36 | if param.starts_with("0x"){ 37 | match u64::from_str_radix(param.trim_start_matches("0x"), 16){ 38 | Ok(hex) => return hex, 39 | Err(err) => {println!("[libparam_config::nro::data] Failed to parse {}",param); return 0} 40 | }; 41 | } 42 | else 43 | { 44 | return match param { 45 | "" => 0, 46 | " " => 0, 47 | _ => hash40(param), 48 | }; 49 | } 50 | } 51 | 52 | lazy_static! { 53 | static ref IN_GAME: RwLock = RwLock::new(false); 54 | static ref HOOK_ARTICLES: RwLock = RwLock::new(false); 55 | static ref HOOK_PARAMS: RwLock = RwLock::new(false); 56 | static ref HOOK_KIRBY: RwLock = RwLock::new(false); 57 | static ref HOOK_VILLAGER: RwLock = RwLock::new(false); 58 | static ref IS_HOOKED_ARTICLES: RwLock = RwLock::new(false); 59 | static ref IS_HOOKED_PARAMS: RwLock = RwLock::new(false); 60 | static ref IS_HOOKED_KIRBY: RwLock = RwLock::new(false); 61 | static ref IS_HOOKED_VILLAGER: RwLock = RwLock::new(false); 62 | static ref HASH_ANY: RwLock = RwLock::new(0); 63 | } 64 | 65 | pub fn is_in_game() -> bool { 66 | return *IN_GAME.read(); 67 | } 68 | pub fn can_hook_articles() -> bool { 69 | return *HOOK_ARTICLES.read() && !is_hooked_articles(); 70 | } 71 | pub fn can_hook_params() -> bool { 72 | return *HOOK_PARAMS.read() && !is_hooked_params(); 73 | } 74 | pub fn can_hook_kirby() -> bool { 75 | return *HOOK_KIRBY.read() && !is_hooked_kirby(); 76 | } 77 | pub fn can_hook_villager() -> bool { 78 | return *HOOK_VILLAGER.read() && !is_hooked_villager(); 79 | } 80 | pub fn is_hooked_articles() -> bool { 81 | return *IS_HOOKED_ARTICLES.read(); 82 | } 83 | pub fn is_hooked_params() -> bool { 84 | return *IS_HOOKED_PARAMS.read(); 85 | } 86 | pub fn is_hooked_kirby() -> bool { 87 | return *IS_HOOKED_KIRBY.read(); 88 | } 89 | pub fn is_hooked_villager() -> bool { 90 | return *IS_HOOKED_VILLAGER.read(); 91 | } 92 | pub fn set_hash_any() { 93 | if *HASH_ANY.read() == 0 { 94 | *HASH_ANY.write() = hash_str_to_u64("any"); 95 | } 96 | } 97 | 98 | pub struct CharacterParam { 99 | pub kind: i32, 100 | pub has_all_slots: bool, 101 | pub slots: Vec, 102 | pub ints: HashMap<(u64,u64),i32>, 103 | pub floats: HashMap<(u64,u64),f32>, 104 | pub attribute_muls: HashMap<(u64,u64),f32>, 105 | pub mul_ints: HashMap<(u64,u64),f32>, 106 | } 107 | impl PartialEq for CharacterParam { 108 | fn eq(&self, other: &Self) -> bool { 109 | self.kind == other.kind 110 | && self.slots == other.slots 111 | } 112 | } 113 | impl Eq for CharacterParam {} 114 | impl CharacterParam { 115 | pub fn get_int(&self, param_type: u64, param_hash: u64) -> Option { 116 | if let Some(value) = self.ints.get(&(param_type,param_hash)){ 117 | return Some(*value); 118 | } 119 | else if let Some(value) = self.ints.get(&(*HASH_ANY.read(),param_hash)){ 120 | return Some(*value); 121 | } 122 | return None; 123 | } 124 | pub fn get_float(&self, param_type: u64, param_hash: u64) -> Option { 125 | if let Some(value) = self.floats.get(&(param_type,param_hash)){ 126 | return Some(*value); 127 | } 128 | else if let Some(value) = self.floats.get(&(*HASH_ANY.read(),param_hash)){ 129 | return Some(*value); 130 | } 131 | return None; 132 | } 133 | pub fn get_attribute_mul(&self, param_type: u64, param_hash: u64) -> Option { 134 | if let Some(value) = self.attribute_muls.get(&(param_type,param_hash)){ 135 | return Some(*value); 136 | } 137 | else if let Some(value) = self.attribute_muls.get(&(*HASH_ANY.read(),param_hash)){ 138 | return Some(*value); 139 | } 140 | return None; 141 | } 142 | pub fn get_int_param_mul(&self, param_type: u64, param_hash: u64) -> Option { 143 | if let Some(value) = self.mul_ints.get(&(param_type,param_hash)){ 144 | return Some(*value); 145 | } 146 | else if let Some(value) = self.mul_ints.get(&(*HASH_ANY.read(),param_hash)){ 147 | return Some(*value); 148 | } 149 | return None; 150 | } 151 | } 152 | 153 | pub struct ParamManager { 154 | pub kinds: Vec, 155 | pub has_all: bool, 156 | pub params: Vec 157 | } 158 | 159 | pub const PARAM_TYPE_INT: i32 = 0; 160 | pub const PARAM_TYPE_FLOAT: i32 = 1; 161 | pub const PARAM_TYPE_ATTR_MUL: i32 = 2; 162 | pub const PARAM_TYPE_INT_MUL: i32 = 3; 163 | 164 | impl ParamManager { 165 | pub(crate) fn new() -> Self { 166 | Self { 167 | kinds: Vec::new(), 168 | has_all: false, 169 | params: Vec::new(), 170 | } 171 | } 172 | pub fn push(&mut self, params: CharacterParam) { 173 | let kind = params.kind; 174 | if !(self.kinds.contains(&kind)) { 175 | self.kinds.push(kind); 176 | if kind == *FIGHTER_KIND_ALL { 177 | self.has_all = true; 178 | } 179 | } 180 | self.params.push(params); 181 | } 182 | 183 | pub fn get_param_by_slot(&self,kind: i32, slot: i32) -> Option<&CharacterParam> { 184 | for params in &self.params{ 185 | if (params.kind == kind) { 186 | if params.slots.contains(&slot) || params.has_all_slots { 187 | return Some(params); 188 | } 189 | } 190 | } 191 | return None 192 | } 193 | pub fn get_param(&self,kind: i32, slots: Vec) -> Option<&CharacterParam> { 194 | for params in &self.params{ 195 | if (params.kind == kind) { 196 | if params.slots == slots { 197 | return Some(params); 198 | } 199 | } 200 | } 201 | return None 202 | } 203 | 204 | fn update_value(&mut self,kind: i32, slots: Vec,index: (u64,u64),value_i: i32, value_f: f32,value_type: i32) { 205 | for param in &mut self.params { 206 | if (param.kind == kind) { 207 | if param.slots == slots { 208 | match value_type { 209 | PARAM_TYPE_FLOAT => {param.floats.insert(index, value_f);} 210 | PARAM_TYPE_ATTR_MUL => {param.attribute_muls.insert(index, value_f);} 211 | PARAM_TYPE_INT_MUL => {param.mul_ints.insert(index, value_f);} 212 | _ => {param.ints.insert(index, value_i);} 213 | } 214 | 215 | return; 216 | } 217 | } 218 | } 219 | let mut newparams = CharacterParam { 220 | kind: kind, 221 | has_all_slots: (slots.contains(&-1)), 222 | slots: slots, 223 | ints: HashMap::new(), 224 | floats: HashMap::new(), 225 | attribute_muls: HashMap::new(), 226 | mul_ints: HashMap::new(), 227 | }; 228 | match value_type { 229 | PARAM_TYPE_FLOAT => {newparams.floats.insert(index, value_f);} 230 | PARAM_TYPE_ATTR_MUL => {newparams.attribute_muls.insert(index, value_f);} 231 | PARAM_TYPE_INT_MUL => {newparams.mul_ints.insert(index, value_f);} 232 | _ => {newparams.ints.insert(index,value_i);} 233 | } 234 | self.push(newparams); 235 | } 236 | pub fn update_int(&mut self,kind: i32, slots: Vec,index: (u64,u64),value: i32) { 237 | self.update_value(kind,slots,index,value,0.0,PARAM_TYPE_INT); 238 | } 239 | pub fn update_float(&mut self,kind: i32, slots: Vec,index: (u64,u64),value: f32) { 240 | self.update_value(kind,slots,index,0,value,PARAM_TYPE_FLOAT); 241 | } 242 | pub fn update_attribute_mul(&mut self,kind: i32, slots: Vec,index: (u64,u64),value: f32) { 243 | self.update_value(kind,slots,index,0,value,PARAM_TYPE_ATTR_MUL); 244 | } 245 | pub fn update_int_mul(&mut self,kind: i32, slots: Vec,index: (u64,u64),value: f32) { 246 | self.update_value(kind,slots,index,0,value,PARAM_TYPE_INT_MUL); 247 | } 248 | 249 | } 250 | 251 | lazy_static! { 252 | pub static ref PARAM_MANAGER: RwLock = RwLock::new(ParamManager::new()); 253 | } 254 | 255 | pub struct FighterParamModule { 256 | pub manager: ParamManager 257 | } 258 | 259 | impl FighterParamModule { 260 | #[export_name = "FighterParamModule__has_kind"] 261 | pub extern "C" fn has_kind(kind: i32) -> bool { 262 | let mut manager = PARAM_MANAGER.read(); 263 | return manager.kinds.contains(&kind) || manager.has_all; 264 | } 265 | 266 | #[export_name = "FighterParamModule__get_int_param"] 267 | pub extern "C" fn get_int_param(kind: i32, slot: i32, param_type: u64, param_hash: u64) -> Option { 268 | let mut manager = PARAM_MANAGER.read(); 269 | for params in &manager.params { 270 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 271 | if params.slots.contains(&slot) || params.has_all_slots { 272 | if let Some(value) = params.get_int(param_type, param_hash){ 273 | return Some(value); 274 | } 275 | } 276 | } 277 | } 278 | return None; 279 | } 280 | #[export_name = "FighterParamModule__get_float_param"] 281 | pub extern "C" fn get_float_param(kind: i32, slot: i32, param_type: u64, param_hash: u64) -> Option { 282 | let mut manager = PARAM_MANAGER.read(); 283 | for params in &manager.params { 284 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 285 | if params.slots.contains(&slot) || params.has_all_slots { 286 | if let Some(value) = params.get_float(param_type, param_hash){ 287 | return Some(value); 288 | } 289 | } 290 | } 291 | } 292 | return None; 293 | } 294 | #[export_name = "FighterParamModule__get_attribute_mul"] 295 | pub extern "C" fn get_attribute_mul(kind: i32, slot: i32, param_type: u64, param_hash: u64) -> Option { 296 | let mut manager = PARAM_MANAGER.read(); 297 | for params in &manager.params { 298 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 299 | if params.slots.contains(&slot) || params.has_all_slots { 300 | if let Some(value) = params.get_attribute_mul(param_type, param_hash){ 301 | return Some(value); 302 | } 303 | } 304 | } 305 | } 306 | return None; 307 | } 308 | #[export_name = "FighterParamModule__get_int_param_mul"] 309 | pub extern "C" fn get_int_param_mul(kind: i32, slot: i32, param_type: u64, param_hash: u64) -> Option { 310 | let mut manager = PARAM_MANAGER.read(); 311 | for params in &manager.params { 312 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 313 | if params.slots.contains(&slot) || params.has_all_slots { 314 | if let Some(value) = params.get_int_param_mul(param_type, param_hash){ 315 | return Some(value); 316 | } 317 | } 318 | } 319 | } 320 | return None; 321 | } 322 | #[export_name = "FighterParamModule__get_article_use_type"] 323 | pub extern "C" fn get_article_use_type(kind: i32) -> Option { 324 | let mut manager = PARAM_MANAGER.read(); 325 | for params in &manager.params { 326 | if (params.kind == kind) { 327 | let article_hash = hash_str_to_u64("article_use_type"); 328 | if let Some(value) = params.get_int(article_hash,0){ 329 | return Some(value); 330 | } 331 | } 332 | } 333 | return None; 334 | } 335 | 336 | #[export_name = "FighterParamModule__can_kirby_copy"] 337 | pub extern "C" fn can_kirby_copy(kind: i32, slot: i32) -> bool { 338 | let mut manager = PARAM_MANAGER.read(); 339 | for params in &manager.params { 340 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 341 | if params.slots.contains(&slot) || params.has_all_slots { 342 | let article_hash = hash_str_to_u64("kirby_cant_copy"); 343 | if let Some(value) = params.get_int(article_hash,0){ 344 | return false; 345 | } 346 | } 347 | } 348 | } 349 | return true; 350 | } 351 | 352 | #[export_name = "FighterParamModule__can_villager_pocket"] 353 | pub extern "C" fn can_villager_pocket(kind: i32, slot: i32, weapon_kind: i32) -> bool { 354 | let mut manager = PARAM_MANAGER.read(); 355 | for params in &manager.params { 356 | if (params.kind == kind || params.kind == *FIGHTER_KIND_ALL) { 357 | if params.slots.contains(&slot) || params.has_all_slots { 358 | let article_hash = hash_str_to_u64("villager_cant_pocket"); 359 | if let Some(value) = params.get_int(article_hash,weapon_kind.abs() as u64) { 360 | return false; 361 | } 362 | else if let Some(value) = params.get_int(article_hash,0) { 363 | return false; 364 | } 365 | } 366 | } 367 | } 368 | return true; 369 | } 370 | } 371 | 372 | #[no_mangle] 373 | /// Updates (or creates) a new param value based on fighter/weapon kind and current alternate costume (slot) 374 | /// 375 | /// # Arguments 376 | /// 377 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 378 | /// * `slots` - Array of effected slots 379 | /// * `index` - (hash40(""),hash40("")) for param/subparam hashes. For common params, the second argument should be 0. 380 | /// * `value` - Value for the param 381 | /// 382 | /// # Example 383 | /// 384 | /// ``` 385 | /// // remove doc's walljump on slot 1 386 | /// let slots = vec![1]; 387 | /// let param = (hash40("wall_jump_type"),0 as u64); 388 | /// param_config::update_int(*FIGHTER_KIND_MARIOD, slots.clone(), param, 0); 389 | /// ``` 390 | pub extern "C" fn update_int(kind: i32, slots: Vec,index: (u64,u64),value: i32) 391 | { 392 | let mut manager = PARAM_MANAGER.write(); 393 | manager.update_int(kind,slots.clone(),index,value); 394 | 395 | if index.0 == hash40("article_use_type"){ 396 | *HOOK_ARTICLES.write() = true; 397 | hook::install_articles(); 398 | } 399 | else if index.0 == hash40("kirby_cant_copy"){ 400 | *HOOK_KIRBY.write() = true; 401 | hook::install_kirby(); 402 | } 403 | else if index.0 == hash40("villager_cant_pocket"){ 404 | *HOOK_VILLAGER.write() = true; 405 | hook::install_villager(); 406 | } 407 | else { 408 | *HOOK_PARAMS.write() = true; 409 | hook::install_params(); 410 | } 411 | } 412 | 413 | #[no_mangle] 414 | /// Updates (or creates) a new param value based on fighter/weapon kind and current alternate costume (slot) 415 | /// 416 | /// # Arguments 417 | /// 418 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 419 | /// * `slots` - Array of effected slots 420 | /// * `param` - (hash40(""),hash40(""),i32) for param/subparam hashes and values. For common params, the second argument should be 0. 421 | /// 422 | /// # Example 423 | /// 424 | /// ``` 425 | /// // remove doc's walljump on slot 1 426 | /// let slots = vec![1]; 427 | /// let param = (hash40("wall_jump_type"),0 as u64,0); 428 | /// param_config::update_int_2(*FIGHTER_KIND_MARIOD, slots.clone(), param); 429 | /// ``` 430 | pub extern "C" fn update_int_2(kind: i32, slots: Vec,param: (u64,u64,i32)) 431 | { 432 | update_int(kind,slots,(param.0,param.1),param.2); 433 | } 434 | 435 | #[no_mangle] 436 | /// Updates (or creates) a new param value based on fighter/weapon kind and current alternate costume (slot) 437 | /// Recommended to only do this for vl.prc entries, and not fighter attributes (see update_attribute_mul) 438 | /// 439 | /// # Arguments 440 | /// 441 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 442 | /// * `slots` - Array of effected slots 443 | /// * `index` - (hash40(""),hash40("")) for param/subparam hashes. For common params, the second argument should be 0. 444 | /// * `value` - Value for the param 445 | /// 446 | /// # Example 447 | /// 448 | /// ``` 449 | /// // Set Doc's Down Special Buoyancy to 3.0 on slot 1 450 | /// let slots = vec![1]; 451 | /// let param = (hash40("param_special_lw"),hash40("buoyancy")); 452 | /// param_config::update_float(*FIGHTER_KIND_MARIOD, slots.clone(), param, 3.0); 453 | /// ``` 454 | pub extern "C" fn update_float(kind: i32, slots: Vec,index: (u64,u64),value: f32) 455 | { 456 | let mut manager = PARAM_MANAGER.write(); 457 | manager.update_float(kind,slots,index,value); 458 | *HOOK_PARAMS.write() = true; 459 | hook::install_params(); 460 | } 461 | 462 | #[no_mangle] 463 | /// Updates (or creates) a new param value based on fighter/weapon kind and current alternate costume (slot) 464 | /// Recommended to only do this for vl.prc entries, and not fighter attributes (see update_attribute_mul) 465 | /// 466 | /// # Arguments 467 | /// 468 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 469 | /// * `slots` - Array of effected slots 470 | /// * `param` - (hash40(""),hash40(""),f32) for param/subparam hashes and value. For common params, the second argument should be 0. 471 | /// 472 | /// 473 | /// # Example 474 | /// 475 | /// ``` 476 | /// // Set Doc's Down Special Buoyancy to 3.0 on slot 1 477 | /// let slots = vec![1]; 478 | /// let param = (hash40("param_special_lw"),hash40("buoyancy"), 3.0); 479 | /// param_config::update_float_2(*FIGHTER_KIND_MARIOD, slots.clone(), param); 480 | /// ``` 481 | pub extern "C" fn update_float_2(kind: i32, slots: Vec,param: (u64,u64,f32)) 482 | { 483 | update_float(kind,slots,(param.0,param.1),param.2); 484 | } 485 | 486 | #[no_mangle] 487 | /// Updates (or creates) an attribute multiplier based on fighter/weapon kind and current alternate costume (slot) 488 | /// 489 | /// # Arguments 490 | /// 491 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 492 | /// * `slots` - Array of effected slots 493 | /// * `index` - (hash40(""),hash40("")) for param/subparam hashes. For common params, the second argument should be 0. 494 | /// * `value` - Value for the param 495 | /// 496 | /// # Example 497 | /// 498 | /// ``` 499 | /// // let doc run twice as fast on slot 1 500 | /// let slots = vec![1]; 501 | /// let param = (hash40("run_speed_max"),0 as u64); 502 | /// param_config::update_attribute_mul(*FIGHTER_KIND_MARIOD, slots.clone(), param, 2.0); 503 | /// ``` 504 | pub extern "C" fn update_attribute_mul(kind: i32, slots: Vec,index: (u64,u64),value: f32) 505 | { 506 | let mut manager = PARAM_MANAGER.write(); 507 | manager.update_attribute_mul(kind,slots,index,value); 508 | *HOOK_PARAMS.write() = true; 509 | hook::install_params(); 510 | } 511 | 512 | #[no_mangle] 513 | /// Updates (or creates) an attribute multiplier based on fighter/weapon kind and current alternate costume (slot) 514 | /// 515 | /// # Arguments 516 | /// 517 | /// * `kind` - Fighter/Weapon kind, as commonly used like *FIGHTER_KIND_MARIOD. If it's a weapon, use a negative number. 518 | /// * `slots` - Array of effected slots 519 | /// * `param` - (hash40(""),hash40(""),f32) for param/subparam hashes and value. For common params, the second argument should be 0. 520 | /// 521 | /// 522 | /// # Example 523 | /// 524 | /// ``` 525 | /// // let doc run twice as fast on slot 1 526 | /// let slots = vec![1]; 527 | /// let param = (hash40("run_speed_max"),0 as u64, 2.0); 528 | /// param_config::update_attribute_mul_2(*FIGHTER_KIND_MARIOD, slots.clone(), param); 529 | /// ``` 530 | pub extern "C" fn update_attribute_mul_2(kind: i32, slots: Vec,param: (u64,u64,f32)) 531 | { 532 | update_attribute_mul(kind,slots,(param.0,param.1),param.2); 533 | } 534 | 535 | pub extern "C" fn update_int_mul(kind: i32, slots: Vec,index: (u64,u64),value: f32) 536 | { 537 | let mut manager = PARAM_MANAGER.write(); 538 | manager.update_int_mul(kind,slots,index,value); 539 | *HOOK_PARAMS.write() = true; 540 | hook::install_params(); 541 | } 542 | pub extern "C" fn update_int_mul_2(kind: i32, slots: Vec,param: (u64,u64,f32)) 543 | { 544 | update_int_mul(kind,slots,(param.0,param.1),param.2); 545 | } 546 | #[no_mangle] 547 | /// Changes the article use type, potentially allowing the article to be spawned during different game states 548 | /// 549 | /// # Arguments 550 | /// 551 | /// * `kind` - Weapon Kind 552 | /// * `use_type` - i32 value of desired *ARTICLE_USETYPE const 553 | /// 554 | /// # Example 555 | /// 556 | /// ``` 557 | /// // Prevent Kirby from copying Dr Mario's first alt 558 | /// let slots = vec![1]; 559 | /// param_config::set_article_use_type(*WEAPON_KIND_MARIOD_CAPSULEBLOCK, *ARTICLE_USETYPE_FINAL); 560 | /// ``` 561 | pub extern "C" fn set_article_use_type(kind: i32, use_type: i32) 562 | { 563 | update_int(-(kind.abs()),vec![1],(hash40("article_use_type"),0),use_type); 564 | } 565 | #[no_mangle] 566 | /// Prevents Kirby from copying the ability of a fighter kind and slot 567 | /// 568 | /// # Arguments 569 | /// 570 | /// * `kind` - Fighter kind, as commonly used like *FIGHTER_KIND_MARIOD. 571 | /// * `slots` - Array of effected slots 572 | /// 573 | /// # Example 574 | /// 575 | /// ``` 576 | /// // Prevent Kirby from copying Dr Mario's first alt 577 | /// let slots = vec![1]; 578 | /// param_config::disable_kirby_copy(*FIGHTER_KIND_MARIOD, slots.clone()); 579 | /// ``` 580 | pub extern "C" fn disable_kirby_copy(kind: i32, slots: Vec) 581 | { 582 | update_int(kind,slots,(hash40("kirby_cant_copy"),0),0); 583 | } 584 | 585 | #[no_mangle] 586 | /// Prevents Villager/Isabelle from pocketting a weapon if it spawned from a given fighter kind and slot 587 | /// 588 | /// # Arguments 589 | /// 590 | /// * `kind` - Fighter kind, as commonly used like *FIGHTER_KIND_MARIOD. 591 | /// * `slots` - Array of effected slots 592 | /// * `weapon_kind` - Weapon kind. If this is 0, then all weapons spawned from kind/slots will be accounted for 593 | /// 594 | /// # Example 595 | /// 596 | /// ``` 597 | /// // Prevent Villager from pocketing Dr Mario's first alt's Pill 598 | /// let slots = vec![1]; 599 | /// param_config::disable_villager_pocket(*FIGHTER_KIND_MARIOD, slots.clone(), *WEAPON_KIND_MARIOD_DRCAPSULE); 600 | /// ``` 601 | pub extern "C" fn disable_villager_pocket(kind: i32, slots: Vec, weapon_kind: i32) 602 | { 603 | update_int(kind,slots,(hash40("villager_cant_pocket"),weapon_kind.abs() as u64),0); 604 | } --------------------------------------------------------------------------------