Skip to content

Commit 6984c69

Browse files
committed
Display construction pre_flags
1 parent cd59a1e commit 6984c69

File tree

8 files changed

+211
-17
lines changed

8 files changed

+211
-17
lines changed

data/json/flags.json

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,5 +2741,110 @@
27412741
"id": "CYLINDER_GRENADE",
27422742
"type": "json_flag",
27432743
"//": "A flag for the large grenade bandolier to limit the type of grenades it will accept."
2744+
},
2745+
{
2746+
"id": "BARRICADABLE_DOOR_DAMAGED",
2747+
"type": "json_flag",
2748+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2749+
"name": "Damaged Barricadable Door"
2750+
},
2751+
{
2752+
"id": "BARRICADABLE_DOOR_REINFORCED_DAMAGED",
2753+
"type": "json_flag",
2754+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2755+
"name": "Damaged Barricadable Reinforced Door"
2756+
},
2757+
{
2758+
"id": "BARRICADABLE_DOOR_REINFORCED",
2759+
"type": "json_flag",
2760+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2761+
"name": "Barricadable Reinforced Door"
2762+
},
2763+
{
2764+
"id": "BARRICADABLE_DOOR",
2765+
"type": "json_flag",
2766+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2767+
"name": "Barricadable Door"
2768+
},
2769+
{
2770+
"id": "BARRICADABLE_WINDOW_CURTAINS",
2771+
"type": "json_flag",
2772+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2773+
"name": "Barricadable Window with Curtains"
2774+
},
2775+
{
2776+
"id": "BARRICADABLE_WINDOW",
2777+
"type": "json_flag",
2778+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2779+
"name": "Barricadable Window"
2780+
},
2781+
{
2782+
"id": "CHIP",
2783+
"type": "json_flag",
2784+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2785+
"name": "Chip",
2786+
"info": "A paint chipper can be used to remove paint from this."
2787+
},
2788+
{
2789+
"id": "DIGGABLE",
2790+
"type": "json_flag",
2791+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2792+
"name": "Diggable",
2793+
"info": "A hole can be dug here."
2794+
},
2795+
{
2796+
"id": "EASY_DECONSTRUCT",
2797+
"type": "json_flag",
2798+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2799+
"name": "Simple"
2800+
},
2801+
{
2802+
"id": "FLAT",
2803+
"type": "json_flag",
2804+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2805+
"name": "Flat"
2806+
},
2807+
{
2808+
"id": "PIT_FILLABLE",
2809+
"type": "json_flag",
2810+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2811+
"name": "Fillable pit"
2812+
},
2813+
{
2814+
"id": "PLOWABLE",
2815+
"type": "json_flag",
2816+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2817+
"name": "Plowable"
2818+
},
2819+
{
2820+
"id": "RUBBLE",
2821+
"type": "json_flag",
2822+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2823+
"name": "Rubble"
2824+
},
2825+
{
2826+
"id": "SUPPORTS_ROOF",
2827+
"type": "json_flag",
2828+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2829+
"name": "Supports roof",
2830+
"info": "A roof can be built above this without other support."
2831+
},
2832+
{
2833+
"id": "TREE",
2834+
"type": "json_flag",
2835+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2836+
"name": "Tree"
2837+
},
2838+
{
2839+
"id": "WALL",
2840+
"type": "json_flag",
2841+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2842+
"name": "Wall"
2843+
},
2844+
{
2845+
"id": "WIRED_WALL",
2846+
"type": "json_flag",
2847+
"//": "Terrain / Furniture flag used in Construction pre_flags field",
2848+
"name": "Wired Wall"
27442849
}
27452850
]

doc/JSON/JSON_FLAGS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171

7272
## Notes
7373

74-
- Some flags (items, effects, vehicle parts) have to be defined in `flags.json` or `vp_flags.json` (with type: `json_flag`) to work correctly.
74+
- Some flags (items, effects, vehicle parts, construction pre_flags) have to be defined in `flags.json` or `vp_flags.json` (with type: `json_flag`) to work correctly.
7575
- Many of the flags intended for one category or item type can be used in other categories or item types. Experiment to see where else flags can be used.
7676
- Offensive and defensive flags can be used on any item type that can be wielded.
7777

