Skip to content

Commit

Permalink
refine calculations, add field for guns also, add debug tool to damag…
Browse files Browse the repository at this point in the history
…e items
  • Loading branch information
GuardianDll committed Jun 26, 2024
1 parent b779264 commit 9666ad5
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 8 deletions.
65 changes: 65 additions & 0 deletions data/json/items/tool/debug_tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,70 @@
"symbol": ";",
"color": "light_gray",
"use_action": [ "DBG_LUX_METER" ]
},
{
"id": "debug_item_damager",
"type": "TOOL",
"category": "tools",
"name": { "str_sp": "debug item damager (simple)" },
"description": "Deals 1 full bar of damage to an item you wield.",
"weight": "1 g",
"volume": "1 ml",
"material": [ "plastic" ],
"symbol": ";",
"color": "light_gray",
"use_action": {
"type": "effect_on_conditions",
"menu_text": "Damage item",
"effect_on_conditions": [
{
"id": "EOC_FIND_ITEM_simple",
"effect": {
"u_run_inv_eocs": "all",
"search_data": [ { "wielded_only": true } ],
"true_eocs": {
"id": "EOC_DAMAGE_ITEM_simple",
"effect": [
{ "math": [ "_hp_before", "=", "n_hp('ALL')" ] },
{ "math": [ "n_hp('ALL')", "-=", "1000" ] },
{ "math": [ "_hp_after", "=", "n_hp('ALL')" ] },
{ "u_message": "<npc_name> have had <context_val:hp_before> hp, now has <context_val:hp_after> hp." }
]
}
}
}
]
}
},
{
"id": "debug_item_damager_adv",
"type": "TOOL",
"category": "tools",
"name": { "str_sp": "debug item damager (advanced)" },
"description": "Deals damage to items you pick.",
"weight": "1 g",
"volume": "1 ml",
"material": [ "plastic" ],
"symbol": ";",
"color": "light_gray",
"use_action": {
"type": "effect_on_conditions",
"menu_text": "Damage item",
"effect_on_conditions": [
{
"id": "EOC_FIND_ITEM",
"effect": {
"u_run_inv_eocs": "manual_mult",
"true_eocs": {
"id": "EOC_DAMAGE_ITEM",
"effect": [
{ "math": [ "n_hp('ALL')", "-=", "num_input('Amount of damage, 1000 is one bar of damage.', 1000)" ] },
{ "u_message": "Dealt damage to all items." }
]
}
}
}
]
}
}
]
3 changes: 2 additions & 1 deletion src/item_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2839,6 +2839,7 @@ void Item_factory::load( islot_gun &slot, const JsonObject &jo, const std::strin
assign( jo, "heat_per_shot", slot.heat_per_shot, strict, 0.0 );
assign( jo, "cooling_value", slot.cooling_value, strict, 0.0 );
assign( jo, "overheat_threshold", slot.overheat_threshold, strict, -1.0 );
optional(jo, false, "gun_fail_to_feed_chance", slot.gun_fail_to_feed_chance, 0.00027 );

if( jo.has_array( "valid_mod_locations" ) ) {
slot.valid_mod_locations.clear();
Expand Down Expand Up @@ -3571,7 +3572,7 @@ void Item_factory::load( islot_magazine &slot, const JsonObject &jo, const std::
assign( jo, "count", slot.count, strict, 0 );
assign( jo, "default_ammo", slot.default_ammo, strict );
assign( jo, "reload_time", slot.reload_time, strict, 0 );
assign( jo, "mag_jam_odds", slot.mag_jam_odds, strict, 0, 1000 );
optional(jo, false, "mag_fail_to_feed_chance", slot.mag_fail_to_feed_chance, 0.00053 );
assign( jo, "linkage", slot.linkage, strict );
}

Expand Down
9 changes: 7 additions & 2 deletions src/itype.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,11 @@ struct islot_gun : common_ranged_data {
*/
double overheat_threshold = -1.0;

/**
* Chance for the gun to fail to feed.
*/
double gun_fail_to_feed_chance = 0.00027;

std::map<ammotype, std::set<itype_id>> cached_ammos;

/**
Expand Down Expand Up @@ -945,8 +950,8 @@ struct islot_magazine {
/** How long it takes to load each unit of ammo into the magazine */
int reload_time = 100;

/** Permille for the gun to jam, usually due the size of the magazine*/
int mag_jam_odds = 0;
/** Permille for the gun to fail to feed, usually due the size of the magazine*/
double mag_fail_to_feed_chance = 0.00053 ;

/** For ammo belts one linkage (of given type) is dropped for each unit of ammo consumed */
std::optional<itype_id> linkage;
Expand Down
26 changes: 21 additions & 5 deletions src/ranged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,20 @@ bool Character::handle_gun_damage( item &it )
return false;
}


double mag_ftf_chance = 0.0;
double mag_damage = 0.0;
if (it.magazine_current()) {
mag_ftf_chance = it.magazine_current()->type->magazine->mag_fail_to_feed_chance;
mag_damage = it.magazine_current()->damage() / 1000.0;
}
const double gun_damage = it.damage() / 1000.0;
const double gun_ftf_chance = firing.gun_fail_to_feed_chance;

const double jam_chance = (mag_ftf_chance + gun_ftf_chance) * std::pow(2, (gun_damage * 1.75) + (mag_damage * 2));

add_msg_debug(debugmode::DF_RANGED, "Gun fail to feed chance: %g\nMagazine fail to feed chance: %g\nGun damage level: %g\nMagazine damage level: %g\nFail to feed chance: %g%%", gun_ftf_chance, mag_ftf_chance, gun_damage, mag_damage, jam_chance * 100);

// Here we check if we're underwater and whether we should misfire.
// As a result this causes no damage to the firearm, note that some guns are waterproof
// and so are immune to this effect, note also that WATERPROOF_GUN status does not
Expand All @@ -690,14 +704,16 @@ bool Character::handle_gun_damage( item &it )
// effect as current guns have a durability between 5 and 9 this results in
// a chance of mechanical failure between 1/(64*3) and 1/(1024*3) on any given shot.
// the malfunction can't cause damage
} else if( one_in( ( 2 << effective_durability ) * 3 ) && !it.has_flag( flag_NEVER_JAMS ) ) {
add_msg_player_or_npc( _( "Your %s malfunctions!" ),
_( "<npcname>'s %s malfunctions!" ),
it.tname() );
}
else if (one_in((2 << effective_durability) * 3) && !it.has_flag(flag_NEVER_JAMS)) {
add_msg_player_or_npc(_("Your %s malfunctions!"),
_("<npcname>'s %s malfunctions!"),
it.tname());
return false;
// Here we check for a chance for the weapon to suffer a failure to feed
// usually caused by the magazine size or condition
else if ( x_in_y( it.magazine_current()->type->magazine->mag_jam_odds, 1000 )) {
}
else if (x_in_y(jam_chance, 1 )) {
add_msg_player_or_npc(_("Your %s didn't load into the chamber!"),
_("<npcname>'s %s didn't load into the chamber!"),
it.tname());
Expand Down

0 comments on commit 9666ad5

Please sign in to comment.