Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bombastic Perks] Two gun-related perks #76487

Merged
merged 7 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions data/json/monster_weakpoints/abomination_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
{
"id": "armor_thick",
"name": "a thick part of its armor",
"is_good": false,
"armor_mult": { "all": 2.0 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "cut": 1.5 },
Expand Down
2 changes: 2 additions & 0 deletions data/json/monster_weakpoints/arthropod_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
{
"id": "armor_thick",
"name": "a thick part of the exoskeleton",
"is_good": false,
"armor_mult": { "all": 1.5 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "cut": 1.5 },
Expand Down Expand Up @@ -329,6 +330,7 @@
{
"id": "armor_thick",
"name": "a thick part of its armor",
"is_good": false,
"armor_mult": { "all": 1.5 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "cut": 1.5 },
Expand Down
1 change: 1 addition & 0 deletions data/json/monster_weakpoints/cyborg_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
{
"id": "hard_point",
"name": "a particularly thick patch of armor",
"is_good": false,
"armor_mult": { "all": 1.25 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down
3 changes: 3 additions & 0 deletions data/json/monster_weakpoints/generic_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
{
"id": "hard_hide",
"name": "a particularly thick patch of hide",
"is_good": false,
"armor_mult": { "all": 1.25 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down Expand Up @@ -52,6 +53,7 @@
{
"id": "hard_point",
"name": "a particularly thick patch of bone",
"is_good": false,
"armor_mult": { "all": 1.25 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down Expand Up @@ -83,6 +85,7 @@
{
"id": "hard_point",
"name": "a strong, rigid chunk of metal",
"is_good": false,
"armor_mult": { "all": 1.4 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down
4 changes: 4 additions & 0 deletions data/json/monster_weakpoints/humanoid_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
{
"id": "armour_plate_bullet",
"name": "the body armor",
"is_good": false,
"armor_mult": { "cut": 1.5, "stab": 1.5, "bash": 1.5 },
"coverage_mult": { "ranged": 0.8, "melee": 0 },
"//": "Note that most bullet hits on an armour plate probably shatter it, but not all of them shatter it enough to matter for future attacks.",
Expand Down Expand Up @@ -315,6 +316,7 @@
{
"id": "armour_plate_melee",
"name": "the body armor",
"is_good": false,
"armor_mult": { "cut": 1.3, "stab": 1.15, "bash": 1.15 },
"coverage_mult": { "ranged": 0, "melee": 0.8 },
"//": "Note that most bullet hits on an armour plate probably shatter it, but not all of them shatter it enough to matter for future attacks.",
Expand Down Expand Up @@ -446,6 +448,7 @@
"id": "helmet",
"//": "the hard part of the helmet is actually the opposite of a weakpoint.",
"name": "the helmet",
"is_good": false,
"armor_mult": { "physical": 1.5 },
"crit_mult": { "all": 0.5 },
"coverage_mult": { "melee": 0.75 },
Expand Down Expand Up @@ -520,6 +523,7 @@
"id": "helmet",
"name": "the helmet",
"//": "the hard part of the helmet is actually the opposite of a weakpoint.",
"is_good": false,
"armor_mult": { "physical": 1.5 },
"crit_mult": { "all": 0.5 },
"coverage_mult": { "melee": 0.75 },
Expand Down
1 change: 1 addition & 0 deletions data/json/monster_weakpoints/slime_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
{
"id": "insensitive_spot",
"name": "a spot with virtually nothing to damage",
"is_good": false,
"armor_mult": { "all": 1.25 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down
1 change: 1 addition & 0 deletions data/json/monster_weakpoints/triffid_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
{
"id": "thick bark",
"name": "a particularly thick patch of the bark",
"is_good": false,
"armor_mult": { "all": 1.25 },
"crit_mult": { "all": 0.75 },
"coverage_mult": { "melee": 0.75 },
Expand Down
2 changes: 2 additions & 0 deletions data/json/monster_weakpoints/yrax_weakpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
{
"id": "heavy_armor",
"name": "a segment of sloped armor",
"is_good": false,
"armor_mult": { "all": 1 },
"crit_mult": { "all": 0.1 },
"coverage_mult": { "melee": 1.5 },
Expand Down Expand Up @@ -51,6 +52,7 @@
{
"id": "heavy_armor",
"name": "a segment of sloped armor",
"is_good": false,
"armor_mult": { "all": 5 },
"crit_mult": { "all": 0.1 },
"coverage_mult": { "melee": 0.1 },
Expand Down
35 changes: 35 additions & 0 deletions data/mods/BombasticPerks/perkmenu.json
Original file line number Diff line number Diff line change
Expand Up @@ -1361,6 +1361,41 @@
],
"topic": "TALK_PERK_MENU_SELECT_PLAYSTYLE"
},
{
"condition": { "not": { "u_has_trait": "revolvers_are_cool" } },
"text": "Gain [<trait_name:revolvers_are_cool>]",
"effect": [
{ "set_string_var": "<trait_name:revolvers_are_cool>", "target_var": { "context_val": "trait_name" } },
{
"set_string_var": "<trait_description:revolvers_are_cool>",
"target_var": { "context_val": "trait_description" }
},
{ "set_string_var": "revolvers_are_cool", "target_var": { "context_val": "trait_id" } },
{
"set_string_var": "No Requirements",
"target_var": { "context_val": "trait_requirement_description" },
"i18n": true
},
{ "set_condition": "perk_condition", "condition": { "math": [ "0", "==", "0" ] } }
],
"topic": "TALK_PERK_MENU_SELECT_PLAYSTYLE"
},
{
"condition": { "not": { "u_has_trait": "22_is_cool" } },
"text": "Gain [<trait_name:22_is_cool>]",
"effect": [
{ "set_string_var": "<trait_name:22_is_cool>", "target_var": { "context_val": "trait_name" } },
{ "set_string_var": "<trait_description:22_is_cool>", "target_var": { "context_val": "trait_description" } },
{ "set_string_var": "22_is_cool", "target_var": { "context_val": "trait_id" } },
{
"set_string_var": "No Requirements",
"target_var": { "context_val": "trait_requirement_description" },
"i18n": true
},
{ "set_condition": "perk_condition", "condition": { "math": [ "0", "==", "0" ] } }
],
"topic": "TALK_PERK_MENU_SELECT_PLAYSTYLE"
},
{
"condition": { "not": { "u_has_trait": "perk_empath" } },
"text": "Gain [<trait_name:perk_empath>]",
Expand Down
36 changes: 36 additions & 0 deletions data/mods/BombasticPerks/perks.json
Original file line number Diff line number Diff line change
Expand Up @@ -1178,5 +1178,41 @@
"valid": false,
"description": "Exposure to portal storms and related phenomena causes your body change along predictable lines. When out in a portal storm without any protection, you periodically have a chance to mutate.",
"category": [ "perk" ]
},
{
"type": "mutation",
"id": "revolvers_are_cool",
"name": { "str": "Double Action Action" },
"description": "You always knew nothing can beat the good old six shooters. You have a minor bonus using revolvers.",
"points": 0,
"purifiable": false,
"valid": false,
"category": [ "perk" ],
"enchantments": [
{
"condition": { "and": [ { "u_has_wielded_with_flag": "RELOAD_ONE" }, { "u_has_wielded_with_skill": "pistol" } ] },
GuardianDll marked this conversation as resolved.
Show resolved Hide resolved
"values": [
{ "value": "WEAPON_DISPERSION", "multiply": -0.25 },
{ "value": "RANGED_DAMAGE", "add": 6 },
{ "value": "RANGE", "add": 4 }
]
}
]
},
{
"type": "mutation",
"id": "22_is_cool",
"name": { "str": "Rimfire Rebel" },
"description": "You always appreciated the size of this little fella named \"Dot Two Two Long Rifle\", but they laughed at you. Not anymore! You found that the size of a bullet that small is perfect to hit into little spots between armor or narrow places. .22 weapons have additional armor penetration and quadrupled chance to hit a weakpoint.",

Check failure on line 1206 in data/mods/BombasticPerks/perks.json

View workflow job for this annotation

GitHub Actions / Basic Build and Test (Clang 10, Ubuntu, Curses)

(all_mods)=> excessive spaces at this location. 2 required, but 3 found. Suggested fix: remove " " At the following position (marked with caret) "id": "22_is_cool", "name": { "str": "Rimfire Rebel" }, "description": "You always appreciated the size of this little fella named \"Dot Two Two Long Rifle\", but they laughed at you. Not anymore! You found that the size of a bullet that small is perfect to hit into little spots between armor or narrow places. .22 weapons have additional armor penetration and quadrupled chance to hit a weakpoint.", ▲▲▲ "points": 0, "purifiable": false,
GuardianDll marked this conversation as resolved.
Show resolved Hide resolved
"points": 0,
"purifiable": false,
"valid": false,
"category": [ "perk" ],
"enchantments": [
{
"condition": { "u_has_wielded_with_ammotype": "22" },
"values": [ { "value": "RANGED_ARMOR_PENETRATION", "add": 5 }, { "value": "WEAKPOINT_ACCURACY", "multiply": 3 } ]
}
]
}
]
35 changes: 35 additions & 0 deletions doc/EFFECT_ON_CONDITION.md
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,41 @@ check do you wield something with `LONG_SWORDS` weapon category
{ "u_has_wielded_with_weapon_category": "LONG_SWORDS" }
```

### `u_has_wielded_with_skill`, `npc_has_wielded_with_skill`
- type: string or [variable object](#variable-object)
- return true if alpha or beta talker wield a gun or melee weapon with this skill
- gun skills are delivered from `skill` field
- melee weapon skill is delivered from the highest damage type item has

#### Valid talkers:

| Avatar | Character | NPC | Monster | Furniture | Item |
| ------ | --------- | --------- | ---- | ------- | --- |
| ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |

#### Examples
check do you wield a gun with `pistol` skill
```json
{ "u_has_wielded_with_skill": "pistol" }
```

### `u_has_wielded_with_ammotype`, `npc_has_wielded_with_ammotype`
- type: string or [variable object](#variable-object)
- return true if alpha or beta talker wield an item that can have this ammo type
- works with items that allow multiple ammo types

#### Valid talkers:

| Avatar | Character | NPC | Monster | Furniture | Item |
| ------ | --------- | --------- | ---- | ------- | --- |
| ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |

#### Examples
check do you wield a gun with `22` ammo type (.22 LR)
```json
{ "u_has_wielded_with_ammotype": "22" }
```

### `u_can_see`, `npc_can_see`
- type: simple string
- return true if alpha or beta talker can see (not blind)
Expand Down
2 changes: 2 additions & 0 deletions doc/MAGIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ Character status value | Description
`PHASE_DISTANCE` | Distance the character is able to teleport through impassible terrain. Values less than 1 do nothing and the max distance is 48 tiles.
`POWER_TRICKLE` | Generates this amount of millijoules each second. Default value is zero, so better to use `add`
`RANGE` | Modifies your characters range with firearms
`RANGED_ARMOR_PENETRATION` | Adds armor penetration to ranged attacks.
`RANGED_DAMAGE` | Adds damage to ranged attacks.
`RANGE_DODGE` | Chance to dodge projectile attack, no matter of it's speed; Consumes dodges similarly to melee dodges, and fails, if character has no dodges left. `add` and `multiply` behave equally. `add: 0.5` would result in 50% chance to avoid projectile
`READING_EXP` | Changes the minimum you learn from each reading increment.
Expand Down Expand Up @@ -912,6 +913,7 @@ Character status value | Description
`VITAMIN_ABSORB_MOD` | Increases amount of vitamins obtained from the food
`VOMIT_MUL` | Affects your chances to vomit.
`WEAKNESS_TO_WATER` | Amount of damage character gets when wet, once per second; scales with wetness, being 50% wet deal only half of damage; negative values restore hp; flat number with default value of 0, so `multiply` is useful only in combination with `add`; Works with float numbers, so `"add": -0.3` would result in restoring 1 hp with 30% change, and 70% chance to do nothing
`WEAKPOINT_ACCURACY` | Increases the coverage of every weakpoint you hit, therefore, increasing chances to hit said weakpoint. Works only if weakpoint has `"is_good": true` (all weakpoints have it true by default)
`WEAPON_DISPERSION` | Positive value increase the dispersion, negative decrease one.


Expand Down
1 change: 1 addition & 0 deletions doc/MONSTERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ Field | Description
`id` | id of the weakpoint. Defaults to `name`, if not specified.
`name` | name of the weakpoint. Used in hit messages.
`coverage` | base percentage chance of hitting the weakpoint. (e.g. A coverage of 5 means a 5% base chance of hitting the weakpoint)
`is_good` | marks mutation, that is beneficial for you to hit (like headshot); false means it is a bad weakpoint for you to hit (like thick piece of armor); default true;
`coverage_mult` | object mapping weapon types to constant coverage multipliers.
`difficulty` | object mapping weapon types to difficulty values. Difficulty acts as soft "gate" on the attacker's skill. If the the attacker has skill equal to the difficulty, coverage is reduced to 50%.
`armor_mult` | object mapping damage types to multipliers on the monster's base protection, when hitting the weakpoint.
Expand Down
24 changes: 24 additions & 0 deletions src/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1943,6 +1943,28 @@ conditional_t::func f_has_wielded_with_weapon_category( const JsonObject &jo,
};
}

conditional_t::func f_has_wielded_with_skill( const JsonObject &jo, std::string_view member,
bool is_npc )
{
// ideally all this "u wield with X" should be moved to some mutator
// and a single effect should check mutator applied to the item in your hands
str_or_var w_skill = get_str_or_var( jo.get_member( member ), member, true );
return [w_skill, is_npc]( dialogue const & d ) {

return d.actor( is_npc )->wielded_with_weapon_skill( skill_id( w_skill.evaluate( d ) ) );
};
}

conditional_t::func f_has_wielded_with_ammotype( const JsonObject &jo, std::string_view member,
bool is_npc )
{
str_or_var w_ammotype = get_str_or_var( jo.get_member( member ), member, true );
return [w_ammotype, is_npc]( dialogue const & d ) {

return d.actor( is_npc )->wielded_with_item_ammotype( ammotype( w_ammotype.evaluate( d ) ) );
};
}

conditional_t::func f_can_see( bool is_npc )
{
return [is_npc]( dialogue const & d ) {
Expand Down Expand Up @@ -2531,6 +2553,8 @@ parsers = {
{"u_has_worn_with_flag", "npc_has_worn_with_flag", jarg::member, &conditional_fun::f_has_worn_with_flag },
{"u_has_wielded_with_flag", "npc_has_wielded_with_flag", jarg::member, &conditional_fun::f_has_wielded_with_flag },
{"u_has_wielded_with_weapon_category", "npc_has_wielded_with_weapon_category", jarg::member, &conditional_fun::f_has_wielded_with_weapon_category },
{"u_has_wielded_with_skill", "npc_has_wielded_with_skill", jarg::member, &conditional_fun::f_has_wielded_with_skill },
{"u_has_wielded_with_ammotype", "npc_has_wielded_with_ammotype", jarg::member, &conditional_fun::f_has_wielded_with_ammotype },
{"u_is_on_terrain", "npc_is_on_terrain", jarg::member, &conditional_fun::f_is_on_terrain },
{"u_is_on_terrain_with_flag", "npc_is_on_terrain_with_flag", jarg::member, &conditional_fun::f_is_on_terrain_with_flag },
{"u_is_in_field", "npc_is_in_field", jarg::member, &conditional_fun::f_is_in_field },
Expand Down
2 changes: 2 additions & 0 deletions src/magic_enchantment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ namespace io
case enchant_vals::mod::PAIN_PENALTY_MOD_SPEED: return "PAIN_PENALTY_MOD_SPEED";
case enchant_vals::mod::MELEE_DAMAGE: return "MELEE_DAMAGE";
case enchant_vals::mod::RANGED_DAMAGE: return "RANGED_DAMAGE";
case enchant_vals::mod::RANGED_ARMOR_PENETRATION: return "RANGED_ARMOR_PENETRATION";
case enchant_vals::mod::DODGE_CHANCE: return "DODGE_CHANCE";
case enchant_vals::mod::BONUS_BLOCK: return "BONUS_BLOCK";
case enchant_vals::mod::BONUS_DODGE: return "BONUS_DODGE";
Expand Down Expand Up @@ -202,6 +203,7 @@ namespace io
case enchant_vals::mod::SWEAT_MULTIPLIER: return "SWEAT_MULTIPLIER";
case enchant_vals::mod::STAMINA_REGEN_MOD: return "STAMINA_REGEN_MOD";
case enchant_vals::mod::MOVEMENT_EXERTION_MODIFIER: return "MOVEMENT_EXERTION_MODIFIER";
case enchant_vals::mod::WEAKPOINT_ACCURACY: return "WEAKPOINT_ACCURACY";
case enchant_vals::mod::NUM_MOD: break;
}
cata_fatal( "Invalid enchant_vals::mod" );
Expand Down
2 changes: 2 additions & 0 deletions src/magic_enchantment.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum class mod : int {
BONUS_BLOCK,
MELEE_DAMAGE,
RANGED_DAMAGE,
RANGED_ARMOR_PENETRATION,
ATTACK_NOISE,
SHOUT_NOISE,
FOOTSTEP_NOISE,
Expand Down Expand Up @@ -179,6 +180,7 @@ enum class mod : int {
SWEAT_MULTIPLIER,
STAMINA_REGEN_MOD,
MOVEMENT_EXERTION_MODIFIER,
WEAKPOINT_ACCURACY,
NUM_MOD
};
} // namespace enchant_vals
Expand Down
2 changes: 2 additions & 0 deletions src/ranged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,8 @@ int Character::fire_gun( const tripoint &target, int shots, item &gun, item_loca

for( damage_unit &elem : proj.impact.damage_units ) {
elem.amount = enchantment_cache->modify_value( enchant_vals::mod::RANGED_DAMAGE, elem.amount );
elem.res_pen = enchantment_cache->modify_value( enchant_vals::mod::RANGED_ARMOR_PENETRATION,
elem.res_pen );
}

dispersion_sources dispersion = total_gun_dispersion( gun, recoil_total(), proj.shot_spread );
Expand Down
6 changes: 6 additions & 0 deletions src/talker.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,12 @@ class talker
virtual bool wielded_with_weapon_category( const weapon_category_id & ) const {
return false;
}
virtual bool wielded_with_weapon_skill( const skill_id & ) const {
return false;
}
virtual bool wielded_with_item_ammotype( const ammotype & ) const {
return false;
}
virtual bool has_item_with_flag( const flag_id & ) const {
return false;
}
Expand Down
31 changes: 31 additions & 0 deletions src/talker_character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,37 @@ bool talker_character_const::wielded_with_weapon_category( const weapon_category
me_chr_const->get_wielded_item()->typeId()->weapon_category.count( w_cat ) > 0;
}

bool talker_character_const::wielded_with_weapon_skill( const skill_id &w_skill ) const
{
if( me_chr_const->get_wielded_item() ) {
item *it = me_chr_const->get_wielded_item().get_item();
skill_id it_skill = it->is_gun() ? it->gun_skill() : it->melee_skill();
return it_skill == w_skill;
} else {
return false;
}
}

bool talker_character_const::wielded_with_item_ammotype( const ammotype &w_ammotype ) const
{
if( !me_chr_const->get_wielded_item() ) {
return false;
}
item *it = me_chr_const->get_wielded_item().get_item();
if( it->ammo_types().empty() ) {
return false;
}
std::set<ammotype> it_ammotype = it->ammo_types();
bool match = false;

for( ammotype ammo : it_ammotype ) {
if( ammo == w_ammotype ) {
match = true;
}
}
return match;
}

bool talker_character_const::has_item_with_flag( const flag_id &flag ) const
{
return me_chr_const->cache_has_item_with( flag );
Expand Down
Loading
Loading