1
0
mirror of https://github.com/JezuzLizard/BO2-Reimagined.git synced 2025-06-10 23:27:57 -05:00

Melee weapons: add held weapon

Combat Knife: add model from BO2 MP
Add melee wallbuy HUD icons to all maps
Fix level.item_meat_name being undefined
This commit is contained in:
Jbleezy
2023-12-22 03:26:12 -08:00
parent 09a0ee3fb4
commit 747751bc0b
28 changed files with 35429 additions and 65 deletions

View File

@ -35,6 +35,7 @@ main()
replaceFunc(maps\mp\zombies\_zm_stats::set_global_stat, scripts\zm\replaced\_zm_stats::set_global_stat);
replaceFunc(maps\mp\zombies\_zm_playerhealth::playerhealthregen, scripts\zm\replaced\_zm_playerhealth::playerhealthregen);
replaceFunc(maps\mp\zombies\_zm_utility::init_player_offhand_weapons, scripts\zm\replaced\_zm_utility::init_player_offhand_weapons);
replaceFunc(maps\mp\zombies\_zm_utility::give_start_weapon, scripts\zm\replaced\_zm_utility::give_start_weapon);
replaceFunc(maps\mp\zombies\_zm_utility::is_headshot, scripts\zm\replaced\_zm_utility::is_headshot);
replaceFunc(maps\mp\zombies\_zm_utility::shock_onpain, scripts\zm\replaced\_zm_utility::shock_onpain);
replaceFunc(maps\mp\zombies\_zm_utility::create_zombie_point_of_interest_attractor_positions, scripts\zm\replaced\_zm_utility::create_zombie_point_of_interest_attractor_positions);
@ -62,6 +63,7 @@ main()
replaceFunc(maps\mp\zombies\_zm_weapons::createballisticknifewatcher_zm, scripts\zm\replaced\_zm_weapons::createballisticknifewatcher_zm);
replaceFunc(maps\mp\zombies\_zm_weapons::weapon_spawn_think, scripts\zm\replaced\_zm_weapons::weapon_spawn_think);
replaceFunc(maps\mp\zombies\_zm_weapons::weapon_set_first_time_hint, scripts\zm\replaced\_zm_weapons::weapon_set_first_time_hint);
replaceFunc(maps\mp\zombies\_zm_weapons::give_fallback_weapon, scripts\zm\replaced\_zm_weapons::give_fallback_weapon);
replaceFunc(maps\mp\zombies\_zm_magicbox::treasure_chest_init, scripts\zm\replaced\_zm_magicbox::treasure_chest_init);
replaceFunc(maps\mp\zombies\_zm_magicbox::init_starting_chest_location, scripts\zm\replaced\_zm_magicbox::init_starting_chest_location);
replaceFunc(maps\mp\zombies\_zm_magicbox::decide_hide_show_hint, scripts\zm\replaced\_zm_magicbox::decide_hide_show_hint);
@ -99,10 +101,12 @@ main()
replaceFunc(maps\mp\zombies\_zm_clone::spawn_player_clone, scripts\zm\replaced\_zm_clone::spawn_player_clone);
replaceFunc(maps\mp\zombies\_zm_spawner::zombie_gib_on_damage, scripts\zm\replaced\_zm_spawner::zombie_gib_on_damage);
replaceFunc(maps\mp\zombies\_zm_spawner::head_should_gib, scripts\zm\replaced\_zm_spawner::head_should_gib);
replaceFunc(maps\mp\zombies\_zm_spawner::zombie_death_animscript, scripts\zm\replaced\_zm_spawner::zombie_death_animscript);
replaceFunc(maps\mp\zombies\_zm_spawner::zombie_can_drop_powerups, scripts\zm\replaced\_zm_spawner::zombie_can_drop_powerups);
replaceFunc(maps\mp\zombies\_zm_spawner::zombie_complete_emerging_into_playable_area, scripts\zm\replaced\_zm_spawner::zombie_complete_emerging_into_playable_area);
replaceFunc(maps\mp\zombies\_zm_ai_basic::inert_wakeup, scripts\zm\replaced\_zm_ai_basic::inert_wakeup);
replaceFunc(maps\mp\zombies\_zm_ai_dogs::enable_dog_rounds, scripts\zm\replaced\_zm_ai_dogs::enable_dog_rounds);
replaceFunc(maps\mp\zombies\_zm_melee_weapon::init, scripts\zm\replaced\_zm_melee_weapon::init);
replaceFunc(maps\mp\zombies\_zm_melee_weapon::change_melee_weapon, scripts\zm\replaced\_zm_melee_weapon::change_melee_weapon);
replaceFunc(maps\mp\zombies\_zm_melee_weapon::give_melee_weapon, scripts\zm\replaced\_zm_melee_weapon::give_melee_weapon);
replaceFunc(maps\mp\zombies\_zm_weap_ballistic_knife::watch_use_trigger, scripts\zm\replaced\_zm_weap_ballistic_knife::watch_use_trigger);
@ -136,6 +140,11 @@ init()
level.pregame_minplayers = getDvarInt("party_minplayers");
level.player_starting_health = 150;
if (!isdefined(level.item_meat_name))
{
level.item_meat_name = "";
}
setscoreboardcolumns_gametype();
set_lethal_grenade_init();
@ -215,8 +224,6 @@ on_player_spawned()
self thread fall_velocity_check();
self thread melee_weapon_switch_watcher();
self thread give_additional_perks();
self thread weapon_locker_give_ammo_after_rounds();
@ -316,6 +323,7 @@ post_all_players_spawned()
level.ta_vaultfee = 0;
level.ta_tellerfee = 0;
level.weapon_locker_online = 0;
level.disable_melee_wallbuy_icons = 0;
level.dont_link_common_wallbuys = 1;
level.magicbox_timeout = 9;
level.packapunch_timeout = 12;
@ -2566,45 +2574,6 @@ fall_velocity_check()
}
}
melee_weapon_switch_watcher()
{
self endon("disconnect");
vars = [];
vars["prev_wep"] = undefined;
while (1)
{
if (is_true(self.use_staff_melee))
{
wait 0.05;
continue;
}
vars["melee_wep"] = self get_player_melee_weapon();
vars["curr_wep"] = self getCurrentWeapon();
if (vars["curr_wep"] != "none" && !is_offhand_weapon(vars["curr_wep"]))
{
vars["prev_wep"] = vars["curr_wep"];
}
if (self actionSlotTwoButtonPressed() && !self hasWeapon("time_bomb_zm") && !self hasWeapon("time_bomb_detonator_zm") && !self hasWeapon("equip_dieseldrone_zm") && !self hasWeapon(level.item_meat_name))
{
if (vars["curr_wep"] != vars["melee_wep"])
{
self switchToWeapon(vars["melee_wep"]);
}
else
{
self maps\mp\zombies\_zm_weapons::switch_back_primary_weapon(vars["prev_wep"]);
}
}
wait 0.05;
}
}
disable_bank_teller()
{
level notify("stop_bank_teller");
@ -2625,6 +2594,12 @@ disable_carpenter()
weapon_changes()
{
if (level.script == "zm_transit" || level.script == "zm_nuked" || level.script == "zm_highrise" || level.script == "zm_buried" || level.script == "zm_tomb")
{
include_weapon( "held_knife_zm", 0 );
register_melee_weapon_for_level( "held_knife_zm" );
}
if (level.script == "zm_transit" || level.script == "zm_nuked" || level.script == "zm_highrise" || level.script == "zm_buried")
{
level.laststandpistol = "fnp45_zm";
@ -2635,6 +2610,12 @@ weapon_changes()
include_weapon( "fnp45_upgraded_zm", 0 );
add_limited_weapon( "fnp45_zm", 0 );
add_zombie_weapon( "fnp45_zm", "fnp45_upgraded_zm", &"WEAPON_FNP45", 50, "wpck_pistol", "", undefined, 1 );
include_weapon( "held_bowie_knife_zm", 0 );
register_melee_weapon_for_level( "held_bowie_knife_zm" );
include_weapon( "held_tazer_knuckles_zm", 0 );
register_melee_weapon_for_level( "held_tazer_knuckles_zm" );
}
}
@ -3744,6 +3725,7 @@ tombstone_give()
if (isDefined(self.tombstone_savedweapon_melee))
{
self set_player_melee_weapon(self.tombstone_savedweapon_melee);
self setactionslot(2, "weapon", "held_" + self.tombstone_savedweapon_melee);
}
if (isDefined(self.tombstone_savedweapon_grenades))

View File

@ -118,7 +118,7 @@ chugabud_save_loadout()
if (isdefined(self.loadout.equipment))
self equipment_take(self.loadout.equipment);
self.loadout save_weapons_for_chugabud(self);
self.loadout.melee_weapon = self get_player_melee_weapon();
if (self hasweapon("claymore_zm"))
{
@ -258,11 +258,10 @@ chugabud_give_loadout()
if (loadout.current_weapon >= 0 && isdefined(loadout.weapons[loadout.current_weapon]["name"]))
self switchtoweapon(loadout.weapons[loadout.current_weapon]["name"]);
self giveweapon("knife_zm");
self.do_not_display_equipment_pickup_hint = 1;
self maps\mp\zombies\_zm_equipment::equipment_give(self.loadout.equipment);
self.do_not_display_equipment_pickup_hint = undefined;
loadout restore_weapons_for_chugabud(self);
self chugabud_restore_melee_weapon();
self chugabud_restore_claymore();
self.score = loadout.score;
self.pers["score"] = loadout.score;
@ -281,6 +280,14 @@ chugabud_give_loadout()
self.loadout.weapons = undefined;
}
chugabud_restore_melee_weapon()
{
self giveweapon( self.loadout.melee_weapon );
self set_player_melee_weapon( self.loadout.melee_weapon );
self giveweapon("held_" + self.loadout.melee_weapon);
self setactionslot(2, "weapon", "held_" + self.loadout.melee_weapon);
}
chugabud_give_perks()
{
loadout = self.loadout;

View File

@ -320,7 +320,10 @@ treasure_chest_think()
if (is_player_valid(user))
current_weapon = user getcurrentweapon();
if (grabber == user && is_player_valid(user) && !(user.is_drinking > 0) && !is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(current_weapon) && level.revive_tool != current_weapon)
primaries = user getweaponslistprimaries();
weapon_limit = get_player_weapon_limit(user);
if (grabber == user && is_player_valid(user) && !(user.is_drinking > 0) && level.revive_tool != current_weapon && (primaries.size < weapon_limit || (!is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(current_weapon))))
{
bbprint("zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_accept");
self notify("user_grabbed_weapon");
@ -858,10 +861,24 @@ decide_hide_show_hint(endon_notify, second_endon_notify, onlyplayer)
if (isdefined(self.chest_user) && !isdefined(self.box_rerespun))
{
if (is_melee_weapon(self.chest_user getcurrentweapon()) || is_placeable_mine(self.chest_user getcurrentweapon()) || self.chest_user hacker_active())
self setinvisibletoplayer(self.chest_user);
else
primaries = self.chest_user getweaponslistprimaries();
weapon_limit = get_player_weapon_limit(self.chest_user);
if (primaries.size < weapon_limit)
{
self setvisibletoplayer(self.chest_user);
}
else
{
if (is_melee_weapon(self.chest_user getcurrentweapon()) || is_placeable_mine(self.chest_user getcurrentweapon()) || self.chest_user hacker_active())
{
self setinvisibletoplayer(self.chest_user);
}
else
{
self setvisibletoplayer(self.chest_user);
}
}
}
else if (isdefined(onlyplayer))
{
@ -905,8 +922,20 @@ trigger_visible_to_player(player)
if (isdefined(self.stub.trigger_target.chest_user) && !isdefined(self.stub.trigger_target.box_rerespun))
{
if (player != self.stub.trigger_target.chest_user || is_melee_weapon(self.stub.trigger_target.chest_user getcurrentweapon()) || is_placeable_mine(self.stub.trigger_target.chest_user getcurrentweapon()) || self.stub.trigger_target.chest_user hacker_active())
if (player != self.stub.trigger_target.chest_user || self.stub.trigger_target.chest_user hacker_active())
{
visible = 0;
}
else
{
primaries = self.stub.trigger_target.chest_user getweaponslistprimaries();
weapon_limt = get_player_weapon_limit(self.stub.trigger_target.chest_user);
if (primaries.size >= weapon_limt && (is_melee_weapon(self.stub.trigger_target.chest_user getcurrentweapon()) || is_placeable_mine(self.stub.trigger_target.chest_user getcurrentweapon())))
{
visible = 0;
}
}
}
else
{
@ -944,7 +973,10 @@ can_buy_weapon()
current_weapon = self getcurrentweapon();
if (is_melee_weapon(current_weapon) || is_placeable_mine(current_weapon) || is_equipment_that_blocks_purchase(current_weapon))
primaries = self getweaponslistprimaries();
weapon_limt = get_player_weapon_limit(self);
if (primaries.size >= weapon_limt && (is_melee_weapon(current_weapon) || is_placeable_mine(current_weapon) || is_equipment_that_blocks_purchase(current_weapon)))
return false;
if (self in_revive_trigger())

View File

@ -4,6 +4,95 @@
#include maps\mp\zombies\_zm_utility;
#include maps\mp\zombies\_zm_weapons;
init( weapon_name, flourish_weapon_name, ballistic_weapon_name, ballistic_upgraded_weapon_name, cost, wallbuy_targetname, hint_string, vo_dialog_id, flourish_fn )
{
precacheitem( weapon_name );
precacheitem( flourish_weapon_name );
precacheitem( "held_" + weapon_name );
add_melee_weapon( weapon_name, flourish_weapon_name, ballistic_weapon_name, ballistic_upgraded_weapon_name, cost, wallbuy_targetname, hint_string, vo_dialog_id, flourish_fn );
melee_weapon_triggers = getentarray( wallbuy_targetname, "targetname" );
for ( i = 0; i < melee_weapon_triggers.size; i++ )
{
knife_model = getent( melee_weapon_triggers[i].target, "targetname" );
if ( isdefined( knife_model ) )
knife_model hide();
melee_weapon_triggers[i] thread melee_weapon_think( weapon_name, cost, flourish_fn, vo_dialog_id, flourish_weapon_name, ballistic_weapon_name, ballistic_upgraded_weapon_name );
if ( !( isdefined( level.monolingustic_prompt_format ) && level.monolingustic_prompt_format ) )
{
melee_weapon_triggers[i] sethintstring( hint_string, cost );
cursor_hint = "HINT_WEAPON";
cursor_hint_weapon = weapon_name;
melee_weapon_triggers[i] setcursorhint( cursor_hint, cursor_hint_weapon );
}
else
{
weapon_display = get_weapon_display_name( weapon_name );
hint_string = &"ZOMBIE_WEAPONCOSTONLY";
melee_weapon_triggers[i] sethintstring( hint_string, weapon_display, cost );
cursor_hint = "HINT_WEAPON";
cursor_hint_weapon = weapon_name;
melee_weapon_triggers[i] setcursorhint( cursor_hint, cursor_hint_weapon );
}
melee_weapon_triggers[i] usetriggerrequirelookat();
}
melee_weapon_structs = getstructarray( wallbuy_targetname, "targetname" );
for ( i = 0; i < melee_weapon_structs.size; i++ )
prepare_stub( melee_weapon_structs[i].trigger_stub, weapon_name, flourish_weapon_name, ballistic_weapon_name, ballistic_upgraded_weapon_name, cost, wallbuy_targetname, hint_string, vo_dialog_id, flourish_fn );
register_melee_weapon_for_level( weapon_name );
if ( !isdefined( level.ballistic_weapon_name ) )
level.ballistic_weapon_name = [];
level.ballistic_weapon_name[weapon_name] = ballistic_weapon_name;
if ( !isdefined( level.ballistic_upgraded_weapon_name ) )
level.ballistic_upgraded_weapon_name = [];
level.ballistic_upgraded_weapon_name[weapon_name] = ballistic_upgraded_weapon_name;
}
prepare_stub( stub, weapon_name, flourish_weapon_name, ballistic_weapon_name, ballistic_upgraded_weapon_name, cost, wallbuy_targetname, hint_string, vo_dialog_id, flourish_fn )
{
if ( isdefined( stub ) )
{
if ( !( isdefined( level.monolingustic_prompt_format ) && level.monolingustic_prompt_format ) )
{
stub.hint_string = hint_string;
stub.cursor_hint = "HINT_WEAPON";
stub.cursor_hint_weapon = weapon_name;
}
else
{
stub.hint_parm1 = get_weapon_display_name( weapon_name );
stub.hint_parm2 = cost;
stub.hint_string = &"ZOMBIE_WEAPONCOSTONLY";
stub.cursor_hint = "HINT_WEAPON";
stub.cursor_hint_weapon = weapon_name;
}
stub.cost = cost;
stub.weapon_name = weapon_name;
stub.vo_dialog_id = vo_dialog_id;
stub.flourish_weapon_name = flourish_weapon_name;
stub.ballistic_weapon_name = ballistic_weapon_name;
stub.ballistic_upgraded_weapon_name = ballistic_upgraded_weapon_name;
stub.trigger_func = ::melee_weapon_think;
stub.flourish_fn = flourish_fn;
}
}
change_melee_weapon(weapon_name, current_weapon)
{
current_melee_weapon = self get_player_melee_weapon();
@ -82,6 +171,9 @@ change_melee_weapon(weapon_name, current_weapon)
self seteverhadweaponall(1);
}
self giveweapon("held_" + weapon_name);
self setactionslot(2, "weapon", "held_" + weapon_name);
return current_weapon;
}
@ -145,7 +237,7 @@ do_melee_weapon_flourish_end(gun, flourish_weapon_name, weapon_name, ballistic_w
}
else if (is_melee_weapon(gun))
{
self switchtoweapon(weapon_name);
self switchtoweapon("held_" + weapon_name);
self decrement_is_drinking();
return;
}

View File

@ -1284,7 +1284,10 @@ wait_for_player_to_take(player, weapon, packa_timer, upgrade_as_attachment)
player maps\mp\zombies\_zm_stats::increment_player_stat("pap_weapon_grabbed");
current_weapon = player getcurrentweapon();
if (is_player_valid(player) && !(player.is_drinking > 0) && !is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(current_weapon) && level.revive_tool != current_weapon && "none" != current_weapon && !player hacker_active())
primaries = player getweaponslistprimaries();
weapon_limit = get_player_weapon_limit(player);
if (is_player_valid(player) && !(player.is_drinking > 0) && level.revive_tool != current_weapon && "none" != current_weapon && !player hacker_active() && (primaries.size < weapon_limit || (!is_melee_weapon(current_weapon) && !is_placeable_mine(current_weapon) && !is_equipment(current_weapon))))
{
maps\mp\_demo::bookmark("zm_player_grabbed_packapunch", gettime(), player);
self notify("pap_taken");

View File

@ -418,6 +418,69 @@ head_should_gib(attacker, type, point)
return 1;
}
zombie_death_animscript()
{
team = undefined;
recalc_zombie_array();
if ( isdefined( self._race_team ) )
team = self._race_team;
self reset_attack_spot();
if ( self check_zombie_death_animscript_callbacks() )
return false;
if ( isdefined( level.zombie_death_animscript_override ) )
self [[ level.zombie_death_animscript_override ]]();
if ( self.has_legs && isdefined( self.a.gib_ref ) && self.a.gib_ref == "no_legs" )
self.deathanim = "zm_death";
self.grenadeammo = 0;
if ( isdefined( self.nuked ) )
{
if ( zombie_can_drop_powerups( self ) )
{
if ( isdefined( self.in_the_ground ) && self.in_the_ground == 1 )
{
trace = bullettrace( self.origin + vectorscale( ( 0, 0, 1 ), 100.0 ), self.origin + vectorscale( ( 0, 0, -1 ), 100.0 ), 0, undefined );
origin = trace["position"];
level thread zombie_delay_powerup_drop( origin );
}
else
{
trace = groundtrace( self.origin + vectorscale( ( 0, 0, 1 ), 5.0 ), self.origin + vectorscale( ( 0, 0, -1 ), 300.0 ), 0, undefined );
origin = trace["position"];
level thread zombie_delay_powerup_drop( self.origin );
}
}
}
else
level zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self, team );
if ( isdefined( self.attacker ) && isai( self.attacker ) )
self.attacker notify( "killed", self );
if ( "rottweil72_upgraded_zm" == self.damageweapon && "MOD_RIFLE_BULLET" == self.damagemod )
self thread dragons_breath_flame_death_fx();
if ( issubstr( self.damageweapon, "tazer_knuckles_zm" ) && "MOD_MELEE" == self.damagemod )
{
self.is_on_fire = 0;
self notify( "stop_flame_damage" );
}
if ( self.damagemod == "MOD_BURNED" )
self thread maps\mp\animscripts\zm_death::flame_death_fx();
if ( self.damagemod == "MOD_GRENADE" || self.damagemod == "MOD_GRENADE_SPLASH" )
level notify( "zombie_grenade_death", self.origin );
return false;
}
zombie_can_drop_powerups(zombie)
{
if (!flag("zombie_drop_powerups"))

View File

@ -19,6 +19,26 @@ init_player_offhand_weapons()
init_player_equipment();
}
give_start_weapon( switch_to_weapon )
{
if ( !self hasweapon( level.zombie_melee_weapon_player_init ) )
{
self giveweapon( level.zombie_melee_weapon_player_init );
}
if ( !self hasweapon( "held_" + level.zombie_melee_weapon_player_init ) )
{
self giveweapon( "held_" + level.zombie_melee_weapon_player_init );
self setactionslot( 2, "weapon", "held_" + level.zombie_melee_weapon_player_init );
}
self giveweapon( level.start_weapon );
self givestartammo( level.start_weapon );
if ( isdefined( switch_to_weapon ) && switch_to_weapon )
self switchtoweapon( level.start_weapon );
}
is_headshot(sweapon, shitloc, smeansofdeath)
{
if (smeansofdeath == "MOD_MELEE" || smeansofdeath == "MOD_BAYONET" || smeansofdeath == "MOD_IMPACT" || smeansofdeath == "MOD_UNKNOWN" || smeansofdeath == "MOD_IMPACT")

View File

@ -865,4 +865,9 @@ createballisticknifewatcher_zm(name, weapon)
watcher.onspawnretrievetriggers = maps\mp\zombies\_zm_weap_ballistic_knife::on_spawn_retrieve_trigger;
watcher.storedifferentobject = 1;
watcher.headicon = 0;
}
give_fallback_weapon()
{
self switchtoweapon( "held_" + self get_player_melee_weapon() );
}

View File

@ -287,16 +287,8 @@ wallbuy(weapon_name, target, targetname, origin, angles, play_chalk_fx = 1)
unitrigger_stub.vo_dialog_id = melee_weapon.vo_dialog_id;
unitrigger_stub.flourish_fn = melee_weapon.flourish_fn;
if (is_true(level.disable_melee_wallbuy_icons))
{
unitrigger_stub.cursor_hint = "HINT_NOICON";
unitrigger_stub.cursor_hint_weapon = undefined;
}
else
{
unitrigger_stub.cursor_hint = "HINT_WEAPON";
unitrigger_stub.cursor_hint_weapon = melee_weapon.weapon_name;
}
unitrigger_stub.cursor_hint = "HINT_WEAPON";
unitrigger_stub.cursor_hint_weapon = melee_weapon.weapon_name;
}
if (weapon_name == "tazer_knuckles_zm")

View File

@ -788,6 +788,15 @@ kill_feed()
self.last_griefed_by.meansofdeath = "MOD_UNKNOWN";
}
// show weapon icon for melee damage (except for start melee weapon)
if (self.last_griefed_by.meansofdeath == "MOD_MELEE")
{
if (self.last_griefed_by.weapon != level.zombie_melee_weapon_player_init && self.last_griefed_by.weapon != "held_" + level.zombie_melee_weapon_player_init)
{
self.last_griefed_by.meansofdeath = "MOD_UNKNOWN";
}
}
obituary(self, self.last_griefed_by.attacker, self.last_griefed_by.weapon, self.last_griefed_by.meansofdeath);
}
else
@ -2148,6 +2157,7 @@ grief_laststand_weapons_return()
if (isDefined(self.grief_savedweapon_melee))
{
self set_player_melee_weapon(self.grief_savedweapon_melee);
self setactionslot(2, "weapon", "held_" + self.grief_savedweapon_melee);
}
if (isDefined(self.grief_savedweapon_grenades))