From 7fcbb87c570a66f162bfcc543728b6c50b0f9af5 Mon Sep 17 00:00:00 2001 From: PatrikLundell Date: Fri, 18 Dec 2020 06:28:04 +0100 Subject: [PATCH 01/10] Fixed base camp bb handling of multi line entries Co-authored-by: olanti-p --- src/mission_companion.cpp | 76 +++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index 5ea5899ee9ae..1a7760ef3ee8 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -377,6 +377,7 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr base_camps::tab_mode tab_mode = base_camps::TAB_MAIN; size_t sel = 0; + int name_offset = 0; // The following are for managing the right pane scrollbar. size_t info_offset = 0; @@ -432,6 +433,8 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr ui_adaptor ui; ui.on_screen_resize( [&]( ui_adaptor & ui ) { + name_offset = 0; + info_offset = 0; part_y = TERMY > FULL_SCREEN_HEIGHT ? ( TERMY - FULL_SCREEN_HEIGHT ) / 4 : 0; part_x = TERMX > FULL_SCREEN_WIDTH ? ( TERMX - FULL_SCREEN_WIDTH ) / 4 : 0; maxy = part_y ? TERMY - 2 * part_y : FULL_SCREEN_HEIGHT; @@ -460,51 +463,70 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr mvwprintz( w_list, point( 1, 1 ), c_white, name_mission_tabs( omt_pos, role_id, title, tab_mode ) ); - std::vector> folded_names; - size_t folded_names_lines = 0; - for( const auto &cur_key_entry : cur_key_list ) { - std::vector f_name = foldstring( cur_key_entry.name_display, MAX_FAC_NAME_SIZE - 5, - ' ' ); - folded_names_lines += f_name.size(); - folded_names.emplace_back( f_name ); - } + struct disp_entry { + std::vector lines; + nc_color col; + }; - int name_offset = 0; - calcStartPos( name_offset, sel, info_height, folded_names_lines ); + std::vector disp_names; + size_t folded_names_lines = 0; + for( size_t i = 0; i < cur_key_list.size(); i++ ) { + const mission_entry &e = cur_key_list[i]; + std::vector lines = foldstring( e.name_display, MAX_FAC_NAME_SIZE - 5, ' ' ); + nc_color col = i == sel ? h_white : c_white; - size_t list_line = 2; - for( size_t current = name_offset; list_line < info_height && - current < cur_key_list.size(); current++ ) { - nc_color col = ( current == sel ? h_white : c_white ); //highlight important missions for( const auto &k : mission_key.entries[0] ) { - if( cur_key_list[current].id == k.id ) { - col = ( current == sel ? h_white : c_yellow ); + if( e.id == k.id ) { + col = ( i == sel ? h_white : c_yellow ); break; } } //dull uncraftable items for( const auto &k : mission_key.entries[10] ) { - if( cur_key_list[current].id == k.id ) { - col = ( current == sel ? h_white : c_dark_gray ); + if( e.id == k.id ) { + col = ( i == sel ? h_white : c_dark_gray ); break; } } - std::vector &name_text = folded_names[current]; - for( size_t name_line = 0; name_line < name_text.size(); name_line++ ) { - print_colored_text( w_list, point( name_line ? 5 : 1, list_line ), - col, col, name_text[name_line] ); - list_line += 1; + + folded_names_lines += lines.size(); + disp_names.push_back( { lines, col } ); + } + + size_t sel_pos_min = 0; + for( size_t i = 0; i < sel; i++ ) { + sel_pos_min += disp_names[i].lines.size(); + } + size_t sel_pos_max = sel_pos_min + disp_names[sel].lines.size() - 1; + + // Make sure the selected entry is fully visible, + // and the cursor is positioned at 1st line of the entry. + calcStartPos( name_offset, sel_pos_max, info_height, folded_names_lines ); + calcStartPos( name_offset, sel_pos_min, info_height, folded_names_lines ); + + // Some entries may be shown only partially, + // but that's fine since it makes scrolling smoother. + int name_curr = 0; + int name_max = name_offset + static_cast( info_height ); + for( const disp_entry &e : disp_names ) { + for( size_t i = 0; i < e.lines.size() && name_curr < name_max; i++, name_curr++ ) { + if( name_curr < name_offset ) { + continue; + } + point p( i == 0 ? 1 : 5, name_curr - name_offset + 2 ); + nc_color col = e.col; + print_colored_text( w_list, p, col, col, e.lines[i] ); } } - if( cur_key_list.size() > info_height + 1 ) { + if( folded_names_lines > info_height ) { scrollbar() .offset_x( 0 ) .offset_y( 1 ) .content_size( folded_names_lines ) - .viewport_pos( sel ) - .viewport_size( info_height + 1 ) + .viewport_pos( name_offset ) + .viewport_size( info_height ) .apply( w_list ); } wnoutrefresh( w_list ); @@ -569,6 +591,7 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr info_offset++; } else if( action == "NEXT_TAB" && role_id == "FACTION_CAMP" ) { sel = 0; + name_offset = 0; info_offset = 0; do { @@ -582,6 +605,7 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr } while( cur_key_list.empty() ); } else if( action == "PREV_TAB" && role_id == "FACTION_CAMP" ) { sel = 0; + name_offset = 0; info_offset = 0; do { From 926aa033d5f3c0f0a09ac1be6e61ba09864b3e0f Mon Sep 17 00:00:00 2001 From: Kelenius Date: Wed, 2 Dec 2020 13:35:35 +0300 Subject: [PATCH 02/10] Removed spammed unnecessary messages --- src/bionics.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/bionics.cpp b/src/bionics.cpp index 1c325bd11c61..7613127142f5 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -1787,15 +1787,11 @@ int Character::bionics_pl_skill( const skill_id &most_important_skill, // Medical residents have some idea what they're doing if( has_trait( trait_PROF_MED ) ) { pl_skill += 3; - add_msg_player_or_npc( m_neutral, _( "You prep to begin surgery." ), - _( " prepares for surgery." ) ); } // People trained in bionics gain an additional advantage towards using it if( has_trait( trait_PROF_AUTODOC ) ) { pl_skill += 7; - add_msg( m_neutral, _( "A lifetime of augmentation has taught %s a thing or two…" ), - disp_name() ); } return pl_skill; } From b6a0b62b2a5a7aae16cb2344c500930267a4354d Mon Sep 17 00:00:00 2001 From: Aivean Date: Mon, 30 Nov 2020 20:35:02 -0800 Subject: [PATCH 03/10] fix issues with sound (walking on boats), sound triggering twice --- src/sdlsound.cpp | 5 ++++ src/sounds.cpp | 64 +++++++++++++++++++++++++++++++----------------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/sdlsound.cpp b/src/sdlsound.cpp index 2eda13a4e2f6..fccea7f6de75 100644 --- a/src/sdlsound.cpp +++ b/src/sdlsound.cpp @@ -24,6 +24,7 @@ #include "init.h" #include "json.h" #include "loading_ui.h" +#include "messages.h" #include "options.h" #include "path_info.h" #include "rng.h" @@ -442,6 +443,8 @@ static Mix_Chunk *do_pitch_shift( Mix_Chunk *s, float pitch ) void sfx::play_variant_sound( const std::string &id, const std::string &variant, int volume ) { + add_msg( m_debug, "sound id: %s, variant: %s, volume: %d ", id, variant, volume ); + if( !check_sound( volume ) ) { return; } @@ -466,6 +469,8 @@ void sfx::play_variant_sound( const std::string &id, const std::string &variant, void sfx::play_variant_sound( const std::string &id, const std::string &variant, int volume, int angle, double pitch_min, double pitch_max ) { + add_msg( m_debug, "sound id: %s, variant: %s, volume: %d ", id, variant, volume ); + if( !check_sound( volume ) ) { return; } diff --git a/src/sounds.cpp b/src/sounds.cpp index f1b2c8ee1ee8..1e7a245eeead 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -1401,39 +1401,55 @@ void sfx::do_footstep() static const std::set chain_fence = { ter_str_id( "t_chainfence" ), }; - if( !g->u.wearing_something_on( bp_foot_l ) ) { - play_variant_sound( "plmove", "walk_barefoot", heard_volume, 0, 0.8, 1.2 ); + + const auto play_plmove_sound_variant = [&]( const std::string & variant ) { + play_variant_sound( "plmove", variant, heard_volume, 0, 0.8, 1.2 ); start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + }; + + auto veh_displayed_part = g->m.veh_at( g->u.pos() ).part_displayed(); + + if( !veh_displayed_part && ( water.count( terrain ) > 0 ) ) { + play_plmove_sound_variant( "walk_water" ); return; - } else if( sfx::has_variant_sound( "plmove", terrain.str() ) ) { - play_variant_sound( "plmove", terrain.str(), heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( !g->u.wearing_something_on( body_part::bp_foot_l ) ) { + play_plmove_sound_variant( "walk_barefoot" ); return; - } else if( grass.count( terrain ) > 0 ) { - play_variant_sound( "plmove", "walk_grass", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( veh_displayed_part ) { + const std::string &part_id = veh_displayed_part->part().info().get_id().str(); + if( has_variant_sound( "plmove", part_id ) ) { + play_plmove_sound_variant( part_id ); + } else if( veh_displayed_part->has_feature( VPFLAG_AISLE ) ) { + play_plmove_sound_variant( "walk_tarmac" ); + } else { + play_plmove_sound_variant( "clear_obstacle" ); + } return; - } else if( dirt.count( terrain ) > 0 ) { - play_variant_sound( "plmove", "walk_dirt", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( sfx::has_variant_sound( "plmove", terrain.str() ) ) { + play_plmove_sound_variant( terrain.str() ); return; - } else if( metal.count( terrain ) > 0 ) { - play_variant_sound( "plmove", "walk_metal", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( grass.count( terrain ) > 0 ) { + play_plmove_sound_variant( "walk_grass" ); return; - } else if( water.count( terrain ) > 0 ) { - play_variant_sound( "plmove", "walk_water", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( dirt.count( terrain ) > 0 ) { + play_plmove_sound_variant( "walk_dirt" ); return; - } else if( chain_fence.count( terrain ) > 0 ) { - play_variant_sound( "plmove", "clear_obstacle", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( metal.count( terrain ) > 0 ) { + play_plmove_sound_variant( "walk_metal" ); return; - } else { - play_variant_sound( "plmove", "walk_tarmac", heard_volume, 0, 0.8, 1.2 ); - start_sfx_timestamp = std::chrono::high_resolution_clock::now(); + } + if( chain_fence.count( terrain ) > 0 ) { + play_plmove_sound_variant( "clear_obstacle" ); return; } + + play_plmove_sound_variant( "walk_tarmac" ); } } @@ -1458,6 +1474,8 @@ void sfx::do_obstacle( const std::string &obst ) } else { play_variant_sound( "plmove", "clear_obstacle", heard_volume, 0, 0.8, 1.2 ); } + // prevent footsteps from triggering + start_sfx_timestamp = std::chrono::high_resolution_clock::now(); } void sfx::play_activity_sound( const std::string &id, const std::string &variant, int volume ) From 45bbee4d0bdd90a90159cfdd405faeeee5b5f1da Mon Sep 17 00:00:00 2001 From: Thomas Wisneski Date: Mon, 7 Dec 2020 02:38:01 -0600 Subject: [PATCH 04/10] Fixed extinguishing items on boats --- src/item.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/item.cpp b/src/item.cpp index 7b36c4f2b81c..c9b64238a97b 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -8727,6 +8727,7 @@ bool item::process_extinguish( player *carrier, const tripoint &pos ) bool submerged = false; bool precipitation = false; bool windtoostrong = false; + bool in_veh = carrier != nullptr && carrier->in_vehicle; w_point weatherPoint = *g->weather.weather_precise; int windpower = g->weather.windspeed; switch( g->weather.weather ) { @@ -8749,11 +8750,11 @@ bool item::process_extinguish( player *carrier, const tripoint &pos ) default: break; } - if( in_inv && g->m.has_flag( flag_DEEP_WATER, pos ) ) { + if( in_inv && !in_veh && g->m.has_flag( flag_DEEP_WATER, pos ) ) { extinguish = true; submerged = true; } - if( ( !in_inv && g->m.has_flag( flag_LIQUID, pos ) ) || + if( ( !in_inv && g->m.has_flag( flag_LIQUID, pos ) && !g->m.veh_at( pos ) ) || ( precipitation && !g->is_sheltered( pos ) ) ) { extinguish = true; } From bc6f0263700480a90374581ac4a38068cc202aae Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Tue, 8 Dec 2020 16:53:03 -0800 Subject: [PATCH 05/10] Gate 3+ engines behind DEBUG_HS It's not intended that a survivor can install more than 2 engines in a vehicle, yet it is still useful to be able to install more than 2 engines for vehicle creation. Additionally, it was often asked how to get to mechanics 12, an effectively impossible task, but still show for the install requirements for 2+ engines. As such, require debug hammerspace to install more than 2 engines or display the skills need to install more engines. The skills don't mean anything after 2 engines, but it's easier to leave them there, and there is no harm in doing so. --- src/veh_interact.cpp | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index 1f3566cbc691..16eab0358d67 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -725,14 +725,23 @@ bool veh_interact::update_part_requirements() std::string additional_requirements; bool lifting_or_jacking_required = false; + bool allow_more_eng = engines < 2 || g->u.has_trait( trait_DEBUG_HS ); + if( dif_eng > 0 ) { - if( g->u.get_skill_level( skill_mechanics ) < dif_eng ) { + if( !allow_more_eng || g->u.get_skill_level( skill_mechanics ) < dif_eng ) { ok = false; } - //~ %1$s represents the internal color name which shouldn't be translated, %2$s is skill name, and %3$i is skill level - additional_requirements += string_format( _( "> %1$s%2$s %3$i for extra engines." ), - status_color( g->u.get_skill_level( skill_mechanics ) >= dif_eng ), - skill_mechanics.obj().name(), dif_eng ) + "\n"; + if( allow_more_eng ) { + //~ %1$s represents the internal color name which shouldn't be translated, %2$s is skill name, and %3$i is skill level + additional_requirements += string_format( _( "> %1$s%2$s %3$i for extra engines." ), + status_color( g->u.get_skill_level( skill_mechanics ) >= dif_eng ), + skill_mechanics.obj().name(), dif_eng ) + "\n"; + } else { + additional_requirements += + _( "> You cannot install any more engines on this vehicle." ) + + std::string( "\n" ); + } + } if( dif_steering > 0 ) { @@ -1994,8 +2003,22 @@ int veh_interact::part_at( const point &d ) */ bool veh_interact::can_potentially_install( const vpart_info &vpart ) { - return g->u.has_trait( trait_DEBUG_HS ) || - vpart.install_requirements().can_make_with_inventory( crafting_inv, is_crafting_component ); + bool engine_reqs_met = true; + bool can_make = vpart.install_requirements().can_make_with_inventory( crafting_inv, + is_crafting_component ); + bool hammerspace = g->u.has_trait( trait_DEBUG_HS ); + + int engines = 0; + if( vpart.has_flag( VPFLAG_ENGINE ) && vpart.has_flag( "E_HIGHER_SKILL" ) ) { + for( const vpart_reference &vp : veh->get_avail_parts( "ENGINE" ) ) { + if( vp.has_feature( "E_HIGHER_SKILL" ) ) { + engines++; + } + } + engine_reqs_met = engines < 2; + } + + return hammerspace || ( can_make && engine_reqs_met ); } /** From 3e837a6d0edadb6468984d69810fb5f1b0e18da5 Mon Sep 17 00:00:00 2001 From: satheon49 <75445240+satheon49@users.noreply.github.com> Date: Sun, 13 Dec 2020 07:46:22 +0100 Subject: [PATCH 06/10] Keep AIM panels while moving items --- src/advanced_inv_pane.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/advanced_inv_pane.cpp b/src/advanced_inv_pane.cpp index 96eec42f05dd..ec7698be052d 100644 --- a/src/advanced_inv_pane.cpp +++ b/src/advanced_inv_pane.cpp @@ -35,7 +35,8 @@ void advanced_inventory_pane::save_settings() void advanced_inventory_pane::load_settings( int saved_area_idx, const std::array &squares, bool is_re_enter ) { - const int i_location = ( get_option( "OPEN_DEFAULT_ADV_INV" ) ) ? saved_area_idx : + const int i_location = ( get_option( "OPEN_DEFAULT_ADV_INV" ) && + !is_re_enter ) ? saved_area_idx : save_state->area_idx; const aim_location location = static_cast( i_location ); auto square = squares[location]; From 0bc37ff3dfe65630a6119e02bdba2ff9a912db9e Mon Sep 17 00:00:00 2001 From: satheon49 <75445240+satheon49@users.noreply.github.com> Date: Fri, 18 Dec 2020 06:37:26 +0100 Subject: [PATCH 07/10] Allow chargeless firestarters to interact with furniture * allow chargeless firestarters to interact with furniture * have firestarter use function decide if fire can be started * keep checking charges for charged firestarters --- src/character.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/character.cpp b/src/character.cpp index 53a08db40e63..abbea2c9a787 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -9328,7 +9328,13 @@ bool Character::has_fire( const int quantity ) const } else if( has_item_with_flag( "FIRESTARTER" ) ) { auto firestarters = all_items_with_flag( "FIRESTARTER" ); for( auto &i : firestarters ) { - if( has_charges( i->typeId(), quantity ) ) { + if( !i->type->can_have_charges() ) { + const use_function *usef = i->type->get_use( "firestarter" ); + const firestarter_actor *actor = dynamic_cast( usef->get_actor_ptr() ); + if( actor->can_use( *this->as_character(), *i, false, tripoint_zero ).success() ) { + return true; + } + } else if( has_charges( i->typeId(), quantity ) ) { return true; } } From 745aa70d5223b2315e1c267ab3b0d770be9e4f56 Mon Sep 17 00:00:00 2001 From: ZigVert <56202842+Daved27hundred@users.noreply.github.com> Date: Sun, 20 Dec 2020 02:38:28 -0500 Subject: [PATCH 08/10] uninstalling a tied mattress no longer requires hacksaw --- data/json/vehicleparts/rams.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/json/vehicleparts/rams.json b/data/json/vehicleparts/rams.json index 54b38b727b82..78c8fb7b54d3 100644 --- a/data/json/vehicleparts/rams.json +++ b/data/json/vehicleparts/rams.json @@ -165,7 +165,10 @@ "durability": 40, "description": "A mattress, strapped onto the vehicle. It could serve to blunt any impact.", "breaks_into": [ { "item": "rag", "count": [ 40, 55 ] } ], - "requirements": { "install": { "skills": [ [ "mechanics", 0 ] ], "time": "5 m", "using": [ [ "rope_natural_short", 2 ] ] } }, + "requirements": { + "install": { "skills": [ [ "mechanics", 0 ] ], "time": "5 m", "using": [ [ "rope_natural_short", 2 ] ] }, + "removal": { "skills": [ [ "mechanics", 0 ] ], "time": "5 m", "using": [ ] } + }, "damage_reduction": { "bash": 20 }, "flags": [ "PROTRUSION", "OBSTACLE", "OPAQUE" ] }, From 66ee906a69be5da65c9a39819c2e8f992fa67de9 Mon Sep 17 00:00:00 2001 From: Kevin Granade Date: Fri, 18 Dec 2020 23:55:38 -0800 Subject: [PATCH 09/10] Stop friendly animals from stealing food from under the player's nose --- src/monattack.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/monattack.cpp b/src/monattack.cpp index 65e70df4fa09..014a5d7ec608 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -317,6 +317,10 @@ bool mattack::eat_food( monster *z ) if( g->m.has_flag( "PLANT", p ) ) { continue; } + // Don't snap up food RIGHT under the player's nose. + if( z->friendly && rl_dist( g->u.pos(), p ) <= 2 ) { + continue; + } auto items = g->m.i_at( p ); for( auto &item : items ) { //Fun limit prevents scavengers from eating feces From 306de96d1b8d4eb34ea0983dd8afa5b25033df43 Mon Sep 17 00:00:00 2001 From: anothersimulacrum Date: Sat, 14 Nov 2020 11:59:13 -0800 Subject: [PATCH 10/10] Apply migrations to more jmapgens jmapgen_spawn_item and jmapgen_liquid_item did not migrate items passed to them. This showed up when spawning in a rural gas station with generic guns, a shotgun and shot for it would be spawned, but not migrated to the generic guns versions. Migrate those now. --- src/mapgen.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index ca93b36131d7..3b7754084a16 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1111,6 +1111,9 @@ class jmapgen_liquid_item : public jmapgen_piece amount( jsi, "amount", 0, 0 ) , liquid( jsi.get_string( "liquid" ) ) , chance( jsi, "chance", 1, 1 ) { + // Itemgroups apply migrations when being loaded, but we need to migrate + // individual items here. + liquid = item_controller->migrate_id( itype_id( liquid ) ); if( !item::type_is_defined( itype_id( liquid ) ) ) { set_mapgen_defer( jsi, "liquid", "no such item type '" + liquid + "'" ); } @@ -1389,6 +1392,9 @@ class jmapgen_spawn_item : public jmapgen_piece type( jsi.get_string( "item" ) ) , amount( jsi, "amount", 1, 1 ) , chance( jsi, "chance", 100, 100 ) { + // Itemgroups apply migrations when being loaded, but we need to migrate + // individual items here. + type = item_controller->migrate_id( type ); if( !item::type_is_defined( type ) ) { set_mapgen_defer( jsi, "item", "no such item" ); }