2
2
3
3
#include " activity_handlers.h"
4
4
#include " cata_catch.h"
5
+ #include " flag.h"
5
6
#include " item.h"
6
7
#include " itype.h"
7
8
#include " iuse_actor.h"
17
18
18
19
static const activity_id ACT_REPAIR_ITEM ( " ACT_REPAIR_ITEM" );
19
20
21
+ static const itype_id itype_backpack ( " backpack" );
22
+ static const itype_id itype_can_drink ( " can_drink" );
23
+ static const itype_id itype_canvas_patch ( " canvas_patch" );
20
24
static const itype_id itype_leather ( " leather" );
21
25
static const itype_id itype_tailors_kit ( " tailors_kit" );
26
+ static const itype_id itype_technician_shirt_gray ( " technician_shirt_gray" );
22
27
static const itype_id itype_test_baseball ( " test_baseball" );
23
28
static const itype_id itype_test_baseball_half_degradation ( " test_baseball_half_degradation" );
24
29
static const itype_id itype_test_baseball_x2_degradation ( " test_baseball_x2_degradation" );
@@ -221,22 +226,28 @@ TEST_CASE( "Items_that_get_damaged_gain_degradation", "[item][degradation]" )
221
226
}
222
227
}
223
228
224
- static void setup_repair ( item &fix, player_activity &act, Character &u )
229
+ static item_location setup_tailorkit ( Character &u )
225
230
{
226
231
map &m = get_map ();
232
+ const tripoint_bub_ms pos = spawn_pos;
233
+ item &thread = m.add_item_or_charges ( pos, item ( itype_thread ) );
234
+ item &tailor = m.add_item_or_charges ( pos, item ( itype_tailors_kit ) );
235
+ thread.charges = 400 ;
236
+ tailor.reload ( u, { map_cursor ( pos ), &thread }, 400 );
237
+ REQUIRE ( m.i_at ( spawn_pos ).begin ()->typeId () == tailor.typeId () );
238
+ return item_location ( map_cursor ( pos ), &tailor );
239
+ }
227
240
241
+ static void setup_repair ( item &fix, player_activity &act, Character &u )
242
+ {
228
243
// Setup character
229
244
clear_character ( u, true );
230
245
u.set_skill_level ( skill_tailor, 10 );
231
246
u.wield ( fix );
232
247
REQUIRE ( u.get_wielded_item ()->typeId () == fix.typeId () );
233
248
234
249
// Setup tool
235
- item &thread = m.add_item_or_charges ( spawn_pos, item ( itype_thread ) );
236
- item &tailor = m.add_item_or_charges ( spawn_pos, item ( itype_tailors_kit ) );
237
- thread.charges = 400 ;
238
- tailor.reload ( u, { map_cursor ( tripoint_bub_ms ( spawn_pos ) ), &thread }, 400 );
239
- REQUIRE ( m.i_at ( spawn_pos ).begin ()->typeId () == tailor.typeId () );
250
+ item_location tailorloc = setup_tailorkit ( u );
240
251
241
252
// Setup materials
242
253
item leather ( itype_leather );
@@ -245,7 +256,6 @@ static void setup_repair( item &fix, player_activity &act, Character &u )
245
256
246
257
// Setup activity
247
258
item_location fixloc ( u, &fix );
248
- item_location tailorloc ( map_cursor ( tripoint_bub_ms ( spawn_pos ) ), &tailor );
249
259
act.values .emplace_back ( /* repeat_type::FULL */ 3 );
250
260
act.str_values .emplace_back ( " repair_fabric" );
251
261
act.targets .emplace_back ( tailorloc );
@@ -628,3 +638,67 @@ TEST_CASE( "Gun_repair_with_degradation", "[item][degradation]" )
628
638
}
629
639
}
630
640
}
641
+
642
+ static player_activity setup_repair_activity ( item_location &tailorloc, item_location &fixloc )
643
+ {
644
+ player_activity act ( ACT_REPAIR_ITEM );
645
+ act.values .emplace_back ( /* repeat_type::FULL */ 3 );
646
+ act.str_values .emplace_back ( " repair_fabric" );
647
+ act.targets .emplace_back ( tailorloc );
648
+ act.targets .emplace_back ( fixloc );
649
+ return act;
650
+ }
651
+
652
+ static item_location put_in_container ( item_location &container, const itype_id &type )
653
+ {
654
+ ret_val<item *> inserted = container->get_contents ().insert_item ( item ( type ),
655
+ pocket_type::CONTAINER );
656
+ REQUIRE ( inserted.success () );
657
+ return item_location ( container, inserted.value () );
658
+ }
659
+
660
+ // Reproduce previous segfault from https://github.com/CleverRaven/Cataclysm-DDA/issues/74254
661
+ TEST_CASE ( " refit_item_inside_spillable_container" , " [item][repair][container]" )
662
+ {
663
+ clear_avatar ();
664
+ clear_map ();
665
+ set_time_to_day ();
666
+ REQUIRE ( static_cast <int >( get_map ().light_at ( spawn_pos.raw () ) ) > 2 );
667
+
668
+ Character &u = get_player_character ();
669
+ u.set_skill_level ( skill_tailor, 10 );
670
+
671
+ // Setup starting equipment
672
+ item_location tailorkit = setup_tailorkit ( u );
673
+ REQUIRE ( u.wear_item ( item ( itype_backpack ) ) );
674
+ item_location backpack = u.top_items_loc ().front ();
675
+ item canvas_patch ( itype_canvas_patch );
676
+ u.i_add_or_drop ( canvas_patch, 100 );
677
+
678
+ // Starting inventory looks like:
679
+ // backpack >
680
+ // 100 canvas patch
681
+ // aluminum can >
682
+ // work t-shirt (poor fit)
683
+ // It's a bit odd that we can put the shirt into the aluminum can, since it
684
+ // would normally reject that with a message stating that it would spill.
685
+ GIVEN ( " backpack > aluminum can > work t-shirt (poor fit)" ) {
686
+ item_location aluminum_can = put_in_container ( backpack, itype_can_drink );
687
+ item_location fix_tshirt = put_in_container ( aluminum_can, itype_technician_shirt_gray );
688
+ WHEN ( " Refitting tshirt inside spillable container" ) {
689
+ REQUIRE_FALSE ( fix_tshirt->has_flag ( flag_FIT ) );
690
+ player_activity act = setup_repair_activity ( tailorkit, fix_tshirt );
691
+ while ( !act.is_null () ) {
692
+ ::repair_item_finish ( &act, &u, true );
693
+ }
694
+ THEN ( " tshirt should be refitted successfully" ) {
695
+ const item *refitted_tshirt = backpack->get_item_with ( [&]( const item & i ) {
696
+ return i.typeId () == itype_technician_shirt_gray;
697
+ } );
698
+ REQUIRE ( refitted_tshirt != nullptr );
699
+ CHECK ( refitted_tshirt->has_flag ( flag_FIT ) );
700
+ }
701
+ }
702
+
703
+ }
704
+ }
0 commit comments