Skip to content

Commit

Permalink
wip on_hit_effect
Browse files Browse the repository at this point in the history
  • Loading branch information
Fris0uman committed Jun 25, 2024
1 parent fe27e2a commit c9daa91
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
12 changes: 12 additions & 0 deletions src/ammo_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ void ammo_effect::load( const JsonObject &jo, const std::string_view )
JsonObject joe = jo.get_object( "explosion" );
aoe_explosion_data = load_explosion_data( joe );
}
if( jo.has_member( "on_hit_effects" ) ) {
JsonArray json_arr = jo.get_array( "on_hit_effects" );
for( JsonObject joe : json_arr ) {
on_hit_effect new_effect;
optional( joe, was_loaded, "bp_to_hit", new_effect.bp_to_hit, bodypart_str_id::NULL_ID() );
optional( joe, was_loaded, "need_touch_skin", new_effect.need_touch_skin, false );
mandatory( joe, was_loaded, "duration", new_effect.duration );
mandatory( joe, was_loaded, "effect", new_effect.effect );
mandatory( joe, was_loaded, "intensity", new_effect.intensity );
on_hit_effects.push_back( new_effect );
}
}
optional( jo, was_loaded, "do_flashbang", do_flashbang, false );
optional( jo, was_loaded, "do_emp_blast", do_emp_blast, false );
optional( jo, was_loaded, "foamcrete_build", foamcrete_build, false );
Expand Down
10 changes: 10 additions & 0 deletions src/ammo_effect.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ template <typename T> class generic_factory;

generic_factory<ammo_effect> &get_all_ammo_effects();

struct on_hit_effect {
bodypart_id bp_to_hit;
bool need_touch_skin;
efftype_id effect;
time_duration duration;
int intensity;
};

struct ammo_effect {
public:
void load( const JsonObject &jo, std::string_view src );
Expand Down Expand Up @@ -53,6 +61,8 @@ struct ammo_effect {
int trail_intensity_max = 0;
int trail_chance = 100;

std::vector<on_hit_effect> on_hit_effects;

// Used by generic_factory
ammo_effect_str_id id;
std::vector<std::pair<ammo_effect_str_id, mod_id>> src;
Expand Down
29 changes: 24 additions & 5 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string>
#include <tuple>

#include "ammo_effect.h"
#include "anatomy.h"
#include "body_part_set.h"
#include "cached_options.h"
Expand Down Expand Up @@ -85,6 +86,7 @@ static const ammo_effect_str_id ammo_effect_FOAMCRETE( "FOAMCRETE" );
static const ammo_effect_str_id ammo_effect_IGNITE( "IGNITE" );
static const ammo_effect_str_id ammo_effect_INCENDIARY( "INCENDIARY" );
static const ammo_effect_str_id ammo_effect_LARGE_BEANBAG( "LARGE_BEANBAG" );
static const ammo_effect_str_id ammo_effect_LIQUID( "LIQUID" );
static const ammo_effect_str_id ammo_effect_MAGIC( "MAGIC" );
static const ammo_effect_str_id ammo_effect_NOGIB( "NOGIB" );
static const ammo_effect_str_id ammo_effect_NO_DAMAGE_SCALING( "NO_DAMAGE_SCALING" );
Expand Down Expand Up @@ -939,11 +941,27 @@ double Creature::accuracy_projectile_attack( dealt_projectile_attack &attack ) c
return attack.missed_by + std::max( 0.0, std::min( 1.0, dodge_rescaled ) );
}

void projectile::apply_effects_nodamage( Creature &target, Creature *source ) const
void projectile::apply_effects_nodamage( Creature &target, Creature *source,
const dealt_damage_instance &dealt_dam, bool soaked_through ) const
{
bool is_liquid = proj_effects.count( ammo_effect_LIQUID );
if( proj_effects.count( ammo_effect_BOUNCE ) ) {
target.add_effect( effect_source( source ), effect_bounced, 1_turns );
}

for( const ammo_effect_str_id &proj_effect : proj_effects ) {
for( const on_hit_effect &on_hit_eff : proj_effect->on_hit_effects ) {
if( on_hit_eff.need_touch_skin && is_liquid && !soaked_through ) {
continue;
}
if( on_hit_eff.bp_to_hit ) {
if( on_hit_eff.bp_to_hit != dealt_dam.bp_hit ) {
continue;
}
}
target.add_effect( on_hit_eff.effect, on_hit_eff.duration, false, on_hit_eff.intensity );
}
}
}

void projectile::apply_effects_damage( Creature &target, Creature *source,
Expand Down Expand Up @@ -1266,8 +1284,6 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
return;
}

proj.apply_effects_nodamage( *this, source );

projectile_attack_results hit_selection = select_body_part_projectile_attack( proj, goodhit,
missed_by );
// Create a copy that records whether the attack is a crit.
Expand Down Expand Up @@ -1296,15 +1312,16 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack
}
}

if( attack.proj.proj_effects.count( "LIQUID" ) > 0 ) {
bool soaked_through = false;
if( attack.proj.proj_effects.count( ammo_effect_LIQUID ) > 0 ) {
if( Character *char_target = as_character() ) {
// clothing_wetness_mult returns the effective permeability of the armor on bp_hit
// as a float between 0 and 1
// 0 permeability means no liquid touches the skin and the damage is negated
// 1 permeability means all liquid touches the skin and no damage is negated
float permeability = char_target->worn.clothing_wetness_mult( hit_selection.bp_hit );
permeability = std::clamp( permeability, 0.0f, 1.0f );

soaked_through = permeability > 0;
impact.mult_damage( permeability );
}
}
Expand All @@ -1317,6 +1334,8 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack

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

proj.apply_effects_nodamage( *this, source, dealt_dam, soaked_through );

if( print_messages ) {
messaging_projectile_attack( source, hit_selection, dealt_dam.total_damage() );
}
Expand Down
3 changes: 2 additions & 1 deletion src/projectile.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ struct projectile {
const dealt_damage_instance &dealt_dam,
bool critical ) const;
// pplies proj_effects to a creature that was hit but not damaged
void apply_effects_nodamage( Creature &target, Creature *source ) const;
void apply_effects_nodamage( Creature &target, Creature *source,
const dealt_damage_instance &dealt_dam, bool soaked_through = false ) const;

projectile();
projectile( const projectile & );
Expand Down
3 changes: 2 additions & 1 deletion src/ranged.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static const ammo_effect_str_id ammo_effect_HEAVY_HIT( "HEAVY_HIT" );
static const ammo_effect_str_id ammo_effect_IGNITE( "IGNITE" );
static const ammo_effect_str_id ammo_effect_LASER( "LASER" );
static const ammo_effect_str_id ammo_effect_LIGHTNING( "LIGHTNING" );
static const ammo_effect_str_id ammo_effect_LIQUID( "LIQUID" );
static const ammo_effect_str_id ammo_effect_MATCHHEAD( "MATCHHEAD" );
static const ammo_effect_str_id ammo_effect_MULTI_EFFECTS( "MULTI_EFFECTS" );
static const ammo_effect_str_id ammo_effect_NON_FOULING( "NON_FOULING" );
Expand Down Expand Up @@ -2099,7 +2100,7 @@ static projectile make_gun_projectile( const item &gun )
proj.proj_effects = gun.ammo_effects();

if( gun.ammo_data()->phase == phase_id::LIQUID ) {
proj.proj_effects.insert( "LIQUID" );
proj.proj_effects.insert( ammo_effect_LIQUID );
}

auto &fx = proj.proj_effects;
Expand Down

0 comments on commit c9daa91

Please sign in to comment.