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

Terrain/furniture: code deduplication and improved "copy-from" support #77637

Merged
merged 1 commit into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 2 additions & 6 deletions data/json/connect_groups.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
[
{
"type": "connect_group",
"id": "WALL",
"group_flags": [ "WALL", "CONNECT_WITH_WALL" ],
"connects_to_flags": [ "WALL", "CONNECT_WITH_WALL" ]
"id": "WALL"
},
{
"type": "connect_group",
Expand Down Expand Up @@ -135,8 +133,6 @@
},
{
"type": "connect_group",
"id": "INDOORFLOOR",
"group_flags": [ "INDOORS" ],
"rotates_to_flags": [ "WINDOW", "DOOR" ]
"id": "INDOORFLOOR"
}
]
65 changes: 35 additions & 30 deletions src/construction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1572,10 +1572,10 @@ bool construct::check_deconstruct( const tripoint_bub_ms &p )
if( here.has_flag_furn( ter_furn_flag::TFLAG_EASY_DECONSTRUCT, p ) ) {
return false;
}
return here.furn( p ).obj().deconstruct.can_do;
return !!here.furn( p ).obj().deconstruct;
}
// terrain can only be deconstructed when there is no furniture in the way
return here.ter( p ).obj().deconstruct.can_do;
return !!here.ter( p ).obj().deconstruct;
}

