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

Refactor fields (step 7) #32488

Merged
merged 14 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from 13 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
220 changes: 178 additions & 42 deletions data/json/field_type.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/activity_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1755,7 +1755,7 @@ void activity_handlers::pulp_do_turn( player_activity *act, player *p )
const mtype *corpse_mtype = corpse.get_mtype();
if( !corpse.is_corpse() || !corpse_mtype->has_flag( MF_REVIVES ) ||
( std::find( act->str_values.begin(), act->str_values.end(), "auto_pulp_no_acid" ) !=
act->str_values.end() && corpse_mtype->bloodType() == fd_acid ) ) {
act->str_values.end() && corpse_mtype->bloodType().obj().has_acid ) ) {
// Don't smash non-rezing corpses //don't smash acid zombies when auto pulping
continue;
}
Expand Down
3 changes: 1 addition & 2 deletions src/advanced_inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,8 +761,7 @@ void advanced_inv_area::init()
const field &tmpfld = g->m.field_at( pos );
for( auto &fld : tmpfld ) {
const field_entry &cur = fld.second;
field_type_id curType = cur.get_field_type();
if( curType == fd_fire ) {
if( fld.first.obj().has_fire ) {
flags.append( _( " <color_white_red>FIRE</color>" ) );
} else {
if( cur.is_dangerous() ) {
Expand Down
76 changes: 31 additions & 45 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2654,31 +2654,19 @@ nc_color Character::symbol_color() const

const auto &fields = g->m.field_at( pos() );

// Priority: electricity, fire, acid, gases
bool has_elec = false;
bool has_fire = false;
bool has_acid = false;
bool has_elec = false;
bool has_fume = false;
for( const auto &field : fields ) {
if( field.first == fd_incendiary || field.first == fd_fire ) {
has_fire = true;
}
if( field.first == fd_electricity ) {
has_elec = true;
}
if( field.first == fd_acid ) {
has_acid = true;
}
if( field.first == fd_relax_gas || field.first == fd_fungal_haze ||
field.first == fd_fungicidal_gas || field.first == fd_toxic_gas ||
field.first == fd_tear_gas || field.first == fd_nuke_gas ||
field.first == fd_smoke ) {
has_fume = true;
has_elec = field.first.obj().has_elec;
if( has_elec ) {
return hilite( basic );
}
}
// Priority: electricity, fire, acid, gases
// Can't just return in the switch, because field order is alphabetic
if( has_elec ) {
return hilite( basic );
has_fire = field.first.obj().has_fire;
has_acid = field.first.obj().has_acid;
has_fume = field.first.obj().has_fume;
}
if( has_fire ) {
return red_background( basic );
Expand All @@ -2701,39 +2689,37 @@ bool Character::is_immune_field( const field_type_id fid ) const
if( has_trait( debug_nodmg ) ) {
return true;
}

// Check to see if we are immune
if( fid == fd_smoke ) {
return get_env_resist( bp_mouth ) >= 12;
const field_type ft = fid.obj();
for( const trait_id &t : ft.immunity_data_traits ) {
if( has_trait( t ) ) {
return true;
}
}
if( fid == fd_tear_gas || fid == fd_toxic_gas || fid == fd_gas_vent || fid == fd_relax_gas ) {
return get_env_resist( bp_mouth ) >= 15;
bool immune_by_body_part_resistance = false;
for( const std::pair<body_part, int> &fide : ft.immunity_data_body_part_env_resistance ) {
immune_by_body_part_resistance = immune_by_body_part_resistance &&
get_env_resist( fide.first ) >= fide.second;
}
if( fid == fd_fungal_haze ) {
return has_trait( trait_id( "M_IMMUNE" ) ) || ( get_env_resist( bp_mouth ) >= 15 &&
get_env_resist( bp_eyes ) >= 15 );
if( immune_by_body_part_resistance ) {
return true;
}
if( fid == fd_electricity ) {
if( ft.has_elec ) {
return is_elec_immune();
}
if( fid == fd_acid ) {
return has_trait( trait_id( "ACIDPROOF" ) ) ||
( !is_on_ground() && get_env_resist( bp_foot_l ) >= 15 &&
get_env_resist( bp_foot_r ) >= 15 &&
get_env_resist( bp_leg_l ) >= 15 &&
get_env_resist( bp_leg_r ) >= 15 &&
get_armor_type( DT_ACID, bp_foot_l ) >= 5 &&
get_armor_type( DT_ACID, bp_foot_r ) >= 5 &&
get_armor_type( DT_ACID, bp_leg_l ) >= 5 &&
get_armor_type( DT_ACID, bp_leg_r ) >= 5 );
}
if( fid == fd_web ) {
return has_trait( trait_id( "WEB_WALKER" ) );
}
if( fid == fd_fire || fid == fd_flame_burst ) {
if( ft.has_fire ) {
return has_active_bionic( bionic_id( "bio_heatsink" ) ) || is_wearing( "rm13_armor_on" );
}

if( ft.has_acid ) {
return !is_on_ground() && get_env_resist( bp_foot_l ) >= 15 &&
get_env_resist( bp_foot_r ) >= 15 &&
get_env_resist( bp_leg_l ) >= 15 &&
get_env_resist( bp_leg_r ) >= 15 &&
get_armor_type( DT_ACID, bp_foot_l ) >= 5 &&
get_armor_type( DT_ACID, bp_foot_r ) >= 5 &&
get_armor_type( DT_ACID, bp_leg_l ) >= 5 &&
get_armor_type( DT_ACID, bp_leg_r ) >= 5;
}
// If we haven't found immunity yet fall up to the next level
return Creature::is_immune_field( fid );
}
Expand Down
2 changes: 1 addition & 1 deletion src/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ bool string_id<emit>::is_valid() const
if( found == emits_all.end() ) {
return false;
}
return found->second.field() != fd_null;
return !found->second.field().id().is_null();
}

/** @relates string_id */
Expand Down
20 changes: 20 additions & 0 deletions src/field.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ int field_entry::move_cost() const
return type.obj().get_move_cost( intensity - 1 );
}

float field_entry::light_emitted() const
{
return type.obj().get_light_emitted( intensity - 1 );
}

float field_entry::translucency() const
{
return type.obj().get_translucency( intensity - 1 );
}

bool field_entry::is_transparent() const
{
return type.obj().get_transparent( intensity - 1 );
}

int field_entry::convection_temperature_mod() const
{
return type.obj().get_convection_temperature_mod( intensity - 1 );
}

nc_color field_entry::color() const
{
return type.obj().get_color( intensity - 1 );
Expand Down
9 changes: 9 additions & 0 deletions src/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ class field_entry
//returns the move cost of this field
int move_cost() const;

float light_emitted() const;
float translucency() const;
bool is_transparent() const;
int convection_temperature_mod() const;

//Returns the field_type_id of the current field entry.
field_type_id get_field_type() const;

Expand Down Expand Up @@ -73,6 +78,10 @@ class field_entry
return type.obj().underwater_age_speedup;
}

int get_gas_absorption_factor() const {
return type.obj().gas_absorption_factor;
}

bool decays_on_actualize() const {
return type.obj().accelerated_decay;
}
Expand Down
26 changes: 26 additions & 0 deletions src/field_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,35 @@ void field_type::load( JsonObject &jo, const std::string & )
fallback_intensity_level.dangerous );
optional( jao, was_loaded, "move_cost", intensity_level.move_cost,
fallback_intensity_level.move_cost );
optional( jao, was_loaded, "light_emitted", intensity_level.light_emitted,
fallback_intensity_level.light_emitted );
optional( jao, was_loaded, "translucency", intensity_level.translucency,
fallback_intensity_level.translucency );
optional( jao, was_loaded, "convection_temperature_mod", intensity_level.convection_temperature_mod,
fallback_intensity_level.convection_temperature_mod );
intensity_levels.emplace_back( intensity_level );
}
JsonObject jid = jo.get_object( "immunity_data" );
JsonArray jidt = jid.get_array( "traits" );
while( jidt.has_more() ) {
immunity_data_traits.emplace_back( trait_id( jidt.next_string() ) );
}
JsonArray jidr = jid.get_array( "body_part_env_resistance" );
while( jidr.has_more() ) {
JsonArray jao = jidr.next_array();
immunity_data_body_part_env_resistance.emplace_back( std::make_pair( get_body_part_token(
jao.get_string( 0 ) ), jao.get_int( 1 ) ) );
}
optional( jo, was_loaded, "underwater_age_speedup", underwater_age_speedup, 0_turns );
optional( jo, was_loaded, "decay_amount_factor", decay_amount_factor, 0 );
optional( jo, was_loaded, "apply_slime_factor", apply_slime_factor, 0 );
optional( jo, was_loaded, "gas_absorption_factor", gas_absorption_factor, 0 );
optional( jo, was_loaded, "is_splattering", is_splattering, false );
optional( jo, was_loaded, "dirty_transparency_cache", dirty_transparency_cache, false );
optional( jo, was_loaded, "has_fire", has_fire, false );
optional( jo, was_loaded, "has_acid", has_acid, false );
optional( jo, was_loaded, "has_elec", has_elec, false );
optional( jo, was_loaded, "has_fume", has_fume, false );
optional( jo, was_loaded, "priority", priority, 0 );
optional( jo, was_loaded, "half_life", half_life, 0_turns );
if( jo.has_member( "phase" ) ) {
Expand Down
26 changes: 26 additions & 0 deletions src/field_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <memory>
#include <string>

#include "bodypart.h"
#include "calendar.h"
#include "catacharset.h"
#include "color.h"
Expand All @@ -19,6 +20,7 @@
class JsonObject;

enum phase_id : int;
enum body_part : int;

struct field_intensity_level {
std::string name;
Expand All @@ -27,6 +29,9 @@ struct field_intensity_level {
bool dangerous = false;
bool transparent = true;
int move_cost = 0;
float light_emitted = 0.0f;
float translucency = 0.0f;
int convection_temperature_mod = 0.0f;
};

struct field_type {
Expand All @@ -45,6 +50,18 @@ struct field_type {
std::vector<field_intensity_level> intensity_levels;

time_duration underwater_age_speedup = 0_turns;
int decay_amount_factor = 0;
int apply_slime_factor = 0;
int gas_absorption_factor = 0;
bool is_splattering = false;
bool dirty_transparency_cache = false;
bool has_fire = false;
bool has_acid = false;
bool has_elec = false;
bool has_fume = false;

std::vector<trait_id> immunity_data_traits;
std::vector<std::pair<body_part, int>> immunity_data_body_part_env_resistance;

int priority = 0;
time_duration half_life = 0_turns;
Expand Down Expand Up @@ -75,6 +92,15 @@ struct field_type {
int get_move_cost( int level = 0 ) const {
return intensity_levels[level].move_cost;
}
float get_light_emitted( int level = 0 ) const {
return intensity_levels[level].light_emitted;
}
float get_translucency( int level = 0 ) const {
return intensity_levels[level].translucency;
}
int get_convection_temperature_mod( int level = 0 ) const {
return intensity_levels[level].convection_temperature_mod;
}

bool is_dangerous() const {
return std::any_of( intensity_levels.begin(), intensity_levels.end(),
Expand Down
45 changes: 16 additions & 29 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1734,8 +1734,9 @@ static int maptile_field_intensity( maptile &mt, field_type_id fld )
{
auto field_ptr = mt.find_field( fld );

return ( field_ptr == nullptr ? 0 : field_ptr->get_field_intensity() );
return field_ptr == nullptr ? 0 : field_ptr->get_field_intensity();
}

static bool maptile_trap_eq( maptile &mt, const trap_id &id )
{
return mt.get_trap() == id;
Expand Down Expand Up @@ -1786,33 +1787,19 @@ int get_heat_radiation( const tripoint &location, bool direct )

int get_convection_temperature( const tripoint &location )
{
// Heat from hot air (fields)
int temp_mod = 0;
// Directly on lava tiles
maptile mt = g->m.maptile_at( location );
// directly on fire/lava tiles
int tile_intensity = maptile_field_intensity( mt, fd_fire );
if( tile_intensity > 0 || maptile_trap_eq( mt, tr_lava ) ) {
temp_mod += 300;
}
// hot air of a fire/lava
auto tile_intensity_mod = []( maptile & mt, field_type_id fld, int case_1, int case_2,
int case_3 ) {
int field_intensity = maptile_field_intensity( mt, fld );
int cases[3] = { case_1, case_2, case_3 };
return ( field_intensity > 0 && field_intensity < 4 ) ? cases[ field_intensity - 1 ] : 0;
};

// TODO: Jsonize
temp_mod += tile_intensity_mod( mt, fd_hot_air1, 2, 6, 10 );
temp_mod += tile_intensity_mod( mt, fd_hot_air2, 6, 16, 20 );
temp_mod += tile_intensity_mod( mt, fd_hot_air3, 16, 40, 70 );
temp_mod += tile_intensity_mod( mt, fd_hot_air4, 70, 100, 160 );
temp_mod -= tile_intensity_mod( mt, fd_cold_air1, 2, 6, 10 );
temp_mod -= tile_intensity_mod( mt, fd_cold_air2, 6, 16, 20 );
temp_mod -= tile_intensity_mod( mt, fd_cold_air3, 16, 40, 70 );
temp_mod -= tile_intensity_mod( mt, fd_cold_air4, 70, 100, 160 );

return temp_mod;
int lava_mod = maptile_trap_eq( mt, tr_lava ) ? fd_fire.obj().get_convection_temperature_mod() : 0;
// Modifier from fields
for( auto fd : g->m.field_at( location ) ) {
// Nullify lava modifier when there is open fire
if( fd.first.obj().has_fire ) {
lava_mod = 0;
};
temp_mod += fd.second.convection_temperature_mod();
}
return temp_mod + lava_mod;
}

int game::assign_mission_id()
Expand Down Expand Up @@ -5857,8 +5844,8 @@ void game::print_fields_info( const tripoint &lp, const catacurses::window &w_lo
const field &tmpfield = m.field_at( lp );
for( auto &fld : tmpfield ) {
const field_entry &cur = fld.second;
if( fld.first == fd_fire && ( m.has_flag( TFLAG_FIRE_CONTAINER, lp ) ||
m.ter( lp ) == t_pit_shallow || m.ter( lp ) == t_pit ) ) {
if( fld.first.obj().has_fire && ( m.has_flag( TFLAG_FIRE_CONTAINER, lp ) ||
m.ter( lp ) == t_pit_shallow || m.ter( lp ) == t_pit ) ) {
const int max_width = getmaxx( w_look ) - column - 2;
int lines = fold_and_print( w_look, ++line, column, max_width, cur.color(),
get_fire_fuel_string( lp ) ) - 1;
Expand Down Expand Up @@ -9278,7 +9265,7 @@ point game::place_player( const tripoint &dest_loc )
const auto pulp = [&]( const tripoint & pos ) {
for( const auto &maybe_corpse : m.i_at( pos ) ) {
if( maybe_corpse.is_corpse() && maybe_corpse.can_revive() &&
maybe_corpse.get_mtype()->bloodType() != fd_acid ) {
!maybe_corpse.get_mtype()->bloodType().obj().has_acid ) {
u.assign_activity( activity_id( "ACT_PULP" ), calendar::INDEFINITELY_LONG, 0 );
u.activity.placement = pos;
u.activity.auto_resume = true;
Expand Down
11 changes: 3 additions & 8 deletions src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4252,13 +4252,8 @@ int iuse::gasmask( player *p, item *it, bool t, const tripoint &pos )
const field &gasfield = g->m.field_at( pos );
for( auto &dfield : gasfield ) {
const field_entry &entry = dfield.second;
const field_type_id fid = entry.get_field_type();
if( fid == fd_smoke ) {
it->set_var( "gas_absorbed", it->get_var( "gas_absorbed", 0 ) + 12 );
}
if( fid == fd_tear_gas || fid == fd_toxic_gas || fid == fd_gas_vent ||
fid == fd_smoke_vent || fid == fd_relax_gas || fid == fd_fungal_haze ) {
it->set_var( "gas_absorbed", it->get_var( "gas_absorbed", 0 ) + 15 );
if( entry.get_gas_absorption_factor() > 0 ) {
it->set_var( "gas_absorbed", it->get_var( "gas_absorbed", 0 ) + entry.get_gas_absorption_factor() );
}
}
if( it->get_var( "gas_absorbed", 0 ) >= 100 ) {
Expand Down Expand Up @@ -4516,7 +4511,7 @@ int iuse::blood_draw( player *p, item *it, bool, const tripoint & )
p->add_msg_if_player( m_info, _( "You drew blood from the %s..." ), map_it.tname() );
drew_blood = true;
auto bloodtype( map_it.get_mtype()->bloodType() );
if( bloodtype == fd_acid ) {
if( bloodtype.obj().has_acid ) {
acid_blood = true;
} else {
blood.set_mtype( map_it.get_mtype() );
Expand Down
2 changes: 1 addition & 1 deletion src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ int explosion_iuse::use( player &p, item &it, bool t, const tripoint &pos ) cons
if( do_flashbang ) {
explosion_handler::flashbang( pos, flashbang_player_immune );
}
if( fields_radius >= 0 && fields_type != fd_null ) {
if( fields_radius >= 0 && !fields_type.id().is_null() ) {
ZhilkinSerg marked this conversation as resolved.
Show resolved Hide resolved
std::vector<tripoint> gas_sources = points_for_gas_cloud( pos, fields_radius );
for( auto &gas_source : gas_sources ) {
const int field_intensity = rng( fields_min_intensity, fields_max_intensity );
Expand Down
Loading