From e4a2888d097871e91e30bde6eef5ad8b267b602b Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Thu, 11 Apr 2019 03:48:37 +0200 Subject: [PATCH] Add simple workbench crafting bonus - plus various small fixes and tweaks --- data/json/items/vehicle_parts.json | 2 +- data/json/vehicleparts/vp_flags.json | 18 +++++++++ src/activity_handlers.cpp | 9 ++--- src/crafting.cpp | 55 ++++++++++++++++++++++++++-- src/game.cpp | 2 +- src/mapdata.h | 2 + src/player.h | 6 ++- 7 files changed, 81 insertions(+), 13 deletions(-) diff --git a/data/json/items/vehicle_parts.json b/data/json/items/vehicle_parts.json index 15025faa76dca..e3d83725790f3 100644 --- a/data/json/items/vehicle_parts.json +++ b/data/json/items/vehicle_parts.json @@ -215,7 +215,7 @@ "type": "GENERIC", "id": "workbench", "name": "workbench", - "description": "A crude wooden table.", + "description": "A sturdy workbench built out of metal. It is perfect for crafting large and heavy things.", "weight": 23000, "to_hit": -8, "color": "red", diff --git a/data/json/vehicleparts/vp_flags.json b/data/json/vehicleparts/vp_flags.json index be8bec45bed1a..5f4f213028ee8 100644 --- a/data/json/vehicleparts/vp_flags.json +++ b/data/json/vehicleparts/vp_flags.json @@ -148,5 +148,23 @@ "type": "json_flag", "context": [ "vehicle_part" ], "info": "If the center of balance of your vehicle is between all the wheels, the vehicle will be able to move, provided it has an active engine or motor with enough power to move the vehicle." + }, + { + "id": "FLAT_SURF", + "type": "json_flag", + "context": [ "vehicle_part" ], + "info": "This has a flat surface. It would be a nice place to eat." + }, + { + "id": "WORKBENCH1", + "type": "json_flag", + "context": [ "vehicle_part" ], + "info": "You can craft here, though a proper workbench would be better." + }, + { + "id": "WORKBENCH2", + "type": "json_flag", + "context": [ "vehicle_part" ], + "info": "A sturdy metal workbench bolted in place. This is a good place to craft, though crafting in a vehicle is still a little cramped." } ] diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 20a85ff06e560..e632f9cd8b142 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -2653,7 +2653,9 @@ void activity_handlers::craft_do_turn( player_activity *act, player *p ) } const recipe &rec = craft->get_making(); - const float crafting_speed = p->crafting_speed_multiplier( rec, true ); + const tripoint loc = act->targets.front().where() == item_location::type::character ? + tripoint_zero : act->targets.front().position(); + const float crafting_speed = p->crafting_speed_multiplier( rec, true, loc ); const bool is_long = act->values[0]; if( crafting_speed <= 0.0f ) { @@ -2676,7 +2678,7 @@ void activity_handlers::craft_do_turn( player_activity *act, player *p ) // Base moves for batch size with no speed modifier or assistants const double base_total_moves = rec.batch_time( craft->charges, 1.0f, 0 ); // Current expected total moves, includes crafting speed modifiers and assistants - const double cur_total_moves = p->expected_time_to_craft( rec, craft->charges ); + const double cur_total_moves = p->expected_time_to_craft( rec, craft->charges, true, loc ); // Delta progress in moves adjusted for current crafting speed const double delta_progress = p->get_moves() * base_total_moves / cur_total_moves; // Current progress in moves @@ -2688,9 +2690,6 @@ void activity_handlers::craft_do_turn( player_activity *act, player *p ) // if item_counter has reached 100% or more if( craft->item_counter >= 10000 ) { item craft_copy = *craft; - const tripoint loc = act->targets.front().where() == item_location::type::character ? - tripoint_zero : - act->targets.front().position(); act->targets.front().remove_item(); p->cancel_activity(); p->complete_craft( craft_copy, loc ); diff --git a/src/crafting.cpp b/src/crafting.cpp index 6d4bd8c8a81d7..c50879dc89be1 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -110,9 +110,55 @@ float player::morale_crafting_speed_multiplier( const recipe &rec ) const return 1.0f / morale_effect; } -float player::crafting_speed_multiplier( const recipe &rec, bool in_progress ) const +static float workbench_crafting_speed_multiplier( const tripoint &loc ) { - float result = morale_crafting_speed_multiplier( rec ) * lighting_craft_speed_multiplier( rec ); + // tripoint_zero indicates crafting from inventory, so no effect + if( loc == tripoint_zero ) { + return 1.0f; + } + + int workbench_level = 0; + + if( const optional_vpart_position vp = g->m.veh_at( loc ) ) { + const point loc_point( loc.x, loc.y ); + if( vp->vehicle().avail_part_with_feature( loc_point, "WORKBENCH1", true ) ) { + workbench_level = 1; + } else if( vp->vehicle().avail_part_with_feature( loc_point, "WORKBENCH2", true ) ) { + workbench_level = 2; + } + } else { + if( g->m.has_flag_furn( "WORKBENCH1", loc ) ) { + workbench_level = 1; + } else if( g->m.has_flag_furn( "WORKBENCH2", loc ) ) { + workbench_level = 2; + } else if( g->m.has_flag_furn( "WORKBENCH3", loc ) ) { + workbench_level = 3; + } + } + + switch( workbench_level ) { + case 3: { + return 1.2f; + } + case 2: { + return 1.1f; + } + case 1: { + return 1.0f; + } + default: { + // If there is no workbench impose a 10% penalty + return 0.9f; + } + } +} + +float player::crafting_speed_multiplier( const recipe &rec, bool in_progress, + const tripoint &loc ) const +{ + float result = morale_crafting_speed_multiplier( rec ) * + lighting_craft_speed_multiplier( rec ) * + workbench_crafting_speed_multiplier( loc ); // Can't start if we'd need 300% time, but we can still finish the job if( !in_progress && result < 0.33f ) { return 0.0f; @@ -196,10 +242,11 @@ int player::base_time_to_craft( const recipe &rec, int batch_size ) const return rec.batch_time( batch_size, 1.0f, assistants ); } -int player::expected_time_to_craft( const recipe &rec, int batch_size ) const +int player::expected_time_to_craft( const recipe &rec, int batch_size, bool in_progress, + const tripoint &loc ) const { const size_t assistants = available_assistant_count( *this, rec ); - float modifier = crafting_speed_multiplier( rec ); + float modifier = crafting_speed_multiplier( rec, in_progress, loc ); return rec.batch_time( batch_size, modifier, assistants ); } diff --git a/src/game.cpp b/src/game.cpp index eb134ad312346..fbde4894b6203 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3187,7 +3187,7 @@ void game::debug() #if defined(TILES) const point offset { POSX - u.posx() + u.view_offset.x, - POSY - u.posy() + u.view_offset.y + POSY - u.posy() + u.view_offset.y }; draw_ter(); auto sounds_to_draw = sounds::get_monster_sounds(); diff --git a/src/mapdata.h b/src/mapdata.h index 170f7d4cea269..b7b42d76f71de 100644 --- a/src/mapdata.h +++ b/src/mapdata.h @@ -122,6 +122,8 @@ struct map_deconstruct_info { * * Furniture only: * BLOCKSDOOR - This will boost map terrain's resistance to bashing if str_*_blocked is set (see map_bash_info) + * FLAT_SURF - This is required for full butchery and gives a morale bonus while eating. + * WORKBENCH1/WORKBENCH2/WORKBENCH3 - This is an adequate/good/great workbench for crafting. Should be paired with a workbench iexamine. */ /* diff --git a/src/player.h b/src/player.h index 09ba8fbdb5ce1..a44ba34ed25e2 100644 --- a/src/player.h +++ b/src/player.h @@ -1370,7 +1370,8 @@ class player : public Character // crafting.cpp float morale_crafting_speed_multiplier( const recipe &rec ) const; float lighting_craft_speed_multiplier( const recipe &rec ) const; - float crafting_speed_multiplier( const recipe &rec, bool in_progress = false ) const; + float crafting_speed_multiplier( const recipe &rec, bool in_progress = false, + const tripoint &loc = tripoint_zero ) const; /** * Time to craft not including speed multiplier */ @@ -1378,7 +1379,8 @@ class player : public Character /** * Expected time to craft a recipe, with assumption that multipliers stay constant. */ - int expected_time_to_craft( const recipe &rec, int batch_size = 1 ) const; + int expected_time_to_craft( const recipe &rec, int batch_size = 1, bool in_progress = false, + const tripoint &loc = tripoint_zero ) const; std::vector get_eligible_containers_for_crafting() const; bool check_eligible_containers_for_crafting( const recipe &rec, int batch_size = 1 ) const; bool has_morale_to_craft() const;