bool construct::check_up_OK( const tripoint_bub_ms & )
Expand Down Expand Up @@ -1788,21 +1788,21 @@ void construct::done_deconstruct( const tripoint_bub_ms &p, Character &player_ch
// TODO: Make this the argument
if( here.has_furn( p ) ) {
const furn_t &f = here.furn( p ).obj();
if( !f.deconstruct.can_do ) {
if( !f.deconstruct ) {
add_msg( m_info, _( "That %s can not be disassembled!" ), f.name() );
return;
}
if( f.deconstruct.furn_set.str().empty() ) {
if( f.deconstruct->furn_set.str().empty() ) {
here.furn_set( p, furn_str_id::NULL_ID() );
} else {
here.furn_set( p, f.deconstruct.furn_set );
here.furn_set( p, f.deconstruct->furn_set );
}
add_msg( _( "The %s is disassembled." ), f.name() );
item &item_here = here.i_at( p ).size() != 1 ? null_item_reference() : here.i_at( p ).only_item();
const std::vector<item *> drop = here.spawn_items( p,
item_group::items_from( f.deconstruct.drop_group, calendar::turn ) );
if( f.deconstruct.skill.has_value() ) {
deconstruction_practice_skill( f.deconstruct.skill.value() );
item_group::items_from( f.deconstruct->drop_group, calendar::turn ) );
if( f.deconstruct->skill.has_value() ) {
deconstruction_practice_skill( f.deconstruct->skill.value() );
}
// if furniture has liquid in it and deconstructs into watertight containers then fill them
if( f.has_flag( "LIQUIDCONT" ) && item_here.made_of( phase_id::LIQUID ) ) {
Expand All @@ -1825,23 +1825,23 @@ void construct::done_deconstruct( const tripoint_bub_ms &p, Character &player_ch
here.delete_signage( p );
} else {
const ter_t &t = here.ter( p ).obj();
if( !t.deconstruct.can_do ) {
if( !t.deconstruct ) {
add_msg( _( "That %s can not be disassembled!" ), t.name() );
return;
}
if( t.deconstruct.deconstruct_above ) {
if( t.deconstruct->deconstruct_above ) {
const tripoint_bub_ms top = p + tripoint_above;
if( here.has_furn( top ) ) {
add_msg( _( "That %s can not be disassembled, since there is furniture above it." ), t.name() );
return;
}
done_deconstruct( top, player_character );
}
here.ter_set( p, t.deconstruct.ter_set );
here.ter_set( p, t.deconstruct->ter_set );
add_msg( _( "The %s is disassembled." ), t.name() );
here.spawn_items( p, item_group::items_from( t.deconstruct.drop_group, calendar::turn ) );
if( t.deconstruct.skill.has_value() ) {
deconstruction_practice_skill( t.deconstruct.skill.value() );
here.spawn_items( p, item_group::items_from( t.deconstruct->drop_group, calendar::turn ) );
if( t.deconstruct->skill.has_value() ) {
deconstruction_practice_skill( t.deconstruct->skill.value() );
}
}
}
Expand Down Expand Up @@ -2090,34 +2090,39 @@ void construct::do_turn_deconstruct( const tripoint_bub_ms &p, Character &who )
}
return ret;
};
auto deconstruction_will_practice_skill = [ &who ]( auto & skill ) {
auto deconstruction_will_practice_skill = [&who]( auto & skill ) {
return who.get_skill_level( skill.id ) >= skill.min &&
who.get_skill_level( skill.id ) < skill.max;
};

if( here.has_furn( p ) ) {
const furn_t &f = here.furn( p ).obj();
if( !!f.deconstruct.skill &&
deconstruction_will_practice_skill( *f.deconstruct.skill ) ) {
auto deconstruct_query = [&who, &cancel_construction, &deconstruction_will_practice_skill,
&deconstruct_items]( map_common_deconstruct_info & deconstruct, std::string & name ) {
if( !!deconstruct.skill &&
deconstruction_will_practice_skill( deconstruct.skill.value() ) ) {
cancel_construction = !who.query_yn(
_( "Deconstructing the %s will yield:\n%s\nYou feel you might also learn something about %s.\nReally deconstruct?" ),
f.name(), deconstruct_items( f.deconstruct.drop_group ), f.deconstruct.skill->id.obj().name() );
name, deconstruct_items( deconstruct.drop_group ), deconstruct.skill->id.obj().name() );
} else {
cancel_construction = !who.query_yn(
_( "Deconstructing the %s will yield:\n%s\nReally deconstruct?" ),
f.name(), deconstruct_items( f.deconstruct.drop_group ) );
name, deconstruct_items( deconstruct.drop_group ) );
}
};

std::string tname;
if( here.has_furn( p ) ) {
const furn_t &f = here.furn( p ).obj();
if( f.deconstruct ) {
map_furn_deconstruct_info deconstruct = f.deconstruct.value();
tname = f.name();
deconstruct_query( deconstruct, tname );
}
} else {
const ter_t &t = here.ter( p ).obj();
if( !!t.deconstruct.skill &&
deconstruction_will_practice_skill( *t.deconstruct.skill ) ) {
cancel_construction = !who.query_yn(
_( "Deconstructing the %s will yield:\n%s\nYou feel you might also learn something about %s.\nReally deconstruct?" ),
t.name(), deconstruct_items( t.deconstruct.drop_group ), t.deconstruct.skill->id.obj().name() );
} else {
cancel_construction = !who.query_yn(
_( "Deconstructing the %s will yield:\n%s\nReally deconstruct?" ),
t.name(), deconstruct_items( t.deconstruct.drop_group ) );
if( t.deconstruct ) {
map_ter_deconstruct_info deconstruct = t.deconstruct.value();
tname = t.name();
deconstruct_query( deconstruct, tname );
}
}
if( cancel_construction ) {
Expand Down
13 changes: 8 additions & 5 deletions src/faction_camp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4863,12 +4863,15 @@ int om_harvest_ter( npc &comp, const tripoint_abs_omt &omt_tgt, const ter_id &t,
continue;
}
if( bring_back ) {
for( const item &itm : item_group::items_from( ter_tgt.bash.drop_group,
calendar::turn ) ) {
comp.companion_mission_inv.push_back( itm );
const std::optional<map_ter_bash_info> &bash = ter_tgt.bash;
if( bash ) {
for( const item &itm : item_group::items_from( ter_tgt.bash->drop_group,
calendar::turn ) ) {
comp.companion_mission_inv.push_back( itm );
}
harvested++;
target_bay.ter_set( p, ter_tgt.bash->ter_set );
}
harvested++;
target_bay.ter_set( p, ter_tgt.bash.ter_set );
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/field_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,12 @@ void field_type::load( const JsonObject &jo, const std::string_view )
optional( jo, was_loaded, "mopsafe", mopsafe, false );

optional( jo, was_loaded, "decrease_intensity_on_contact", decrease_intensity_on_contact, false );

bash_info.load( jo, "bash", map_bash_info::field, "field " + id.str() );
if( jo.has_object( "bash" ) ) {
if( !bash_info ) {
bash_info.emplace();
}
bash_info->load( jo.get_object( "bash" ), was_loaded, "field " + id.str() );
}
if( was_loaded && jo.has_member( "copy-from" ) && looks_like.empty() ) {
looks_like = jo.get_string( "copy-from" );
}
Expand Down
2 changes: 1 addition & 1 deletion src/field_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ struct field_type {
bool has_elec = false;
bool has_fume = false;
description_affix desc_affix = description_affix::DESCRIPTION_AFFIX_NUM;
map_bash_info bash_info;
std::optional<map_fd_bash_info> bash_info;

// chance, issue, duration, speech
std::tuple<int, std::string, time_duration, translation> npc_complain_data;
Expand Down
23 changes: 12 additions & 11 deletions src/handle_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -993,30 +993,31 @@ avatar::smash_result avatar::smash( tripoint_bub_ms &smashp )
}
}
for( std::pair<const field_type_id, field_entry> &fd_to_smsh : here.field_at( smashp ) ) {
const map_bash_info &bash_info = fd_to_smsh.first->bash_info;
if( bash_info.str_min == -1 ) {
const std::optional<map_fd_bash_info> &bash_info = fd_to_smsh.first->bash_info;
if( !bash_info ) {
continue;
}
if( smashskill < bash_info.str_min && one_in( 10 ) ) {
if( smashskill < bash_info->str_min && one_in( 10 ) ) {
add_msg( m_neutral, _( "You don't seem to be damaging the %s." ), fd_to_smsh.first->get_name() );
ret.did_smash = true;
return ret;
} else if( smashskill >= rng( bash_info.str_min, bash_info.str_max ) ) {
sounds::sound( smashp, bash_info.sound_vol, sounds::sound_t::combat, bash_info.sound, true, "smash",
} else if( smashskill >= rng( bash_info->str_min, bash_info->str_max ) ) {
sounds::sound( smashp, bash_info->sound_vol, sounds::sound_t::combat, bash_info->sound, true,
"smash",
"field" );
here.remove_field( smashp, fd_to_smsh.first );
here.spawn_items( smashp, item_group::items_from( bash_info.drop_group, calendar::turn ) );
mod_moves( - bash_info.fd_bash_move_cost );
add_msg( m_info, bash_info.field_bash_msg_success.translated() );
here.spawn_items( smashp, item_group::items_from( bash_info->drop_group, calendar::turn ) );
mod_moves( - bash_info->fd_bash_move_cost );
add_msg( m_info, bash_info->field_bash_msg_success.translated() );
ret.did_smash = true;
ret.success = true;
return ret;
} else {
sounds::sound( smashp, bash_info.sound_fail_vol, sounds::sound_t::combat, bash_info.sound_fail,
sounds::sound( smashp, bash_info->sound_fail_vol, sounds::sound_t::combat, bash_info->sound_fail,
true, "smash",
"field" );

ret.resistance = bash_info.str_min;
ret.resistance = bash_info->str_min;
ret.did_smash = true;
return ret;
}
Expand Down Expand Up @@ -1123,7 +1124,7 @@ avatar::smash_result avatar::smash( tripoint_bub_ms &smashp )
// Bash not effective
g->draw_async_anim( smashp, "bash_ineffective" );
if( one_in( 10 ) ) {
if( here.has_furn( smashp ) && here.furn( smashp ).obj().bash.str_min != -1 ) {
if( here.has_furn( smashp ) && here.furn( smashp ).obj().bash ) {
// %s is the smashed furniture
add_msg( m_neutral, _( "You don't seem to be damaging the %s." ), here.furnname( smashp ) );
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/iexamine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,8 @@ void iexamine::portable_structure( Character &you, const tripoint_bub_ms &examp
}
radius = actor.radius;
} else {
radius = std::max( 1, fid->bash.collapse_radius );
const std::optional<map_furn_bash_info> &furn_bash = fid.obj().bash;
radius = std::max( 1, furn_bash ? furn_bash->collapse_radius : 0 );
}

if( !query_yn( _( "Take down the %s?" ), name ) ) {
Expand Down
Loading
Loading