Skip to content

Commit c9daa91

Browse files
committed
wip on_hit_effect
1 parent fe27e2a commit c9daa91

File tree

5 files changed

+50
-7
lines changed

5 files changed

+50
-7
lines changed

src/ammo_effect.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ void ammo_effect::load( const JsonObject &jo, const std::string_view )
9090
JsonObject joe = jo.get_object( "explosion" );
9191
aoe_explosion_data = load_explosion_data( joe );
9292
}
93+
if( jo.has_member( "on_hit_effects" ) ) {
94+
JsonArray json_arr = jo.get_array( "on_hit_effects" );
95+
for( JsonObject joe : json_arr ) {
96+
on_hit_effect new_effect;
97+
optional( joe, was_loaded, "bp_to_hit", new_effect.bp_to_hit, bodypart_str_id::NULL_ID() );
98+
optional( joe, was_loaded, "need_touch_skin", new_effect.need_touch_skin, false );
99+
mandatory( joe, was_loaded, "duration", new_effect.duration );
100+
mandatory( joe, was_loaded, "effect", new_effect.effect );
101+
mandatory( joe, was_loaded, "intensity", new_effect.intensity );
102+
on_hit_effects.push_back( new_effect );
103+
}
104+
}
93105
optional( jo, was_loaded, "do_flashbang", do_flashbang, false );
94106
optional( jo, was_loaded, "do_emp_blast", do_emp_blast, false );
95107
optional( jo, was_loaded, "foamcrete_build", foamcrete_build, false );

src/ammo_effect.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ template <typename T> class generic_factory;
1919

2020
generic_factory<ammo_effect> &get_all_ammo_effects();
2121

22+
struct on_hit_effect {
23+
bodypart_id bp_to_hit;
24+
bool need_touch_skin;
25+
efftype_id effect;
26+
time_duration duration;
27+
int intensity;
28+
};
29+
2230
struct ammo_effect {
2331
public:
2432
void load( const JsonObject &jo, std::string_view src );
@@ -53,6 +61,8 @@ struct ammo_effect {
5361
int trail_intensity_max = 0;
5462
int trail_chance = 100;
5563

64+
std::vector<on_hit_effect> on_hit_effects;
65+
5666
// Used by generic_factory
5767
ammo_effect_str_id id;
5868
std::vector<std::pair<ammo_effect_str_id, mod_id>> src;

src/creature.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <string>
1313
#include <tuple>
1414

15+
#include "ammo_effect.h"
1516
#include "anatomy.h"
1617
#include "body_part_set.h"
1718
#include "cached_options.h"
@@ -85,6 +86,7 @@ static const ammo_effect_str_id ammo_effect_FOAMCRETE( "FOAMCRETE" );
8586
static const ammo_effect_str_id ammo_effect_IGNITE( "IGNITE" );
8687
static const ammo_effect_str_id ammo_effect_INCENDIARY( "INCENDIARY" );
8788
static const ammo_effect_str_id ammo_effect_LARGE_BEANBAG( "LARGE_BEANBAG" );
89+
static const ammo_effect_str_id ammo_effect_LIQUID( "LIQUID" );
8890
static const ammo_effect_str_id ammo_effect_MAGIC( "MAGIC" );
8991
static const ammo_effect_str_id ammo_effect_NOGIB( "NOGIB" );
9092
static const ammo_effect_str_id ammo_effect_NO_DAMAGE_SCALING( "NO_DAMAGE_SCALING" );
@@ -939,11 +941,27 @@ double Creature::accuracy_projectile_attack( dealt_projectile_attack &attack ) c
939941
return attack.missed_by + std::max( 0.0, std::min( 1.0, dodge_rescaled ) );
940942
}
941943

942-
void projectile::apply_effects_nodamage( Creature &target, Creature *source ) const
944+
void projectile::apply_effects_nodamage( Creature &target, Creature *source,
945+
const dealt_damage_instance &dealt_dam, bool soaked_through ) const
943946
{
947+
bool is_liquid = proj_effects.count( ammo_effect_LIQUID );
944948
if( proj_effects.count( ammo_effect_BOUNCE ) ) {
945949
target.add_effect( effect_source( source ), effect_bounced, 1_turns );
946950
}
951+
952+
for( const ammo_effect_str_id &proj_effect : proj_effects ) {
953+
for( const on_hit_effect &on_hit_eff : proj_effect->on_hit_effects ) {
954+
if( on_hit_eff.need_touch_skin && is_liquid && !soaked_through ) {
955+
continue;
956+
}
957+
if( on_hit_eff.bp_to_hit ) {
958+
if( on_hit_eff.bp_to_hit != dealt_dam.bp_hit ) {
959+
continue;
960+
}
961+
}
962+
target.add_effect( on_hit_eff.effect, on_hit_eff.duration, false, on_hit_eff.intensity );
963+
}
964+
}
947965
}
948966

949967
void projectile::apply_effects_damage( Creature &target, Creature *source,
@@ -1266,8 +1284,6 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
12661284
return;
12671285
}
12681286

1269-
proj.apply_effects_nodamage( *this, source );
1270-
12711287
projectile_attack_results hit_selection = select_body_part_projectile_attack( proj, goodhit,
12721288
missed_by );
12731289
// Create a copy that records whether the attack is a crit.
@@ -1296,15 +1312,16 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
12961312
}
12971313
}
12981314

