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

Move ammo effects to JSON #36919

Merged
merged 12 commits into from
Jan 17, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
149 changes: 149 additions & 0 deletions data/json/ammo_effects.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
[
{
"id": "AE_NULL",
"type": "ammo_effect",
"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": "FLAME",
"type": "ammo_effect",
"aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "size": 3 }
},
{
"id": "NAPALM",
"type": "ammo_effect",
"aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1, "size": 3 },
"explosion": { "power": 60, "distance_factor": 0.7, "fire": true }
},
{
"id": "NAPALM_BIG",
"type": "ammo_effect",
"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": "PYROPHORIC",
"type": "ammo_effect",
"aoe": { "field_type": "fd_fire", "intensity_min": 2, "intensity_max": 2, "radius": 3 },
"explosion": { "power": 360, "distance_factor": 0.8, "fire": true }
},
{
"id": "ACIDBOMB",
"type": "ammo_effect",
"aoe": { "field_type": "fd_acid", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "TOXICGAS",
"type": "ammo_effect",
"aoe": { "field_type": "fd_toxic_gas", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "GAS_FUNGICIDAL",
"type": "ammo_effect",
"aoe": { "field_type": "fd_fungicidal_gas", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "GAS_INSECTICIDAL",
"type": "ammo_effect",
"aoe": { "field_type": "fd_insecticidal_gas", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "SMOKE",
"type": "ammo_effect",
"aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "SMOKE_BIG",
"type": "ammo_effect",
"aoe": { "field_type": "fd_smoke", "intensity_min": 3, "intensity_max": 3, "radius": 6 }
},
{
"id": "FLARE",
"type": "ammo_effect",
"aoe": { "field_type": "fd_fire", "intensity_min": 1, "intensity_max": 1 }
},
{
"id": "LIGHTNING",
"type": "ammo_effect",
"aoe": { "field_type": "fd_electricity", "intensity_min": 3, "intensity_max": 3 }
},
{
"id": "PLASMA",
"type": "ammo_effect",
"aoe": { "field_type": "fd_plasma", "intensity_min": 2, "intensity_max": 3, "chance": 2 }
},
{
"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 }
},
{
"id": "FRAG",
"type": "ammo_effect",
"aoe": { "size": 15 },
"explosion": { "power": 185, "shrapnel": { "casing_mass": 212, "fragment_mass": 0.05 } }
},
{
"id": "MININUKE_MOD",
"type": "ammo_effect",
"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": "FLASHBANG",
"type": "ammo_effect",
"do_flashbang": true
},
{
"id": "EMP",
"type": "ammo_effect",
"do_emp_blast": true
}
]
2 changes: 1 addition & 1 deletion data/json/items/classes/gun.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [ ]
Expand Down
1 change: 0 additions & 1 deletion doc/JSON_FLAGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
129 changes: 129 additions & 0 deletions src/ammo_effect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#include "ammo_effect.h"

#include "generic_factory.h"
#include "json.h"

namespace
{

generic_factory<ammo_effect> all_ammo_effects( "ammo effects" );

} // namespace

/** @relates int_id */
template<>
bool int_id<ammo_effect>::is_valid() const
{
return all_ammo_effects.is_valid( *this );
}

/** @relates int_id */
template<>
const ammo_effect &int_id<ammo_effect>::obj() const
{
return all_ammo_effects.obj( *this );
}

/** @relates int_id */
template<>
const string_id<ammo_effect> &int_id<ammo_effect>::id() const
{
return all_ammo_effects.convert( *this );
}

/** @relates string_id */
template<>
bool string_id<ammo_effect>::is_valid() const
{
return all_ammo_effects.is_valid( *this );
}

/** @relates string_id */
template<>
const ammo_effect &string_id<ammo_effect>::obj() const
{
return all_ammo_effects.obj( *this );
}

/** @relates string_id */
template<>
int_id<ammo_effect> string_id<ammo_effect>::id() const
{
return all_ammo_effects.convert( *this, AE_NULL );
}

/** @relates int_id */
template<>
int_id<ammo_effect>::int_id( const string_id<ammo_effect> &id ) : _id( id.id() )
{
}

void ammo_effect::load( const JsonObject &jo, const std::string & )
{
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<ammo_effect &>( ae ).aoe_field_type = field_type_id( ae.aoe_field_type_name );
}

}

void ammo_effect::check() const
{
ymber marked this conversation as resolved.
Show resolved Hide resolved
}

size_t ammo_effect::count()
{
return all_ammo_effects.size();
}

void ammo_effects::load( const 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<ammo_effect &>( ae ).finalize();
}
}

void ammo_effects::check_consistency()
{
all_ammo_effects.check();
}

void ammo_effects::reset()
{
all_ammo_effects.reset();
}

const std::vector<ammo_effect> &ammo_effects::get_all()
{
return all_ammo_effects.get_all();
}

ammo_effect_id AE_NULL;
61 changes: 61 additions & 0 deletions src/ammo_effect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once
#ifndef AMMO_EFFECT_H
#define AMMO_EFFECT_H

#include <vector>
#include <string>

#include "explosion.h"
#include "field_type.h"
#include "type_id.h"

class JsonObject;

struct ammo_effect {
public:
void load( const JsonObject &jo, const std::string &src );
void finalize();
void check() const;

public:
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<ammo_effect> id;
bool was_loaded = false;

public:
static size_t count();
};

namespace ammo_effects
{

void load( const JsonObject &jo, const std::string &src );
void finalize_all();
void check_consistency();
void reset();

const std::vector<ammo_effect> &get_all();

} // namespace ammo_effects

extern ammo_effect_id AE_NULL;

#endif
8 changes: 1 addition & 7 deletions src/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) ) {
Expand Down
Loading