From 126de50d04f95fa3a5ca98e887ced44bcec54b2f Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Thu, 11 Apr 2019 01:10:37 +0200 Subject: [PATCH] Add vehicle workbench functionality - Add vehicle examine function - Add craft from vehicle infrastructure - Add WORKBENCH1/2/3 flags --- data/json/furniture.json | 15 +++--- data/json/vehicle_parts.json | 6 +-- src/crafting.cpp | 101 +++++++++++++++++++++++++---------- src/iexamine.cpp | 6 +-- src/veh_interact.cpp | 4 +- src/vehicle.h | 1 + src/vehicle_use.cpp | 98 ++++++++++++++++++++++++++++++++- 7 files changed, 188 insertions(+), 43 deletions(-) diff --git a/data/json/furniture.json b/data/json/furniture.json index aff5fea12cd23..a0ad75ebf6f02 100644 --- a/data/json/furniture.json +++ b/data/json/furniture.json @@ -745,7 +745,7 @@ "color": "light_red", "move_cost_mod": 1, "required_str": 8, - "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "CONTAINER", "PLACE_ITEM", "ORGANIC", "MOUNTABLE", "FLAT_SURF" ], + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "CONTAINER", "PLACE_ITEM", "ORGANIC", "MOUNTABLE", "FLAT_SURF", "WORKBENCH" ], "deconstruct": { "items": [ { "item": "2x4", "count": 4 }, { "item": "nail", "charges": [ 6, 10 ] } ] }, "max_volume": 4000, "bash": { @@ -857,7 +857,7 @@ "move_cost_mod": 2, "required_str": 8, "max_volume": 4000, - "flags": [ "TRANSPARENT", "FLAMMABLE", "ORGANIC", "MOUNTABLE", "SHORT", "FLAT_SURF" ], + "flags": [ "TRANSPARENT", "FLAMMABLE", "ORGANIC", "MOUNTABLE", "SHORT", "FLAT_SURF", "WORKBENCH" ], "deconstruct": { "items": [ { "item": "2x4", "count": 6 }, { "item": "nail", "charges": [ 6, 8 ] } ] }, "bash": { "str_min": 12, @@ -970,7 +970,7 @@ "color": "blue", "move_cost_mod": 2, "required_str": 10, - "flags": [ "TRANSPARENT", "FLAMMABLE", "ORGANIC", "MOUNTABLE", "SHORT", "FLAT_SURF" ], + "flags": [ "TRANSPARENT", "FLAMMABLE", "ORGANIC", "MOUNTABLE", "SHORT", "FLAT_SURF", "WORKBENCH" ], "deconstruct": { "items": [ { "item": "2x4", "count": 6 }, { "item": "nail", "charges": [ 6, 8 ] } ] }, "max_volume": 4000, "bash": { @@ -979,7 +979,8 @@ "sound": "smash!", "sound_fail": "whump.", "items": [ { "item": "2x4", "count": [ 2, 6 ] }, { "item": "nail", "charges": [ 4, 8 ] }, { "item": "splinter", "count": 1 } ] - } + }, + "examine_action": "workbench" }, { "type": "furniture", @@ -4453,7 +4454,7 @@ "move_cost_mod": 2, "required_str": -1, "looks_like": "f_counter", - "flags": [ "TRANSPARENT", "PLACE_ITEM", "MOUNTABLE", "FLAT_SURF" ], + "flags": [ "TRANSPARENT", "PLACE_ITEM", "MOUNTABLE", "FLAT_SURF", "WORKBENCH2" ], "deconstruct": { "items": [ { "item": "pipe", "count": [ 6, 12 ] }, @@ -5514,13 +5515,13 @@ "type": "furniture", "id": "f_workbench", "name": "workbench", - "description": "A sturdy workbench built out of durable metal and wood. It is perfect for crafting large and heavy things.", + "description": "A sturdy workbench built out of metal. It is perfect for crafting large and heavy things.", "symbol": "#", "color": "red", "move_cost_mod": 2, "required_str": -1, "looks_like": "f_lab_bench", - "flags": [ "TRANSPARENT", "PLACE_ITEM", "MOUNTABLE", "FLAT_SURF" ], + "flags": [ "TRANSPARENT", "PLACE_ITEM", "MOUNTABLE", "FLAT_SURF", "WORKBENCH3" ], "deconstruct": { "items": [ { "item": "pipe", "count": [ 6, 8 ] }, diff --git a/data/json/vehicle_parts.json b/data/json/vehicle_parts.json index 4d0e8d8d0d12b..12b58dc99a903 100644 --- a/data/json/vehicle_parts.json +++ b/data/json/vehicle_parts.json @@ -969,7 +969,7 @@ "item": "v_table", "difficulty": 1, "location": "center", - "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF" ], + "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF", "WORKBENCH1" ], "breaks_into": [ { "item": "2x4", "count": [ 1, 6 ] }, { "item": "splinter", "count": [ 4, 6 ] }, @@ -990,7 +990,7 @@ "item": "w_table", "difficulty": 1, "location": "center", - "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF" ], + "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF", "WORKBENCH1" ], "breaks_into": [ { "item": "2x4", "count": [ 1, 6 ] }, { "item": "splinter", "count": [ 4, 6 ] }, @@ -1012,7 +1012,7 @@ "item": "workbench", "difficulty": 1, "location": "center", - "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF" ], + "flags": [ "CARGO", "OBSTACLE", "TOOL_WRENCH", "FLAT_SURF", "WORKBENCH2" ], "breaks_into": [ { "item": "pipe", "count": [ 4, 6 ] }, { "item": "sheet_metal", "count": [ 0, 1 ] }, diff --git a/src/crafting.cpp b/src/crafting.cpp index 016838ba2db54..6d4bd8c8a81d7 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -15,6 +15,7 @@ #include "game_inventory.h" #include "inventory.h" #include "item.h" +#include "item_location.h" #include "itype.h" #include "map.h" #include "messages.h" @@ -27,6 +28,7 @@ #include "translations.h" #include "ui.h" #include "vehicle.h" +#include "vehicle_selector.h" #include "vpart_position.h" #include "vpart_reference.h" @@ -468,6 +470,55 @@ static item *set_item_inventory( player &p, item &newit ) return ret_val; } +/** + * Set an item on the map or in a vehicle and return the new location + * + */ +static item_location set_item_map_or_vehicle( const player &p, const tripoint &loc, item &newit ) +{ + if( const cata::optional vp = g->m.veh_at( loc ).part_with_feature( "CARGO", + false ) ) { + + if( vp->vehicle().add_item( vp->part_index(), newit ) ) { + + // Since add succeded, we know that the craft is the last item in the vehicle_stack + auto items_at_part = vp->vehicle().get_items( vp->part_index() ); + item *newit_in_vehicle = &items_at_part[items_at_part.size() - 1]; + + p.add_msg_player_or_npc( + string_format( pgettext( "item, furniture", "You put the %s on the %s" ), + newit.tname(), vp->part().name() ), + string_format( pgettext( "item, furniture", " puts the %s on the %s" ), + newit.tname(), vp->part().name() ) ); + + return item_location( vehicle_cursor( vp->vehicle(), vp->part_index() ), newit_in_vehicle ); + } + + // Couldn't add the in progress craft to the target part, so drop it to the map. + p.add_msg_player_or_npc( + string_format( pgettext( "furniture, item", + "Not enough space on the %s. You drop the %s on the ground." ), + vp->part().name(), newit.tname() ), + string_format( pgettext( "furniture, item", + "Not enough space on the %s. drops the %s on the ground" ), + vp->part().name(), newit.tname() ) ); + + return item_location( map_cursor( loc ), &g->m.add_item_or_charges( loc, newit ) ); + + } else { + if( g->m.has_furn( loc ) ) { + const furn_t &workbench = g->m.furn( loc ).obj(); + p.add_msg_player_or_npc( + string_format( pgettext( "item, furniture", "You put the %s on the %s" ), + newit.tname(), workbench.name() ), + string_format( pgettext( "item, furniture", " puts the %s on the %s" ), + newit.tname(), workbench.name() ) ); + } + + return item_location( map_cursor( loc ), &g->m.add_item_or_charges( loc, newit ) ); + } +} + static void return_all_components_for_craft( player &p, std::list &used, const double &relative_rot ) { @@ -515,37 +566,33 @@ void player::start_craft( const recipe &making, int batch_size, bool is_long, co item craft( &making, batch_size, used ); + item *craft_in_inventory = nullptr; + if( loc == tripoint_zero ) { - item *craft_in_inventory = set_item_inventory( *this, craft ); + + craft_in_inventory = set_item_inventory( *this, craft ); + if( !has_item( *craft_in_inventory ) ) { add_msg_if_player( _( "Activate the %s to start crafting" ), craft.tname() ); - } else { - add_msg_player_or_npc( - string_format( pgettext( "in progress craft", "You start working on the %s" ), - craft.tname() ), - string_format( pgettext( "in progress craft", " starts working on the %s" ), - craft.tname() ) ); - assign_activity( activity_id( "ACT_CRAFT" ) ); - activity.targets.push_back( item_location( *this, craft_in_inventory ) ); - activity.values.push_back( is_long ); + return; } + } + + assign_activity( activity_id( "ACT_CRAFT" ) ); + + if( craft_in_inventory ) { + activity.targets.push_back( item_location( *this, craft_in_inventory ) ); } else { - item *craft_on_map = &g->m.add_item_or_charges( loc, craft ); - const furn_t &workbench = g->m.furn( loc ).obj(); - add_msg_player_or_npc( - string_format( pgettext( "in progress craft", "You put the %s on the %s" ), - craft.tname(), workbench.name() ), - string_format( pgettext( "in progress craft", " puts the %s on the %s" ), - craft.tname(), workbench.name() ) ); - add_msg_player_or_npc( - string_format( pgettext( "in progress craft", "You start working on the %s" ), - craft.tname() ), - string_format( pgettext( "in progress craft", " starts working on the %s" ), - craft.tname() ) ); - assign_activity( activity_id( "ACT_CRAFT" ) ); - activity.targets.push_back( item_location( map_cursor( loc ), craft_on_map ) ); - activity.values.push_back( is_long ); + activity.targets.push_back( set_item_map_or_vehicle( *this, loc, craft ) ); } + + activity.values.push_back( is_long ); + + add_msg_player_or_npc( + string_format( pgettext( "in progress craft", "You start working on the %s" ), + craft.tname() ), + string_format( pgettext( "in progress craft", " starts working on the %s" ), + craft.tname() ) ); } void player::complete_craft( item &craft, const tripoint &loc ) @@ -805,7 +852,7 @@ void player::complete_craft( item &craft, const tripoint &loc ) if( loc == tripoint_zero ) { set_item_inventory( *this, newit ); } else { - g->m.add_item_or_charges( loc, newit ); + set_item_map_or_vehicle( *this, loc, newit ); } } @@ -827,7 +874,7 @@ void player::complete_craft( item &craft, const tripoint &loc ) if( loc == tripoint_zero ) { set_item_inventory( *this, bp ); } else { - g->m.add_item_or_charges( loc, bp ); + set_item_map_or_vehicle( *this, loc, bp ); } } } diff --git a/src/iexamine.cpp b/src/iexamine.cpp index d2bec909eef5d..5b4c02dc5a6d0 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -4504,7 +4504,7 @@ void iexamine::workbench( player &p, const tripoint &examp ) } } - amenu.text = string_format( pgettext( "furniture", "What to do with the %s?" ), + amenu.text = string_format( pgettext( "furniture", "What to do at the %s?" ), f_workbench.name() ); amenu.addentry( start_craft, true, '1', _( "Craft items" ) ); amenu.addentry( repeat_craft, true, '2', _( "Recraft last recipe" ) ); @@ -4548,7 +4548,7 @@ void iexamine::workbench( player &p, const tripoint &examp ) } } uilist amenu2( _( "Which craft to work on?" ), item_names ); - item *selected_craft = crafts[amenu2.ret].get_item(); + const item *selected_craft = crafts[amenu2.ret].get_item(); p.add_msg_player_or_npc( string_format( pgettext( "in progress craft", "You start working on the %s" ), @@ -4556,7 +4556,7 @@ void iexamine::workbench( player &p, const tripoint &examp ) string_format( pgettext( "in progress craft", " starts working on the %s" ), selected_craft->tname() ) ); p.assign_activity( activity_id( "ACT_CRAFT" ) ); - p.activity.targets.push_back( item_location( map_cursor( examp ), selected_craft ) ); + p.activity.targets.push_back( crafts[amenu2.ret].clone() ); p.activity.values.push_back( 0 ); // Not a long craft break; } diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index b7ce18b11b154..a9cdf50f0df56 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -812,7 +812,9 @@ bool veh_interact::do_install( std::string &msg ) part.has_flag( "BED" ) || part.has_flag( "SPACE_HEATER" ) || part.has_flag( "DOOR_MOTOR" ) || - part.has_flag( "WATER_PURIFIER" ); + part.has_flag( "WATER_PURIFIER" ) || + part.has_flag( "WORKBENCH1" ) || + part.has_flag( "WORKBENCH2" ); }; tab_filters[4] = [&]( const vpart_info * p ) { auto &part = *p; diff --git a/src/vehicle.h b/src/vehicle.h index 8b38963b342b5..3cb86e2715df3 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -1436,6 +1436,7 @@ class vehicle void use_washing_machine( int p ); void use_monster_capture( int part, const tripoint &pos ); void use_bike_rack( int part ); + void use_workbench( const int &part, const tripoint &pos ); veh_interact_results interact_with( const tripoint &pos, int interact_part ); diff --git a/src/vehicle_use.cpp b/src/vehicle_use.cpp index 024d9fb22dafb..15f56102a454d 100644 --- a/src/vehicle_use.cpp +++ b/src/vehicle_use.cpp @@ -46,6 +46,8 @@ static const fault_id fault_starter( "fault_engine_starter" ); const skill_id skill_mechanics( "mechanics" ); +static const trait_id trait_SHELL2( "SHELL2" ); + enum change_types : int { OPENCURTAINS = 0, OPENBOTH, @@ -1357,6 +1359,86 @@ void vehicle::use_bike_rack( int part ) } } +void vehicle::use_workbench( const int &part, const tripoint &pos ) +{ + const vehicle_part &workbench = parts[part]; + player &p = g->u; + + uilist amenu; + + enum option : int { + start_craft = 0, + repeat_craft, + start_long_craft, + work_on_craft + }; + + auto items_at_part = get_items( part ); + std::vector crafts; + for( item &it : items_at_part ) { + if( it.is_craft() ) { + crafts.emplace_back( item_location( vehicle_cursor( *this, part ), &it ) ); + } + } + + amenu.text = string_format( pgettext( "furniture", "What to do at the %s?" ), workbench.name() ); + amenu.addentry( start_craft, true, '1', _( "Craft items" ) ); + amenu.addentry( repeat_craft, true, '2', _( "Recraft last recipe" ) ); + amenu.addentry( start_long_craft, true, '3', _( "Craft as long as possible" ) ); + amenu.addentry( work_on_craft, !crafts.empty(), '4', _( "Work on craft" ) ); + + amenu.query(); + + option choice = static_cast