From e32d9ab6b218d3f36c9bbfe0f4fdfdeca99ac336 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Wed, 2 Oct 2019 19:04:36 +0300 Subject: [PATCH 01/11] Jsonized ammo effects --- data/json/ammo_effects.json | 178 ++++++++++++++++++++++++++++++++++++ src/ammo_effect.cpp | 130 ++++++++++++++++++++++++++ src/ammo_effect.h | 63 +++++++++++++ src/explosion.h | 18 ++++ src/init.cpp | 5 + src/projectile.cpp | 154 ++++++------------------------- src/projectile.h | 2 +- src/string_id_null_ids.cpp | 1 + src/turret.cpp | 2 +- src/type_id.h | 4 + 10 files changed, 427 insertions(+), 130 deletions(-) create mode 100644 data/json/ammo_effects.json create mode 100644 src/ammo_effect.cpp create mode 100644 src/ammo_effect.h diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json new file mode 100644 index 0000000000000..5e0a630aa23e6 --- /dev/null +++ b/data/json/ammo_effects.json @@ -0,0 +1,178 @@ +[ + { + "id": "AE_NULL", + "type": "ammo_effect", + "effect_tag": "", + "aoe": { + "field_type": "fd_null", + "intensity_min": 0, + "intensity_max": 0, + "radius": 0, + "radius_z": 0, + "chance": 1, + "size": 0, + "check_passable": false, + "check_sees": false, + "check_sees_radius": 0 + }, + "explosion": { + "power": 0, + "distance_factor": 0.8, + "fire": false, + "shrapnel": { "casing_mass": 0, "fragment_mass": 0.005, "recovery": 0, "drop": "null" } + }, + "do_flashbang": false, + "do_emp_blast": false + }, + { + "id": "AE_NAPALM", + "type": "ammo_effect", + "effect_tag": "NAPALM", + "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "size": 3 }, + "explosion": { "power": 60, "distance_factor": 0.7, "fire": true } + }, + { + "id": "AE_NAPALM_BIG", + "type": "ammo_effect", + "effect_tag": "NAPALM_BIG", + "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "radius": 3, "size": 4 }, + "explosion": { "power": 360, "distance_factor": 0.8, "fire": true } + }, + { + "id": "AE_PYROPHORIC", + "type": "ammo_effect", + "effect_tag": "PYROPHORIC", + "aoe": { "field_type": "fd_fire", "intensity_min": 2, "intensity_max": 2, "radius": 3 }, + "explosion": { "power": 360, "distance_factor": 0.8, "fire": true } + }, + { + "id": "AE_ACIDBOMB", + "type": "ammo_effect", + "effect_tag": "ACIDBOMB", + "aoe": { "field_type": "fd_acid", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_TOXICGAS", + "type": "ammo_effect", + "effect_tag": "TOXICGAS", + "aoe": { "field_type": "fd_toxic_gas", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_GAS_FUNGICIDAL", + "type": "ammo_effect", + "effect_tag": "GAS_FUNGICIDAL", + "aoe": { "field_type": "fd_fungicidal_gas", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_GAS_INSECTICIDAL", + "type": "ammo_effect", + "effect_tag": "GAS_INSECTICIDAL", + "aoe": { "field_type": "fd_insecticidal_gas", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_SMOKE", + "type": "ammo_effect", + "effect_tag": "SMOKE", + "aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_SMOKE_BIG", + "type": "ammo_effect", + "effect_tag": "SMOKE_BIG", + "aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3, "radius": 6 } + }, + { + "id": "AE_FLARE", + "type": "ammo_effect", + "effect_tag": "FLARE", + "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1 } + }, + { + "id": "AE_LIGHTNING", + "type": "ammo_effect", + "effect_tag": "LIGHTNING", + "aoe": { "field_type": "fd_electricity", "intensity_min": 3, "intensity_max": 3 } + }, + { + "id": "AE_PLASMA", + "type": "ammo_effect", + "effect_tag": "PLASMA", + "aoe": { "field_type": "fd_plasma", "intensity_min": 2, "intensity_max": 3, "chance": 2 } + }, + { + "id": "AE_PLASMA", + "type": "ammo_effect", + "effect_tag": "PLASMA", + "aoe": { "field_type": "fd_plasma", "intensity_min": 2, "intensity_max": 3, "chance": 2 } + }, + { + "id": "AE_EXPLOSIVE_HUGE", + "type": "ammo_effect", + "effect_tag": "EXPLOSIVE_HUGE", + "aoe": { "size": 4 }, + "explosion": { "power": 1200 } + }, + { + "id": "AE_EXPLOSIVE_BIG", + "type": "ammo_effect", + "effect_tag": "EXPLOSIVE_BIG", + "aoe": { "size": 3 }, + "explosion": { "power": 1200 } + }, + { + "id": "AE_EXPLOSIVE_HUGE", + "type": "ammo_effect", + "effect_tag": "EXPLOSIVE_HUGE", + "aoe": { "size": 3 }, + "explosion": { "power": 600 } + }, + { + "id": "AE_EXPLOSIVE", + "type": "ammo_effect", + "effect_tag": "EXPLOSIVE", + "aoe": { "size": 2 }, + "explosion": { "power": 360 } + }, + { + "id": "AE_EXPLOSIVE_SMALL", + "type": "ammo_effect", + "effect_tag": "EXPLOSIVE_SMALL", + "aoe": { "size": 2 }, + "explosion": { "power": 360, "distance_factor": 0.4 } + }, + { + "id": "AE_FRAG", + "type": "ammo_effect", + "effect_tag": "FRAG", + "aoe": { "size": 15 }, + "explosion": { "power": 185, "shrapnel": { "casing_mass": 212, "fragment_mass": 0.05 } } + }, + { + "id": "AE_MININUKE_MOD", + "type": "ammo_effect", + "effect_tag": "MININUKE_MOD", + "aoe": { + "field_type": "fd_nuke_gas", + "intensity_min": 3, + "intensity_max": 3, + "radius": 18, + "size": 1, + "check_passable": true, + "check_sees": true, + "check_sees_radius": 3 + }, + "explosion": { "power": 72000000 } + }, + { + "id": "AE_FLASHBANG", + "type": "ammo_effect", + "effect_tag": "FLASHBANG", + "do_flashbang": true + }, + { + "id": "AE_EMP", + "type": "ammo_effect", + "effect_tag": "EMP", + "do_emp_blast": true + } +] diff --git a/src/ammo_effect.cpp b/src/ammo_effect.cpp new file mode 100644 index 0000000000000..ebd4bf41ca0fd --- /dev/null +++ b/src/ammo_effect.cpp @@ -0,0 +1,130 @@ +#include "ammo_effect.h" + +#include "generic_factory.h" +#include "json.h" + +namespace +{ + +generic_factory all_ammo_effects( "ammo effects" ); + +} // namespace + +/** @relates int_id */ +template<> +bool int_id::is_valid() const +{ + return all_ammo_effects.is_valid( *this ); +} + +/** @relates int_id */ +template<> +const ammo_effect &int_id::obj() const +{ + return all_ammo_effects.obj( *this ); +} + +/** @relates int_id */ +template<> +const string_id &int_id::id() const +{ + return all_ammo_effects.convert( *this ); +} + +/** @relates string_id */ +template<> +bool string_id::is_valid() const +{ + return all_ammo_effects.is_valid( *this ); +} + +/** @relates string_id */ +template<> +const ammo_effect &string_id::obj() const +{ + return all_ammo_effects.obj( *this ); +} + +/** @relates string_id */ +template<> +int_id string_id::id() const +{ + return all_ammo_effects.convert( *this, AE_NULL ); +} + +/** @relates int_id */ +template<> +int_id::int_id( const string_id &id ) : _id( id.id() ) +{ +} + +void ammo_effect::load( JsonObject &jo, const std::string & ) +{ + mandatory( jo, was_loaded, "effect_tag", effect_tag ); + if( jo.has_member( "aoe" ) ) { + JsonObject joa = jo.get_object( "aoe" ); + optional( joa, was_loaded, "field_type", aoe_field_type_name, "fd_null" ); + optional( joa, was_loaded, "intensity_min", aoe_intensity_min, 0 ); + optional( joa, was_loaded, "intensity_max", aoe_intensity_max, 0 ); + optional( joa, was_loaded, "radius", aoe_radius, 1 ); + optional( joa, was_loaded, "radius_z", aoe_radius_z, 0 ); + optional( joa, was_loaded, "chance", aoe_chance, 1 ); + optional( joa, was_loaded, "size", aoe_size, 0 ); + optional( joa, was_loaded, "check_passable", aoe_check_passable, false ); + optional( joa, was_loaded, "check_sees", aoe_check_sees, false ); + optional( joa, was_loaded, "check_sees_radius", aoe_check_sees_radius, 0 ); + } + if( jo.has_member( "explosion" ) ) { + JsonObject joe = jo.get_object( "explosion" ); + aoe_explosion_data = load_explosion_data( joe ); + } + optional( jo, was_loaded, "do_flashbang", do_flashbang, false ); + optional( jo, was_loaded, "do_emp_blast", do_emp_blast, false ); +} + +void ammo_effect::finalize() +{ + for( const ammo_effect &ae : ammo_effects::get_all() ) { + const_cast( ae ).aoe_field_type = field_type_id( ae.aoe_field_type_name ); + } + +} + +void ammo_effect::check() const +{ +} + +size_t ammo_effect::count() +{ + return all_ammo_effects.size(); +} + +void ammo_effects::load( JsonObject &jo, const std::string &src ) +{ + all_ammo_effects.load( jo, src ); +} + +void ammo_effects::finalize_all() +{ + all_ammo_effects.finalize(); + for( const ammo_effect &ae : all_ammo_effects.get_all() ) { + const_cast( ae ).finalize(); + } +} + +void ammo_effects::check_consistency() +{ + all_ammo_effects.check(); +} + +void ammo_effects::reset() +{ + all_ammo_effects.reset(); +} + +const std::vector &ammo_effects::get_all() +{ + return all_ammo_effects.get_all(); +} + +ammo_effect_id AE_NULL; diff --git a/src/ammo_effect.h b/src/ammo_effect.h new file mode 100644 index 0000000000000..83b549f036a5c --- /dev/null +++ b/src/ammo_effect.h @@ -0,0 +1,63 @@ +#pragma once +#ifndef AMMO_EFFECT_H +#define AMMO_EFFECT_H + +#include +#include + +#include "explosion.h" +#include "field_type.h" +#include "type_id.h" + +class JsonObject; + +struct ammo_effect { + public: + void load( JsonObject &jo, const std::string &src ); + void finalize(); + void check() const; + + public: + std::string effect_tag; + + field_type_id aoe_field_type = fd_null; + /** used during JSON loading only */ + std::string aoe_field_type_name = "fd_null"; + int aoe_intensity_min = 0; + int aoe_intensity_max = 0; + int aoe_radius = 1; + int aoe_radius_z = 0; + int aoe_chance = 1; + int aoe_size = 0; + explosion_data aoe_explosion_data; + bool aoe_check_passable = false; + + bool aoe_check_sees = false; + int aoe_check_sees_radius = 0; + bool do_flashbang = false; + bool do_emp_blast = false; + + public: + // Used by generic_factory + string_id id; + bool was_loaded = false; + + public: + static size_t count(); +}; + +namespace ammo_effects +{ + +void load( JsonObject &jo, const std::string &src ); +void finalize_all(); +void check_consistency(); +void reset(); + +const std::vector &get_all(); + +} // namespace ammo_effects + +extern ammo_effect_id AE_NULL; + +#endif diff --git a/src/explosion.h b/src/explosion.h index c47a6878a5dfc..eb67aa6ea2516 100644 --- a/src/explosion.h +++ b/src/explosion.h @@ -17,6 +17,15 @@ struct shrapnel_data { // Percentage int recovery = 0; itype_id drop = "null"; + + shrapnel_data() {} + shrapnel_data( int casing_mass, float fragment_mass = 0.005, int recovery = 0, + itype_id drop = "null" ) + : casing_mass( casing_mass ) + , fragment_mass( fragment_mass ) + , recovery( recovery ) + , drop( drop ) { + } }; struct explosion_data { @@ -31,6 +40,15 @@ struct explosion_data { float power_at_range( float dist ) const; /** Returns the distance at which the power drops below 1. */ int safe_range() const; + + explosion_data() {} + explosion_data( float power, float distance_factor = 0.8f, bool fire = false, + shrapnel_data shrapnel = {} ) + : power( power ) + , distance_factor( distance_factor ) + , fire( fire ) + , shrapnel( shrapnel ) { + } }; // handles explosion related functions diff --git a/src/init.cpp b/src/init.cpp index 69a29f999bc56..1be3e7806782f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -81,6 +81,7 @@ #include "construction_category.h" #include "overmap.h" #include "clothing_mod.h" +#include "ammo_effect.h" DynamicDataLoader::DynamicDataLoader() { @@ -188,6 +189,7 @@ void DynamicDataLoader::initialize() add( "json_flag", &json_flag::load ); add( "fault", &fault::load_fault ); add( "field_type", &field_types::load ); + add( "ammo_effect", &ammo_effects::load ); add( "emit", &emit::load_emit ); add( "activity_type", &activity_type::load ); add( "vitamin", &vitamin::load_vitamin ); @@ -467,6 +469,7 @@ void DynamicDataLoader::unload_data() requirement_data::reset(); vitamin::reset(); field_types::reset(); + ammo_effects::reset(); emit::reset(); activity_type::reset(); fault::reset(); @@ -550,6 +553,7 @@ void DynamicDataLoader::finalize_loaded_data( loading_ui &ui ) const std::vector entries = {{ { _( "Body parts" ), &body_part_struct::finalize_all }, { _( "Field types" ), &field_types::finalize_all }, + { _( "Ammo effects" ), &ammo_effects::finalize_all }, { _( "Emissions" ), &emit::finalize }, { _( "Items" ), []() @@ -627,6 +631,7 @@ void DynamicDataLoader::check_consistency( loading_ui &ui ) }, { _( "Vitamins" ), &vitamin::check_consistency }, { _( "Field types" ), &field_types::check_consistency }, + { _( "Ammo effects" ), &ammo_effects::check_consistency }, { _( "Emissions" ), &emit::check_consistency }, { _( "Activities" ), &activity_type::check_consistency }, { diff --git a/src/projectile.cpp b/src/projectile.cpp index 922a66da29b00..1c9f330825381 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -3,6 +3,7 @@ #include #include +#include "ammo_effect.h" #include "explosion.h" #include "field.h" #include "game.h" @@ -91,148 +92,45 @@ void projectile::unset_custom_explosion() void apply_ammo_effects( const tripoint &p, const std::set &effects ) { - if( effects.count( "EXPLOSIVE_SMALL" ) > 0 ) { - // TODO: double-check if this is sensible. - explosion_handler::explosion( p, 360, 0.4 ); - } - - if( effects.count( "EXPLOSIVE" ) > 0 ) { - // TODO: double-check if this is sensible. - explosion_handler::explosion( p, 360 ); - } - - if( effects.count( "FRAG" ) > 0 ) { - // Same as a standard thrown frag grenade. - explosion_handler::explosion( p, 185, 0.8, false, 212, 0.05 ); - } - - if( effects.count( "NAPALM" ) > 0 ) { - explosion_handler::explosion( p, 60, 0.7, true ); - // More intense fire near the center - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_fire, 1 ); - } - } - - if( effects.count( "NAPALM_BIG" ) > 0 ) { - explosion_handler::explosion( p, 360, 0.8, true ); - // More intense fire near the center - for( auto &pt : g->m.points_in_radius( p, 3, 0 ) ) { - g->m.add_field( pt, fd_fire, 1 ); - } - } - - if( effects.count( "PYROPHORIC" ) > 0 ) { - explosion_handler::explosion( p, 360, 0.8, true ); - // Extreme heat near the center of the explosion - for( auto &pt : g->m.points_in_radius( p, 3, 0 ) ) { - g->m.add_field( pt, fd_fire, 2 ); - } - } - - if( effects.count( "MININUKE_MOD" ) > 0 ) { - explosion_handler::explosion( p, 72000000 ); - for( auto &pt : g->m.points_in_radius( p, 18, 0 ) ) { - if( g->m.sees( p, pt, 3 ) && - g->m.passable( pt ) ) { - g->m.add_field( pt, fd_nuke_gas, 3 ); + for( const ammo_effect &ae : ammo_effects::get_all() ) { + if( effects.count( ae.effect_tag ) > 0 ) { + for( auto &pt : g->m.points_in_radius( p, ae.aoe_radius, ae.aoe_radius_z ) ) { + if( one_in( ae.aoe_chance ) ) { + const bool check_sees = !ae.aoe_check_sees || + ( ae.aoe_check_sees && g->m.sees( p, pt, ae.aoe_check_sees_radius ) ); + const bool check_passable = !ae.aoe_check_passable || + ( ae.aoe_check_passable && g->m.passable( pt ) ); + if( check_sees && check_passable ) { + g->m.add_field( pt, ae.aoe_field_type, rng( ae.aoe_intensity_min, ae.aoe_intensity_max ) ); + } + } } } - } - - if( effects.count( "ACIDBOMB" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_acid, 3 ); - } - } - - if( effects.count( "EXPLOSIVE_BIG" ) > 0 ) { - // TODO: double-check if this is sensible. - explosion_handler::explosion( p, 600 ); - } - - if( effects.count( "EXPLOSIVE_HUGE" ) > 0 ) { - // TODO: double-check if this is sensible. - explosion_handler::explosion( p, 1200 ); - } - - if( effects.count( "TOXICGAS" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_toxic_gas, 3 ); - } - } - if( effects.count( "GAS_FUNGICIDAL" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_fungicidal_gas, 3 ); - } - } - if( effects.count( "GAS_INSECTICIDAL" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_insecticidal_gas, 3 ); + if( ae.aoe_explosion_data.power > 0 ) { + explosion_handler::explosion( p, ae.aoe_explosion_data ); } - } - if( effects.count( "SMOKE" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_smoke, 3 ); + if( ae.do_flashbang ) { + explosion_handler::flashbang( p ); } - } - if( effects.count( "SMOKE_BIG" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 6, 0 ) ) { - g->m.add_field( pt, fd_smoke, 3 ); + if( ae.do_emp_blast ) { + explosion_handler::emp_blast( p ); } } - if( effects.count( "FLASHBANG" ) ) { - explosion_handler::flashbang( p ); - } - - if( effects.count( "EMP" ) ) { - explosion_handler::emp_blast( p ); - } - if( effects.count( "NO_BOOM" ) == 0 && effects.count( "FLAME" ) > 0 ) { for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { g->m.add_field( pt, fd_fire, 1 ); } } - - if( effects.count( "FLARE" ) > 0 ) { - g->m.add_field( p, fd_fire, 1 ); - } - - if( effects.count( "LIGHTNING" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_electricity, 3 ); - } - } - - if( effects.count( "PLASMA" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - if( one_in( 2 ) ) { - g->m.add_field( pt, fd_plasma, rng( 2, 3 ) ); - } - } - } } -int aoe_size( const std::set &tags ) +int max_aoe_size( const std::set &tags ) { - if( tags.count( "NAPALM_BIG" ) || - tags.count( "EXPLOSIVE_HUGE" ) ) { - return 4; - } else if( tags.count( "NAPALM" ) || - tags.count( "EXPLOSIVE_BIG" ) ) { - return 3; - } else if( tags.count( "EXPLOSIVE" ) || - tags.count( "EXPLOSIVE_SMALL" ) ) { - return 2; - } else if( tags.count( "FRAG" ) ) { - return 15; - } else if( tags.count( "ACIDBOMB" ) || - tags.count( "FLAME" ) ) { - return 1; + int aoe_size = 0; + for( const ammo_effect &aed : ammo_effects::get_all() ) { + if( tags.count( aed.effect_tag ) > 0 ) { + aoe_size = std::max( aoe_size, aed.aoe_size ) ; + } } - - return 0; + return aoe_size; } - diff --git a/src/projectile.h b/src/projectile.h index a2b9dd0b0e295..6e287a1594bd9 100644 --- a/src/projectile.h +++ b/src/projectile.h @@ -58,6 +58,6 @@ struct dealt_projectile_attack { }; void apply_ammo_effects( const tripoint &p, const std::set &effects ); -int aoe_size( const std::set &tags ); +int max_aoe_size( const std::set &tags ); #endif diff --git a/src/string_id_null_ids.cpp b/src/string_id_null_ids.cpp index 9193f7c311cad..d6829813a2560 100644 --- a/src/string_id_null_ids.cpp +++ b/src/string_id_null_ids.cpp @@ -43,6 +43,7 @@ MAKE_NULL_ID2( oter_type_t, "", 0 ) MAKE_NULL_ID2( ter_t, "t_null", 0 ) MAKE_NULL_ID2( trap, "tr_null" ) MAKE_NULL_ID2( construction_category, "NULL", 0 ) +MAKE_NULL_ID2( ammo_effect, "AE_NULL", 0 ) MAKE_NULL_ID2( field_type, "fd_null", 0 ) MAKE_NULL_ID2( furn_t, "f_null", 0 ) MAKE_NULL_ID2( MonsterGroup, "GROUP_NULL" ) diff --git a/src/turret.cpp b/src/turret.cpp index 874e8b367eab1..4185536012327 100644 --- a/src/turret.cpp +++ b/src/turret.cpp @@ -531,7 +531,7 @@ int vehicle::automatic_fire_turret( vehicle_part &pt ) // Create the targeting computer's npc npc cpu = get_targeting_npc( pt ); - int area = aoe_size( gun.ammo_effects() ); + int area = max_aoe_size( gun.ammo_effects() ); if( area > 0 ) { // Pad a bit for less friendly fire area += area == 1 ? 1 : 2; diff --git a/src/type_id.h b/src/type_id.h index 80fe66168c136..d06c658506f0f 100644 --- a/src/type_id.h +++ b/src/type_id.h @@ -8,6 +8,10 @@ class ammunition_type; using ammotype = string_id; +struct ammo_effect; +using ammo_effect_id = int_id; +using ammo_effect_str_id = string_id; + struct bionic_data; using bionic_id = string_id; From 40d2ff976e6c94b8c8780ca16d9bf771df6b3fe1 Mon Sep 17 00:00:00 2001 From: ZhilkinSerg Date: Wed, 2 Oct 2019 21:39:30 +0300 Subject: [PATCH 02/11] 1 --- data/json/ammo_effects.json | 70 +++++++++++-------------------------- src/ammo_effect.cpp | 1 - src/ammo_effect.h | 2 -- src/projectile.cpp | 4 +-- 4 files changed, 23 insertions(+), 54 deletions(-) diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json index 5e0a630aa23e6..7cc9959140c6e 100644 --- a/data/json/ammo_effects.json +++ b/data/json/ammo_effects.json @@ -2,7 +2,6 @@ { "id": "AE_NULL", "type": "ammo_effect", - "effect_tag": "", "aoe": { "field_type": "fd_null", "intensity_min": 0, @@ -25,132 +24,107 @@ "do_emp_blast": false }, { - "id": "AE_NAPALM", + "id": "NAPALM", "type": "ammo_effect", - "effect_tag": "NAPALM", "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "size": 3 }, "explosion": { "power": 60, "distance_factor": 0.7, "fire": true } }, { - "id": "AE_NAPALM_BIG", + "id": "NAPALM_BIG", "type": "ammo_effect", - "effect_tag": "NAPALM_BIG", "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "radius": 3, "size": 4 }, "explosion": { "power": 360, "distance_factor": 0.8, "fire": true } }, { - "id": "AE_PYROPHORIC", + "id": "PYROPHORIC", "type": "ammo_effect", - "effect_tag": "PYROPHORIC", "aoe": { "field_type": "fd_fire", "intensity_min": 2, "intensity_max": 2, "radius": 3 }, "explosion": { "power": 360, "distance_factor": 0.8, "fire": true } }, { - "id": "AE_ACIDBOMB", + "id": "ACIDBOMB", "type": "ammo_effect", - "effect_tag": "ACIDBOMB", "aoe": { "field_type": "fd_acid", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_TOXICGAS", + "id": "TOXICGAS", "type": "ammo_effect", - "effect_tag": "TOXICGAS", "aoe": { "field_type": "fd_toxic_gas", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_GAS_FUNGICIDAL", + "id": "GAS_FUNGICIDAL", "type": "ammo_effect", - "effect_tag": "GAS_FUNGICIDAL", "aoe": { "field_type": "fd_fungicidal_gas", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_GAS_INSECTICIDAL", + "id": "GAS_INSECTICIDAL", "type": "ammo_effect", - "effect_tag": "GAS_INSECTICIDAL", "aoe": { "field_type": "fd_insecticidal_gas", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_SMOKE", + "id": "SMOKE", "type": "ammo_effect", - "effect_tag": "SMOKE", "aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_SMOKE_BIG", + "id": "SMOKE_BIG", "type": "ammo_effect", - "effect_tag": "SMOKE_BIG", "aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3, "radius": 6 } }, { - "id": "AE_FLARE", + "id": "FLARE", "type": "ammo_effect", - "effect_tag": "FLARE", "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1 } }, { - "id": "AE_LIGHTNING", + "id": "LIGHTNING", "type": "ammo_effect", - "effect_tag": "LIGHTNING", "aoe": { "field_type": "fd_electricity", "intensity_min": 3, "intensity_max": 3 } }, { - "id": "AE_PLASMA", + "id": "PLASMA", "type": "ammo_effect", - "effect_tag": "PLASMA", "aoe": { "field_type": "fd_plasma", "intensity_min": 2, "intensity_max": 3, "chance": 2 } }, { - "id": "AE_PLASMA", + "id": "EXPLOSIVE_HUGE", "type": "ammo_effect", - "effect_tag": "PLASMA", - "aoe": { "field_type": "fd_plasma", "intensity_min": 2, "intensity_max": 3, "chance": 2 } - }, - { - "id": "AE_EXPLOSIVE_HUGE", - "type": "ammo_effect", - "effect_tag": "EXPLOSIVE_HUGE", "aoe": { "size": 4 }, "explosion": { "power": 1200 } }, { - "id": "AE_EXPLOSIVE_BIG", + "id": "EXPLOSIVE_BIG", "type": "ammo_effect", - "effect_tag": "EXPLOSIVE_BIG", "aoe": { "size": 3 }, "explosion": { "power": 1200 } }, { - "id": "AE_EXPLOSIVE_HUGE", + "id": "EXPLOSIVE_HUGE", "type": "ammo_effect", - "effect_tag": "EXPLOSIVE_HUGE", "aoe": { "size": 3 }, "explosion": { "power": 600 } }, { - "id": "AE_EXPLOSIVE", + "id": "EXPLOSIVE", "type": "ammo_effect", - "effect_tag": "EXPLOSIVE", "aoe": { "size": 2 }, "explosion": { "power": 360 } }, { - "id": "AE_EXPLOSIVE_SMALL", + "id": "EXPLOSIVE_SMALL", "type": "ammo_effect", - "effect_tag": "EXPLOSIVE_SMALL", "aoe": { "size": 2 }, "explosion": { "power": 360, "distance_factor": 0.4 } }, { - "id": "AE_FRAG", + "id": "FRAG", "type": "ammo_effect", - "effect_tag": "FRAG", "aoe": { "size": 15 }, "explosion": { "power": 185, "shrapnel": { "casing_mass": 212, "fragment_mass": 0.05 } } }, { - "id": "AE_MININUKE_MOD", + "id": "MININUKE_MOD", "type": "ammo_effect", - "effect_tag": "MININUKE_MOD", "aoe": { "field_type": "fd_nuke_gas", "intensity_min": 3, @@ -164,15 +138,13 @@ "explosion": { "power": 72000000 } }, { - "id": "AE_FLASHBANG", + "id": "FLASHBANG", "type": "ammo_effect", - "effect_tag": "FLASHBANG", "do_flashbang": true }, { - "id": "AE_EMP", + "id": "EMP", "type": "ammo_effect", - "effect_tag": "EMP", "do_emp_blast": true } ] diff --git a/src/ammo_effect.cpp b/src/ammo_effect.cpp index ebd4bf41ca0fd..cb8f6469e3bb0 100644 --- a/src/ammo_effect.cpp +++ b/src/ammo_effect.cpp @@ -60,7 +60,6 @@ int_id::int_id( const string_id &id ) : _id( id.id() ) void ammo_effect::load( JsonObject &jo, const std::string & ) { - mandatory( jo, was_loaded, "effect_tag", effect_tag ); if( jo.has_member( "aoe" ) ) { JsonObject joa = jo.get_object( "aoe" ); optional( joa, was_loaded, "field_type", aoe_field_type_name, "fd_null" ); diff --git a/src/ammo_effect.h b/src/ammo_effect.h index 83b549f036a5c..7e3947d04d66a 100644 --- a/src/ammo_effect.h +++ b/src/ammo_effect.h @@ -18,8 +18,6 @@ struct ammo_effect { void check() const; public: - std::string effect_tag; - field_type_id aoe_field_type = fd_null; /** used during JSON loading only */ std::string aoe_field_type_name = "fd_null"; diff --git a/src/projectile.cpp b/src/projectile.cpp index 1c9f330825381..bc4a4348bf292 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -93,7 +93,7 @@ void projectile::unset_custom_explosion() void apply_ammo_effects( const tripoint &p, const std::set &effects ) { for( const ammo_effect &ae : ammo_effects::get_all() ) { - if( effects.count( ae.effect_tag ) > 0 ) { + if( effects.count( ae.id.str() ) > 0 ) { for( auto &pt : g->m.points_in_radius( p, ae.aoe_radius, ae.aoe_radius_z ) ) { if( one_in( ae.aoe_chance ) ) { const bool check_sees = !ae.aoe_check_sees || @@ -128,7 +128,7 @@ int max_aoe_size( const std::set &tags ) { int aoe_size = 0; for( const ammo_effect &aed : ammo_effects::get_all() ) { - if( tags.count( aed.effect_tag ) > 0 ) { + if( tags.count( aed.id.str() ) > 0 ) { aoe_size = std::max( aoe_size, aed.aoe_size ) ; } } From 5b4fdf306922f8e33003c3c308374deca2ea8b46 Mon Sep 17 00:00:00 2001 From: ymber Date: Sat, 11 Jan 2020 08:40:09 +0000 Subject: [PATCH 03/11] Fix const JsonObject & --- src/ammo_effect.cpp | 4 ++-- src/ammo_effect.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ammo_effect.cpp b/src/ammo_effect.cpp index cb8f6469e3bb0..385010a79f841 100644 --- a/src/ammo_effect.cpp +++ b/src/ammo_effect.cpp @@ -58,7 +58,7 @@ int_id::int_id( const string_id &id ) : _id( id.id() ) { } -void ammo_effect::load( JsonObject &jo, const std::string & ) +void ammo_effect::load( const JsonObject &jo, const std::string & ) { if( jo.has_member( "aoe" ) ) { JsonObject joa = jo.get_object( "aoe" ); @@ -98,7 +98,7 @@ size_t ammo_effect::count() return all_ammo_effects.size(); } -void ammo_effects::load( JsonObject &jo, const std::string &src ) +void ammo_effects::load( const JsonObject &jo, const std::string &src ) { all_ammo_effects.load( jo, src ); } diff --git a/src/ammo_effect.h b/src/ammo_effect.h index 7e3947d04d66a..50b13d53a096a 100644 --- a/src/ammo_effect.h +++ b/src/ammo_effect.h @@ -13,7 +13,7 @@ class JsonObject; struct ammo_effect { public: - void load( JsonObject &jo, const std::string &src ); + void load( const JsonObject &jo, const std::string &src ); void finalize(); void check() const; @@ -47,7 +47,7 @@ struct ammo_effect { namespace ammo_effects { -void load( JsonObject &jo, const std::string &src ); +void load( const JsonObject &jo, const std::string &src ); void finalize_all(); void check_consistency(); void reset(); From 9c6bbc2c71e14b481ee69bc51838767020a11e67 Mon Sep 17 00:00:00 2001 From: ymber Date: Sat, 11 Jan 2020 08:40:59 +0000 Subject: [PATCH 04/11] Don't fire all effects for every projectile --- src/projectile.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/projectile.cpp b/src/projectile.cpp index bc4a4348bf292..ef4ee9e4d55cb 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -105,15 +105,15 @@ void apply_ammo_effects( const tripoint &p, const std::set &effects } } } - } - if( ae.aoe_explosion_data.power > 0 ) { - explosion_handler::explosion( p, ae.aoe_explosion_data ); - } - if( ae.do_flashbang ) { - explosion_handler::flashbang( p ); - } - if( ae.do_emp_blast ) { - explosion_handler::emp_blast( p ); + if( ae.aoe_explosion_data.power > 0 ) { + explosion_handler::explosion( p, ae.aoe_explosion_data ); + } + if( ae.do_flashbang ) { + explosion_handler::flashbang( p ); + } + if( ae.do_emp_blast ) { + explosion_handler::emp_blast( p ); + } } } From 5ab02dd3fb719d0b1e453125592086b94316e513 Mon Sep 17 00:00:00 2001 From: ymber Date: Sat, 11 Jan 2020 08:50:45 +0000 Subject: [PATCH 05/11] Remove hardcoded behaviors for FLAME and NO_BOOM --- data/json/ammo_effects.json | 5 +++++ data/json/items/classes/gun.json | 2 +- doc/JSON_FLAGS.md | 1 - src/creature.cpp | 8 +------- src/map.cpp | 2 +- src/projectile.cpp | 6 ------ 6 files changed, 8 insertions(+), 16 deletions(-) diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json index 7cc9959140c6e..ecd34df7d3bec 100644 --- a/data/json/ammo_effects.json +++ b/data/json/ammo_effects.json @@ -23,6 +23,11 @@ "do_flashbang": false, "do_emp_blast": false }, + { + "id": "FLAME", + "type": "ammo_effect", + "aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "size": 3 } + }, { "id": "NAPALM", "type": "ammo_effect", diff --git a/data/json/items/classes/gun.json b/data/json/items/classes/gun.json index 64c8503cf63a2..35cf6d2f8c59e 100644 --- a/data/json/items/classes/gun.json +++ b/data/json/items/classes/gun.json @@ -16,7 +16,7 @@ "name": "base flamethrower", "skill": "launcher", "ammo": "flammable", - "ammo_effects": [ "NO_BOOM", "FLARE" ], + "ammo_effects": [ "FLARE" ], "reload": 4, "flags": [ "FIRE_100", "NEVER_JAMS", "FIRESTARTER" ], "faults": [ ] diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index a86e1ba5f0257..0b39b68abb37d 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -705,7 +705,6 @@ List of known flags, used in both `terrain.json` and `furniture.json`. - ```MECH_WEAPON``` A built-in mech weapon, cannot be removed or have mods added / removed. - ```MOUNTED_GUN``` Gun can only be used on terrain / furniture with the "MOUNTABLE" flag. - ```NEVER_JAMS``` Never malfunctions. -- ```NO_BOOM``` Cancels the ammo effect "FLAME". - ```NO_UNLOAD``` Cannot be unloaded. - ```PRIMITIVE_RANGED_WEAPON``` Allows using non-gunsmith tools to repair it (but not reinforce). - ```PUMP_ACTION``` Gun has a rails on its pump action, allowing to install only mods with PUMP_RAIL_COMPATIBLE flag on underbarrel slot. diff --git a/src/creature.cpp b/src/creature.cpp index c3f49a6c13aad..8b1bdea6bc4dd 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -697,13 +697,7 @@ void Creature::deal_projectile_attack( Creature *source, dealt_projectile_attack add_effect( effect_stunned, rng( 3_turns, 8_turns ) ); } } - if( proj.proj_effects.count( "FLAME" ) ) { - if( made_of( material_id( "veggy" ) ) || made_of_any( cmat_flammable ) ) { - add_effect( effect_onfire, rng( 8_turns, 20_turns ), bp_hit ); - } else if( made_of_any( cmat_flesh ) ) { - add_effect( effect_onfire, rng( 5_turns, 10_turns ), bp_hit ); - } - } else if( proj.proj_effects.count( "INCENDIARY" ) ) { + if( proj.proj_effects.count( "INCENDIARY" ) ) { if( made_of( material_id( "veggy" ) ) || made_of_any( cmat_flammable ) ) { add_effect( effect_onfire, rng( 2_turns, 6_turns ), bp_hit ); } else if( made_of_any( cmat_flesh ) && one_in( 4 ) ) { diff --git a/src/map.cpp b/src/map.cpp index f497e4eef5657..b7efa1e22139b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3359,7 +3359,7 @@ void map::shoot( const tripoint &p, projectile &proj, const bool hit_items ) g->timed_events.add( TIMED_EVENT_WANTED, calendar::turn + 30_minutes, 0, abs ); } - const bool inc = ( ammo_effects.count( "INCENDIARY" ) || ammo_effects.count( "FLAME" ) ); + const bool inc = ammo_effects.count( "INCENDIARY" ); if( const optional_vpart_position vp = veh_at( p ) ) { dam = vp->vehicle().damage( vp->part_index(), dam, inc ? DT_HEAT : DT_STAB, hit_items ); } diff --git a/src/projectile.cpp b/src/projectile.cpp index ef4ee9e4d55cb..31ba7d937b631 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -116,12 +116,6 @@ void apply_ammo_effects( const tripoint &p, const std::set &effects } } } - - if( effects.count( "NO_BOOM" ) == 0 && effects.count( "FLAME" ) > 0 ) { - for( auto &pt : g->m.points_in_radius( p, 1, 0 ) ) { - g->m.add_field( pt, fd_fire, 1 ); - } - } } int max_aoe_size( const std::set &tags ) From 20962222f23be46fa85793e2deaee287c3e82b03 Mon Sep 17 00:00:00 2001 From: ymber Date: Sat, 11 Jan 2020 09:55:58 +0000 Subject: [PATCH 06/11] Fix EXPLOSIVE_BIG definition --- data/json/ammo_effects.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json index ecd34df7d3bec..0310c034929fc 100644 --- a/data/json/ammo_effects.json +++ b/data/json/ammo_effects.json @@ -101,12 +101,6 @@ "id": "EXPLOSIVE_BIG", "type": "ammo_effect", "aoe": { "size": 3 }, - "explosion": { "power": 1200 } - }, - { - "id": "EXPLOSIVE_HUGE", - "type": "ammo_effect", - "aoe": { "size": 3 }, "explosion": { "power": 600 } }, { From f0504574464cdeba91f49effd301f9f24ed2d4f6 Mon Sep 17 00:00:00 2001 From: ymber Date: Sun, 12 Jan 2020 11:46:54 +0000 Subject: [PATCH 07/11] Restore Mk211 explosion --- data/json/ammo_effects.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json index 0310c034929fc..23e2836fc0553 100644 --- a/data/json/ammo_effects.json +++ b/data/json/ammo_effects.json @@ -115,6 +115,16 @@ "aoe": { "size": 2 }, "explosion": { "power": 360, "distance_factor": 0.4 } }, + { + "id": "EXPLOSIVE_RAUFOSS", + "type": "ammo_effect", + "explosion": { + "power": 2.4, + "distance_factor": 0.6, + "fire": true, + "shrapnel": { "casing_mass": 28, "fragment_mass": 1.4, "recovery": 0, "drop": "null" } + } + }, { "id": "FRAG", "type": "ammo_effect", From d1807764d2c19f3cc6e63e64e5a6057aef849bfa Mon Sep 17 00:00:00 2001 From: ymber Date: Sun, 12 Jan 2020 11:50:16 +0000 Subject: [PATCH 08/11] Remove unused aoe objects --- data/json/ammo_effects.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/data/json/ammo_effects.json b/data/json/ammo_effects.json index 23e2836fc0553..6bc29a7ee0b92 100644 --- a/data/json/ammo_effects.json +++ b/data/json/ammo_effects.json @@ -94,25 +94,21 @@ { "id": "EXPLOSIVE_HUGE", "type": "ammo_effect", - "aoe": { "size": 4 }, "explosion": { "power": 1200 } }, { "id": "EXPLOSIVE_BIG", "type": "ammo_effect", - "aoe": { "size": 3 }, "explosion": { "power": 600 } }, { "id": "EXPLOSIVE", "type": "ammo_effect", - "aoe": { "size": 2 }, "explosion": { "power": 360 } }, { "id": "EXPLOSIVE_SMALL", "type": "ammo_effect", - "aoe": { "size": 2 }, "explosion": { "power": 360, "distance_factor": 0.4 } }, { @@ -128,7 +124,6 @@ { "id": "FRAG", "type": "ammo_effect", - "aoe": { "size": 15 }, "explosion": { "power": 185, "shrapnel": { "casing_mass": 212, "fragment_mass": 0.05 } } }, { From 0fdaa979dc3b4ebbb82a67b8911efc667bd984f1 Mon Sep 17 00:00:00 2001 From: ymber Date: Sun, 12 Jan 2020 11:52:46 +0000 Subject: [PATCH 09/11] Simplify AoE checks --- src/projectile.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/projectile.cpp b/src/projectile.cpp index 31ba7d937b631..ba229a8862206 100644 --- a/src/projectile.cpp +++ b/src/projectile.cpp @@ -96,10 +96,8 @@ void apply_ammo_effects( const tripoint &p, const std::set &effects if( effects.count( ae.id.str() ) > 0 ) { for( auto &pt : g->m.points_in_radius( p, ae.aoe_radius, ae.aoe_radius_z ) ) { if( one_in( ae.aoe_chance ) ) { - const bool check_sees = !ae.aoe_check_sees || - ( ae.aoe_check_sees && g->m.sees( p, pt, ae.aoe_check_sees_radius ) ); - const bool check_passable = !ae.aoe_check_passable || - ( ae.aoe_check_passable && g->m.passable( pt ) ); + const bool check_sees = !ae.aoe_check_sees || g->m.sees( p, pt, ae.aoe_check_sees_radius ); + const bool check_passable = !ae.aoe_check_passable || g->m.passable( pt ); if( check_sees && check_passable ) { g->m.add_field( pt, ae.aoe_field_type, rng( ae.aoe_intensity_min, ae.aoe_intensity_max ) ); } From 96ec090a18467c70e29ce0e5eda26e2d4793400d Mon Sep 17 00:00:00 2001 From: ymber Date: Sun, 12 Jan 2020 12:39:53 +0000 Subject: [PATCH 10/11] Add ammo effect checks --- src/ammo_effect.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/ammo_effect.cpp b/src/ammo_effect.cpp index 385010a79f841..52810fd73b04e 100644 --- a/src/ammo_effect.cpp +++ b/src/ammo_effect.cpp @@ -91,6 +91,27 @@ void ammo_effect::finalize() void ammo_effect::check() const { + if( !aoe_field_type.is_valid() ) { + debugmsg( "No such field type %s", aoe_field_type_name ); + } + if( aoe_check_sees_radius < 0 ) { + debugmsg( "Value of aoe_check_sees_radius cannot be negative" ); + } + if( aoe_size < 0 ) { + debugmsg( "Value of aoe_size cannot be negative" ); + } + if( aoe_chance < 0 || aoe_chance > 1 ) { + debugmsg( "Field chance must be between 0 and 1" ); + } + if( aoe_radius_z < 0 || aoe_radius < 0 ) { + debugmsg( "Radius values cannot be negative" ); + } + if( aoe_intensity_min < 0 ) { + debugmsg( "Field intensity cannot be negative" ); + } + if( aoe_intensity_max < aoe_intensity_min ) { + debugmsg( "Maximum intensity must be greater than or equal to minimum intensity" ); + } } size_t ammo_effect::count() From 1b595deaa7b3b6e5765c184225fa2ad715a7eef4 Mon Sep 17 00:00:00 2001 From: ymber Date: Mon, 13 Jan 2020 15:42:51 +0000 Subject: [PATCH 11/11] Fix ammo_effect::check --- src/ammo_effect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ammo_effect.cpp b/src/ammo_effect.cpp index 52810fd73b04e..edc8a5a74d244 100644 --- a/src/ammo_effect.cpp +++ b/src/ammo_effect.cpp @@ -100,8 +100,8 @@ void ammo_effect::check() const if( aoe_size < 0 ) { debugmsg( "Value of aoe_size cannot be negative" ); } - if( aoe_chance < 0 || aoe_chance > 1 ) { - debugmsg( "Field chance must be between 0 and 1" ); + if( aoe_chance < 0 ) { + debugmsg( "Field chance divisor cannot be negative" ); } if( aoe_radius_z < 0 || aoe_radius < 0 ) { debugmsg( "Radius values cannot be negative" );