@@ -600,6 +600,7 @@ These are checked by hardcode for monsters (introducing new flags will require C
600600
## Furniture and Terrain
601601

602602
List of known flags, used in both `furniture` and `terrain`. Some work for both, others are limited to either.
603+
Can also be used as `pre_flags` for `construction`.
603604

604605
- ```ALARMED``` Sets off an alarm if smashed.
605606
- ```ALLOW_FIELD_EFFECT``` Apply field effects to items inside `SEALED` terrain/furniture.

doc/JSON/JSON_INFO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,7 @@ The array of hobbies (listed as professions) is whitelisted to all characters.
20752075
"components": [ [ [ "spear_wood", 4 ], [ "pointy_stick", 4 ] ] ], // Items used in construction
20762076
"pre_special": [ "check_empty", "check_up_OK" ], // Required something that isn't terrain. The syntax also allows for a square bracket enclosed list of specials which all have to be fulfilled
20772077
"pre_terrain": "t_pit", // Alternative to pre_special; Required terrain to build on
2078-
"pre_flags": [ "WALL", { "flag": "DIGGABLE", "force_terrain": true } ], // Flags beginning furniture/terrain must have. force_ter forces the flag to apply to the underlying terrain
2078+
"pre_flags": [ "WALL", { "flag": "DIGGABLE", "force_terrain": true } ], // Flags beginning furniture/terrain must have. force_ter forces the flag to apply to the underlying terrain. Must be defined in flags.json
20792079
"post_terrain": "t_pit_spiked", // Terrain type after construction is complete
20802080
"post_special": "done_mine_upstairs", // Required to do something beyond setting the post terrain. The syntax also allows for a square bracket enclosed list of specials which all have to be fulfilled
20812081
"pre_note": "Build a spikes on a diggable terrain", // Create an annotation to this recipe

src/activity_item_handling.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ construction const *_find_prereq( tripoint_bub_ms const &loc, construction_id co
836836
( idx->pre_terrain.find( it.post_terrain ) != idx->pre_terrain.end() ) &&
837837
// don't get stuck building and deconstructing the top level post_terrain
838838
( it.pre_terrain.find( top_idx->post_terrain ) == it.pre_terrain.end() ) &&
839-
( it.pre_flags.empty() || !can_construct_furn_ter( it, f, t ) );
839+
( it.pre_flags.empty() || !has_pre_flags( it, f, t ) );
840840
} );
841841

842842
for( construction const *gcon : cons ) {

src/construction.cpp

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "enums.h"
3030
#include "event.h"
3131
#include "event_bus.h"
32+
#include "flag.h"
3233
#include "flexbuffer_json.h"
3334
#include "game.h"
3435
#include "game_constants.h"
@@ -159,7 +160,6 @@ static const vpart_id vpart_frame( "frame" );
159160

160161
static const vproto_id vehicle_prototype_none( "none" );
161162

162-
static const std::string flag_INITIAL_PART( "INITIAL_PART" );
163163
static const std::string flag_WIRING( "WIRING" );
164164

165165
static bool finalized = false;
@@ -480,6 +480,8 @@ static shared_ptr_fast<game::draw_callback_t> construction_preview_callback(
480480
} );
481481
}
482482

483+
static std::string has_pre_flags_colorize( const construction &con );
484+
483485
construction_id construction_menu( const bool blueprint )
484486
{
485487
if( !finalized ) {
@@ -704,10 +706,14 @@ construction_id construction_menu( const bool blueprint )
704706
return ter_str_id( pre_terrain )->name();
705707
} );
706708
}
709+
//TODO: per-requirement colorizing like has_pre_flags_colorize
707710
nc_color pre_color = has_pre_terrain( *current_con ) ? c_green : c_red;
708711
add_line( _( "Requires: " ) + colorize( enumerate_as_string( require_names,
709712
enumeration_conjunction::or_ ), pre_color ) );
710713
}
714+
if( !current_con->pre_flags.empty() ) {
715+
add_line( string_format( _( "Required conditions: %s" ), has_pre_flags_colorize( *current_con ) ) );
716+
}
711717
if( !current_con->pre_note.empty() ) {
712718
add_line( _( "Annotation: " ) + colorize( current_con->pre_note, color_data ) );
713719
}
@@ -1162,7 +1168,7 @@ bool player_can_see_to_build( Character &you, const construction_group_str_id &g
11621168
return false;
11631169
}
11641170