1299-
if( attack.proj.proj_effects.count( "LIQUID" ) > 0 ) {
1315+
bool soaked_through = false;
1316+
if( attack.proj.proj_effects.count( ammo_effect_LIQUID ) > 0 ) {
13001317
if( Character *char_target = as_character() ) {
13011318
// clothing_wetness_mult returns the effective permeability of the armor on bp_hit
13021319
// as a float between 0 and 1
13031320
// 0 permeability means no liquid touches the skin and the damage is negated
13041321
// 1 permeability means all liquid touches the skin and no damage is negated
13051322
float permeability = char_target->worn.clothing_wetness_mult( hit_selection.bp_hit );
13061323
permeability = std::clamp( permeability, 0.0f, 1.0f );
1307-
1324+
soaked_through = permeability > 0;
13081325
impact.mult_damage( permeability );
13091326
}
13101327
}
@@ -1317,6 +1334,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
13171334

13181335
proj.apply_effects_damage( *this, source, dealt_dam, goodhit < accuracy_critical );
13191336

1337+
proj.apply_effects_nodamage( *this, source, dealt_dam, soaked_through );
1338+
13201339
if( print_messages ) {
13211340
messaging_projectile_attack( source, hit_selection, dealt_dam.total_damage() );
13221341
}

src/projectile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ struct projectile {
5151
const dealt_damage_instance &dealt_dam,
5252
bool critical ) const;
5353
// pplies proj_effects to a creature that was hit but not damaged
54-
void apply_effects_nodamage( Creature &target, Creature *source ) const;
54+
void apply_effects_nodamage( Creature &target, Creature *source,
55+
const dealt_damage_instance &dealt_dam, bool soaked_through = false ) const;
5556

5657
projectile();
5758
projectile( const projectile & );

src/ranged.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static const ammo_effect_str_id ammo_effect_HEAVY_HIT( "HEAVY_HIT" );
8686
static const ammo_effect_str_id ammo_effect_IGNITE( "IGNITE" );
8787
static const ammo_effect_str_id ammo_effect_LASER( "LASER" );
8888
static const ammo_effect_str_id ammo_effect_LIGHTNING( "LIGHTNING" );
89+
static const ammo_effect_str_id ammo_effect_LIQUID( "LIQUID" );
8990
static const ammo_effect_str_id ammo_effect_MATCHHEAD( "MATCHHEAD" );
9091
static const ammo_effect_str_id ammo_effect_MULTI_EFFECTS( "MULTI_EFFECTS" );
9192
static const ammo_effect_str_id ammo_effect_NON_FOULING( "NON_FOULING" );
@@ -2099,7 +2100,7 @@ static projectile make_gun_projectile( const item &gun )
20992100
proj.proj_effects = gun.ammo_effects();
21002101

21012102
if( gun.ammo_data()->phase == phase_id::LIQUID ) {
2102-
proj.proj_effects.insert( "LIQUID" );
2103+
proj.proj_effects.insert( ammo_effect_LIQUID );
21032104
}
21042105

21052106
auto &fx = proj.proj_effects;

0 commit comments

Comments
 (0)