1165-
bool can_construct_furn_ter( const construction &con, furn_id const &f, ter_id const &t )
1171+
bool has_pre_flags( const construction &con, furn_id const &f, ter_id const &t )
11661172
{
11671173
return std::all_of( con.pre_flags.begin(), con.pre_flags.end(), [&f, &t]( auto const & flag ) {
11681174
const bool use_ter = flag.second || f == furn_str_id::NULL_ID();
@@ -1171,6 +1177,76 @@ bool can_construct_furn_ter( const construction &con, furn_id const &f, ter_id c
11711177
} );
11721178
}
11731179

1180+
// static bool has_pre_flags( const construction &con, const tripoint_bub_ms &p )
1181+
// {
1182+
// if( con.pre_flags.empty() ) {
1183+
// return true;
1184+
// }
1185+
// const map &here = get_map();
1186+
// furn_id f = here.furn( p );
1187+
// ter_id t = here.ter( p );
1188+
// return has_pre_flags( con, f, t );
1189+
// }
1190+
1191+
// static bool has_pre_flags( const construction &con )
1192+
// {
1193+
// if( con.pre_flags.empty() ) {
1194+
// return true;
1195+
// }
1196+
// const tripoint_bub_ms &avatar_pos = get_player_character().pos_bub();
1197+
// for( const tripoint_bub_ms &p : get_map().points_in_radius( avatar_pos, 1 ) ) {
1198+
// if( p != avatar_pos && has_pre_flags( con, p ) ) {
1199+
// return true;
1200+
// }
1201+
// }
1202+
// return false;
1203+
// }
1204+
1205+
// Returns a colorized list of pre_flags, red for unmatched flags, green for matched flags.
1206+
static std::string has_pre_flags_colorize( const construction &con )
1207+
{
1208+
if( con.pre_flags.empty() ) {
1209+
return "";
1210+
}
1211+
1212+
std::vector<std::string> flags_colorized;
1213+
1214+
const map &here = get_map();
1215+
1216+
const tripoint_bub_ms &avatar_pos = get_player_character().pos_bub();
1217+
const auto points = get_map().points_in_radius( avatar_pos, 1 );
1218+
// which of the surrounding points have all the necessary flags
1219+
std::vector<bool> good_points( 9, true );
1220+
// can't build in the player's location
1221+
good_points[4] = false;
1222+
for( const auto &flag : con.pre_flags ) {
1223+
bool has_flag = false;
1224+
size_t index = 0;
1225+
for( const auto &p : points ) {
1226+
if( p != avatar_pos ) {
1227+
const furn_id &f = here.furn( p );
1228+
const ter_id &t = here.ter( p );
1229+
const bool use_ter = flag.second || f == furn_str_id::NULL_ID();
1230+
has_flag = ( use_ter || f->has_flag( flag.first ) ) && ( !use_ter || t->has_flag( flag.first ) );
1231+
if( !has_flag ) {
1232+
good_points[ index ] = false;
1233+
}
1234+
}
1235+
index++;
1236+
}
1237+
const nc_color color = has_flag ? c_green : c_red;
1238+
flags_colorized.emplace_back( colorize( flag_id( flag.first )->name(), color ) );
1239+
}
1240+
// It's possible that each flag is green because some adjacent location has it
1241+
// but no single location has every flag. That is represented here by coloring
1242+
// the commas and conjunction red.
1243+
const bool has_good_point = std::any_of( good_points.begin(), good_points.end(), []( bool a ) {
1244+
return a;
1245+
} );
1246+
const nc_color color = has_good_point ? c_green : c_red;
1247+
return colorize( enumerate_as_string( flags_colorized ), color );
1248+
}
1249+
11741250
bool can_construct( const construction &con, const tripoint_bub_ms &p )
11751251
{
11761252
const map &here = get_map();
@@ -1186,7 +1262,7 @@ bool can_construct( const construction &con, const tripoint_bub_ms &p )
11861262
return false;
11871263
}
11881264
if( !has_pre_terrain( con, p ) || // terrain type
1189-
!can_construct_furn_ter( con, f, t ) ) { // flags
1265+
!has_pre_flags( con, f, t ) ) { // flags
11901266
return false;
11911267
}
11921268
if( !con.post_terrain.empty() ) { // make sure the construction would actually do something
@@ -1702,7 +1778,7 @@ void construct::done_grave( const tripoint_bub_ms &p, Character &player_characte
17021778
static vpart_id vpart_from_item( const itype_id &item_id )
17031779
{
17041780
for( const vpart_info &vpi : vehicles::parts::get_all() ) {
1705-
if( vpi.base_item == item_id && vpi.has_flag( flag_INITIAL_PART ) ) {
1781+
if( vpi.base_item == item_id && vpi.has_flag( flag_INITIAL_PART.str() ) ) {
17061782
return vpi.id;
17071783
}
17081784
}
@@ -2514,7 +2590,7 @@ void finalize_constructions()
25142590
{
25152591
std::vector<item_comp> frame_items;
25162592
for( const vpart_info &vpi : vehicles::parts::get_all() ) {
2517-
if( !vpi.has_flag( flag_INITIAL_PART ) ) {
2593+
if( !vpi.has_flag( flag_INITIAL_PART.str() ) ) {
25182594
continue;
25192595
}
25202596
if( vpi.id == vpart_frame ) {

src/construction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ void load_construction( const JsonObject &jo );
124124
void reset_constructions();
125125
construction_id construction_menu( bool blueprint );
126126
void complete_construction( Character *you );
127-
bool can_construct_furn_ter( const construction &con, furn_id const &furn, ter_id const &ter );
127+
bool has_pre_flags( const construction &con, furn_id const &f, ter_id const &t );
128128
bool can_construct( const construction &con, const tripoint_bub_ms &p );
129129
bool player_can_build( Character &you, const read_only_visitable &inv, const construction &con,
130130
bool can_construct_skip = false );

src/map.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ static const efftype_id effect_weakened_gravity( "weakened_gravity" );
138138
static const field_type_str_id field_fd_clairvoyant( "fd_clairvoyant" );
139139

140140
static const flag_id json_flag_AVATAR_ONLY( "AVATAR_ONLY" );
141+
static const flag_id json_flag_DIGGABLE( "DIGGABLE" );
142+
static const flag_id json_flag_EASY_DECONSTRUCT( "EASY_DECONSTRUCT" );
143+
static const flag_id json_flag_FLAT( "FLAT" );
141144
static const flag_id json_flag_JETPACK( "JETPACK" );
142145
static const flag_id json_flag_LEVITATION( "LEVITATION" );
146+
static const flag_id json_flag_PLOWABLE( "PLOWABLE" );
143147
static const flag_id json_flag_PRESERVE_SPAWN_LOC( "PRESERVE_SPAWN_LOC" );
144148
static const flag_id json_flag_PROXIMITY( "PROXIMITY" );
145149
static const flag_id json_flag_UNDODGEABLE( "UNDODGEABLE" );
@@ -2315,13 +2319,14 @@ std::string map::features( const tripoint_bub_ms &p ) const
23152319
// to take up one line. So, make sure it does that.
23162320
// FIXME: can't control length of localized text.
23172321
add_if( is_bashable( p ), _( "Smashable." ) );
2318-
add_if( has_flag( ter_furn_flag::TFLAG_DIGGABLE, p ), _( "Diggable." ) );
2319-
add_if( has_flag( ter_furn_flag::TFLAG_PLOWABLE, p ), _( "Plowable." ) );
2322+
add_if( has_flag( ter_furn_flag::TFLAG_DIGGABLE, p ), json_flag_DIGGABLE->name() );
2323+
add_if( has_flag( ter_furn_flag::TFLAG_PLOWABLE, p ), json_flag_PLOWABLE->name() );
23202324
add_if( has_flag( ter_furn_flag::TFLAG_ROUGH, p ), _( "Rough." ) );
23212325
add_if( has_flag( ter_furn_flag::TFLAG_UNSTABLE, p ), _( "Unstable." ) );
23222326
add_if( has_flag( ter_furn_flag::TFLAG_SHARP, p ), _( "Sharp." ) );
2323-
add_if( has_flag( ter_furn_flag::TFLAG_FLAT, p ), _( "Flat." ) );
2324-
add_if( has_flag( ter_furn_flag::TFLAG_EASY_DECONSTRUCT, p ), _( "Simple." ) );
2327+
add_if( has_flag( ter_furn_flag::TFLAG_FLAT, p ), json_flag_FLAT->name() );
2328+
add_if( has_flag( ter_furn_flag::TFLAG_EASY_DECONSTRUCT, p ),
2329+
json_flag_EASY_DECONSTRUCT->name() );
23252330
add_if( has_flag( ter_furn_flag::TFLAG_MOUNTABLE, p ), _( "Mountable." ) );
23262331
add_if( has_flag( ter_furn_flag::TFLAG_FLAMMABLE, p ) ||
23272332
has_flag( ter_furn_flag::TFLAG_FLAMMABLE_ASH, p ) ||

src/mapdata.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "debug.h"
1717
#include "enum_conversions.h"
1818
#include "flexbuffer_json.h"
19+
#include "flag.h"
1920
#include "generic_factory.h"
2021
#include "harvest.h"
2122
#include "iexamine.h"
@@ -33,6 +34,12 @@
3334
#include "type_id.h"
3435

3536
static furn_id f_null;
37+
38+
static const flag_id json_flag_DIGGABLE( "DIGGABLE" );
39+
static const flag_id json_flag_EASY_DECONSTRUCT( "EASY_DECONSTRUCT" );
40+
static const flag_id json_flag_FLAT( "FLAT" );
41+
static const flag_id json_flag_PLOWABLE( "PLOWABLE" );
42+
3643
static const furn_str_id furn_f_null( "f_null" );
3744

3845
static const item_group_id Item_spawn_data_EMPTY_GROUP( "EMPTY_GROUP" );
@@ -825,13 +832,13 @@ std::vector<std::string> map_data_common_t::extended_description() const
825832
add( text );
826833
}
827834
};
828-
add_if( has_flag( ter_furn_flag::TFLAG_DIGGABLE ), _( "Diggable." ) );
829-
add_if( has_flag( ter_furn_flag::TFLAG_PLOWABLE ), _( "Plowable." ) );
835+
add_if( has_flag( ter_furn_flag::TFLAG_DIGGABLE ), json_flag_DIGGABLE->name() );
836+
add_if( has_flag( ter_furn_flag::TFLAG_PLOWABLE ), json_flag_PLOWABLE->name() );
830837
add_if( has_flag( ter_furn_flag::TFLAG_ROUGH ), _( "Rough." ) );
831838
add_if( has_flag( ter_furn_flag::TFLAG_UNSTABLE ), _( "Unstable." ) );
832839
add_if( has_flag( ter_furn_flag::TFLAG_SHARP ), _( "Sharp." ) );
833-
add_if( has_flag( ter_furn_flag::TFLAG_FLAT ), _( "Flat." ) );
834-
add_if( has_flag( ter_furn_flag::TFLAG_EASY_DECONSTRUCT ), _( "Simple." ) );
840+
add_if( has_flag( ter_furn_flag::TFLAG_FLAT ), json_flag_FLAT->name() );
841+
add_if( has_flag( ter_furn_flag::TFLAG_EASY_DECONSTRUCT ), json_flag_EASY_DECONSTRUCT->name() );
835842
add_if( has_flag( ter_furn_flag::TFLAG_MOUNTABLE ), _( "Mountable." ) );
836843
add_if( is_flammable(), _( "Flammable." ) );
837844
if( !result.empty() ) {

0 commit comments

Comments
 (0)