void monster::debug(player &u) { debugmsg("monster::debug %s has %d steps planned.", name().c_str(), plans.size()); debugmsg("monster::debug %s Moves %d Speed %d HP %d",name().c_str(), moves, get_speed(), hp); for (size_t i = 0; i < plans.size(); i++) { const int digit = '0' + (i % 10); mvaddch(plans[i].y - SEEY + u.posy(), plans[i].x - SEEX + u.posx(), digit); } getch(); }
bool ma_requirements::is_valid_player(player &u) { for( auto buff_id : req_buffs ) { if (!u.has_mabuff(buff_id)) { return false; } } //A technique is valid if it applies to unarmed strikes, if it applies generally //to all weapons (such as Ninjutsu sneak attacks or innate weapon techniques like RAPID) //or if the weapon is flagged as being compatible with the style. Some techniques have //further restrictions on required weapon properties (is_valid_weapon). bool cqb = u.has_active_bionic("bio_cqb"); bool valid = ((unarmed_allowed && u.unarmed_attack()) || (melee_allowed && !u.unarmed_attack() && is_valid_weapon(u.weapon)) || (u.has_weapon() && martialarts[u.style_selected].has_weapon(u.weapon.type->id) && is_valid_weapon(u.weapon))) && ((u.skillLevel("melee") >= min_melee && u.skillLevel("unarmed") >= min_unarmed && u.skillLevel("bashing") >= min_bashing && u.skillLevel("cutting") >= min_cutting && u.skillLevel("stabbing") >= min_stabbing) || cqb); return valid; }
void put_into_vehicle( player &p, const std::list<item> &items, vehicle &veh, int part ) { if( items.empty() ) { return; } const tripoint where = veh.global_part_pos3( part ); const std::string ter_name = g->m.name( where ); int fallen_count = 0; for( auto it : items ) { // cant use constant reference here because of the spill_contents() if( it.is_bucket_nonempty() && !it.spill_contents( p ) ) { p.add_msg_player_or_npc( _( "To avoid spilling its contents, you set your %1$s on the %2$s." ), _( "To avoid spilling its contents, <npcname> sets their %1$s on the %2$s." ), it.display_name().c_str(), ter_name.c_str() ); g->m.add_item_or_charges( where, it ); continue; } if( !veh.add_item( part, it ) ) { if( it.count_by_charges() ) { // Maybe we can add a few charges in the trunk and the rest on the ground. it.mod_charges( -veh.add_charges( part, it ) ); } g->m.add_item_or_charges( where, it ); ++fallen_count; } } const std::string part_name = veh.part_info( part ).name(); if( same_type( items ) ) { const item &it = items.front(); const int dropcount = items.size() * ( it.count_by_charges() ? it.charges : 1 ); p.add_msg_player_or_npc( ngettext( "You put your %1$s in the %2$s's %3$s.", "You put your %1$s in the %2$s's %3$s.", dropcount ), ngettext( "<npcname> puts their %1$s in the %2$s's %3$s.", "<npcname> puts their %1$s in the %2$s's %3$s.", dropcount ), it.tname( dropcount ).c_str(), veh.name.c_str(), part_name.c_str() ); } else { p.add_msg_player_or_npc( _( "You put several items in the %1$s's %2$s." ), _( "<npcname> puts several items in the %1$s's %2$s." ), veh.name.c_str(), part_name.c_str() ); } if( fallen_count > 0 ) { add_msg( m_warning, _( "The trunk is full, so some items fell to the %s." ), ter_name.c_str() ); } }
int monster::hit(game *g, player &p, body_part &bp_hit) { int numdice = type->melee_skill; if (dice(numdice, 10) <= dice(p.dodge(g), 10) && !one_in(20)) { if (numdice > p.sklevel[sk_dodge]) p.practice(sk_dodge, 10); return 0; // We missed! } p.practice(sk_dodge, 5); int ret = 0; int highest_hit; switch (type->size) { case MS_TINY: highest_hit = 3; break; case MS_SMALL: highest_hit = 12; break; case MS_MEDIUM: highest_hit = 20; break; case MS_LARGE: highest_hit = 28; break; case MS_HUGE: highest_hit = 35; break; } if (has_flag(MF_DIGS)) highest_hit -= 8; if (has_flag(MF_FLIES)) highest_hit += 20; if (highest_hit <= 1) highest_hit = 2; if (highest_hit > 20) highest_hit = 20; int bp_rand = rng(0, highest_hit - 1); if (bp_rand <= 2) bp_hit = bp_legs; else if (bp_rand <= 10) bp_hit = bp_torso; else if (bp_rand <= 14) bp_hit = bp_arms; else if (bp_rand <= 16) bp_hit = bp_mouth; else if (bp_rand == 17) bp_hit = bp_eyes; else bp_hit = bp_head; ret += dice(type->melee_dice, type->melee_sides); return ret; }
bool player_can_build( player &p, const inventory &pinv, const construction &con ) { if( p.has_trait( "DEBUG_HS" ) ) { return true; } if( p.get_skill_level( con.skill ) < con.difficulty ) { return false; } return con.requirements->can_make_with_inventory( pinv ); }
item_location game::get_item_from_inventory( player &p, const std::string &title ) { const std::string msg = p.is_npc() ? string_format( _( "%s's inventory is empty." ), p.name.c_str() ) : std::string( _( "Your inventory is empty." ) ); return inv_internal( p, inventory_filter_preset( convert_filter( [ &p ]( const item & it ) { return !p.is_worn( it ) && &p.weapon != ⁢ } ) ), title, -1, msg ); }
void test_consumable_ammo( player &p, std::string &itemname, bool when_empty, bool when_full ) { item it = item( itemname, 0, 0 ) ; it.ammo_unset(); INFO( "consume \'" + it.tname() + "\' with " + std::to_string( it.ammo_remaining() ) + " charges" ); REQUIRE( p.can_consume( it ) == when_empty ); it.ammo_set( it.ammo_type()->default_ammotype(), -1 ); // -1 -> full INFO( "consume \'" + it.tname() + "\' with " + std::to_string( it.ammo_remaining() ) + " charges" ); REQUIRE( p.can_consume( it ) == when_full ); }
void pick_up_from_feet( player &p, int pos ) { auto size_before = g->m.i_at( p.pos() ).size(); REQUIRE( size_before > pos ); p.moves = 100; p.assign_activity( activity_id( "ACT_PICKUP" ) ); p.activity.placement = tripoint(0, 0, 0); p.activity.values.push_back( false ); // not from vehicle p.activity.values.push_back( pos ); // index of item to pick up p.activity.values.push_back( 0 ); p.activity.do_turn( p ); REQUIRE( g->m.i_at( p.pos() ).size() == size_before - 1 ); }
int fs2netd_get_pilot_info(const char *callsign, player *out_plr, bool first_call) { if ( !Logged_in ) { return -2; } if ( (out_plr == NULL) || (callsign == NULL) || !(strlen(callsign)) ) { return -2; } static player new_plr; if (first_call) { new_plr.reset(); strncpy( new_plr.callsign, callsign, CALLSIGN_LEN ); // initialize the stats to default values init_scoring_element( &new_plr.stats ); out_plr->reset(); Local_timeout = timer_get_seconds() + 30; In_process = true; ml_printf("FS2NetD MSG: Requesting pilot stats for '%s' ...", callsign); } int rc = FS2NetD_GetPlayerData(callsign, &new_plr, false, first_call); // some sort of failure if (rc > 0) { In_process = false; Local_timeout = -1; return -2; } // if timeout passes then bail on failure if ( timer_get_seconds() > Local_timeout ) { In_process = false; Local_timeout = -1; return -2; } if (rc == 0) { memcpy( out_plr, &new_plr, sizeof(player) ); In_process = false; Local_timeout = -1; } // we should only be returning -1 (processing) or 0 (got data successfully) return rc; }
//initialize player - more to come, for now just animations void setPlayerSprites() { if (mainPlayer.getCharName().compare("Flu") == 0) { mainPlayer.loadPlayerSprites(6); mainPlayer.getSprites()[0] = SOIL_load_OGL_texture("Textures/Flu.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); mainPlayer.getSprites()[1] = SOIL_load_OGL_texture("Textures/Fluattack1.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); mainPlayer.getSprites()[2] = SOIL_load_OGL_texture("Textures/Fluattack2.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); mainPlayer.getSprites()[3] = SOIL_load_OGL_texture("Textures/Fluattack3.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); mainPlayer.getSprites()[4] = SOIL_load_OGL_texture("Textures/Fluattack4.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); mainPlayer.getSprites()[5] = SOIL_load_OGL_texture("Textures/Fluattack5.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y); } }
comestible_inventory_preset( const player &p ) : inventory_selector_preset(), p( p ) { append_cell( [ p, this ]( const item_location & loc ) { return good_bad_none( p.nutrition_for( get_comestible_item( loc ) ) ); }, _( "NUTRITION" ) ); append_cell( [ this ]( const item_location & loc ) { return good_bad_none( get_edible_comestible( loc ).quench ); }, _( "QUENCH" ) ); append_cell( [ p, this ]( const item_location & loc ) { return good_bad_none( p.fun_for( get_comestible_item( loc ) ).first ); }, _( "JOY" ) ); append_cell( [ this ]( const item_location & loc ) { const int spoils = get_edible_comestible( loc ).spoils; if( spoils > 0 ) { return to_string_clipped( time_duration::from_turns( spoils ) ); } return std::string(); }, _( "SPOILS IN" ) ); append_cell( [ this, &p ]( const item_location & loc ) { std::string cbm_name; switch( p.get_cbm_rechargeable_with( get_comestible_item( loc ) ) ) { case rechargeable_cbm::none: break; case rechargeable_cbm::battery: cbm_name = _( "Battery" ); break; case rechargeable_cbm::reactor: cbm_name = _( "Reactor" ); break; case rechargeable_cbm::furnace: cbm_name = _( "Furnace" ); break; } if( !cbm_name.empty() ) { return string_format( "<color_cyan>%s</color>", cbm_name.c_str() ); } return std::string(); }, _( "CBM" ) ); append_cell( [ this, &p ]( const item_location & loc ) { return good_bad_none( p.get_acquirable_energy( get_comestible_item( loc ) ) ); }, _( "ENERGY" ) ); }
static bool crafting_allowed( const player &p, const recipe &rec ) { if( !p.has_morale_to_craft() ) { add_msg( m_info, _( "Your morale is too low to craft..." ) ); return false; } if( p.lighting_craft_speed_multiplier( rec ) <= 0.0f ) { add_msg( m_info, _( "You can't see to craft!" ) ); return false; } return true; }
double calculate_missed_by(player &p, int trange, item* weapon) { // No type for gunmods,so use player weapon. it_gun* firing = dynamic_cast<it_gun*>(p.weapon.type); // Calculate deviation from intended target (assuming we shoot for the head) double deviation = 0.; // Measured in quarter-degrees. // Up to 0.75 degrees for each skill point < 8. if (p.skillLevel(firing->skill_used) < 8) { deviation += rng(0, 3 * (8 - p.skillLevel(firing->skill_used))); } // Up to 0.25 deg per each skill point < 9. if (p.skillLevel("gun") < 9) { deviation += rng(0, 9 - p.skillLevel("gun")); } deviation += rng(0, p.ranged_dex_mod()); deviation += rng(0, p.ranged_per_mod()); deviation += rng(0, 2 * p.encumb(bp_arms)) + rng(0, 4 * p.encumb(bp_eyes)); deviation += rng(0, weapon->curammo->dispersion); // item::dispersion() doesn't support gunmods. deviation += rng(0, p.weapon.dispersion()); int adj_recoil = p.recoil + p.driving_recoil; deviation += rng(int(adj_recoil / 4), adj_recoil); if (deviation < 0) { return 0; } // .013 * trange is a computationally cheap version of finding the tangent. // (note that .00325 * 4 = .013; .00325 is used because deviation is a number // of quarter-degrees) // It's also generous; missed_by will be rather short. return (.00325 * deviation * trange); }
void drop_on_map( const player &p, const std::list<item> &items, const tripoint &where ) { if( items.empty() ) { return; } const std::string ter_name = g->m.name( where ); const bool can_move_there = g->m.passable( where ); if( same_type( items ) ) { const item &it = items.front(); const int dropcount = items.size() * ( it.count_by_charges() ? it.charges : 1 ); const std::string it_name = it.tname( dropcount ); if( can_move_there ) { p.add_msg_player_or_npc( ngettext( "You drop your %1$s on the %2$s.", "You drop your %1$s on the %2$s.", dropcount ), ngettext( "<npcname> drops their %1$s on the %2$s.", "<npcname> drops their %1$s on the %2$s.", dropcount ), it_name.c_str(), ter_name.c_str() ); } else { p.add_msg_player_or_npc( ngettext( "You put your %1$s in the %2$s.", "You put your %1$s in the %2$s.", dropcount ), ngettext( "<npcname> puts their %1$s in the %2$s.", "<npcname> puts their %1$s in the %2$s.", dropcount ), it_name.c_str(), ter_name.c_str() ); } } else { if( can_move_there ) { p.add_msg_player_or_npc( _( "You drop several items on the %s." ), _( "<npcname> drops several items on the %s." ), ter_name.c_str() ); } else { p.add_msg_player_or_npc( _( "You put several items in the %s." ), _( "<npcname> puts several items in the %s." ), ter_name.c_str() ); } } for( const auto &it : items ) { g->m.add_item_or_charges( where, it ); } }
int attack_speed(player &u, bool missed) { int move_cost = u.weapon.attack_time() + 20 * u.encumb(bp_torso); if (u.has_trait(PF_LIGHT_BONES)) move_cost *= .9; if (u.has_trait(PF_HOLLOW_BONES)) move_cost *= .8; move_cost -= u.disease_intensity(DI_SPEED_BOOST); if (move_cost < 25) return 25; return move_cost; }
void stomach_contents::absorb_water( player &p, units::volume amount ) { if( water < amount ) { amount = water; water = 0_ml; } else { water -= amount; } if( p.get_thirst() < -100 ) { return; } else if( p.get_thirst() - units::to_milliliter( amount / 5 ) < -100 ) { p.set_thirst( -100 ); } p.mod_thirst( -units::to_milliliter( amount ) / 5 ); }
/* * Determines whose turn it will be, and returns that player *@ param player &a , player &b the players to be compared, using references * */ player turn(player &a, player &b) { if(a.turn == 1) { a.setTurn(0); b.setTurn(1); return a; } else if(b.turn ==1) { a.setTurn(1); b.setTurn(0); return b; } }
void test_consumable_charges( player &p, std::string &itemname, bool when_none, bool when_max ) { item it = item( itemname, 0, 0 ) ; INFO( "\'" + it.tname() + "\' is count-by-charges" ); CHECK( it.count_by_charges() ); it.charges = 0; INFO( "consume \'" + it.tname() + "\' with " + std::to_string( it.charges ) + " charges" ); REQUIRE( p.can_consume( it ) == when_none ); it.charges = LONG_MAX; INFO( "consume \'" + it.tname() + "\' with " + std::to_string( it.charges ) + " charges" ); REQUIRE( p.can_consume( it ) == when_max ); }
void gates::open_gate( const tripoint &pos, player &p ) { const gate_id gid = get_gate_id( pos ); if( !gates_data.is_valid( gid ) ) { p.add_msg_if_player( _( "Nothing happens." ) ); return; } const gate_data &gate = gates_data.obj( gid ); p.add_msg_if_player( gate.pull_message.c_str() ); p.assign_activity( ACT_OPEN_GATE, gate.moves ); p.activity.placement = pos; }
void stack_invlet_test( player &dummy, inventory_location from, inventory_location to ) { // invlet to assign constexpr char invlet = '|'; // duplication will most likely only happen if the stack is in the inventory // and is subsequently wielded or worn if( from != INVENTORY || ( to != WORN && to != WIELDED_OR_WORN ) ) { FAIL( "unimplemented" ); } // remove all items dummy.inv.clear(); dummy.worn.clear(); dummy.remove_weapon(); g->m.i_clear( dummy.pos() ); // some stackable item that can be wielded and worn item tshirt( "tshirt" ); // add two such items to the starting position add_item( dummy, tshirt, from ); add_item( dummy, tshirt, from ); // assign the stack with invlet assign_invlet( dummy, item_at( dummy, 0, from ), invlet, CACHED ); // wield or wear one of the items move_item( dummy, 0, from, to ); std::stringstream ss; ss << "1. add a stack of two same items to " << location_desc( from ) << std::endl; ss << "2. assign the stack with an invlet" << std::endl; ss << "3. " << move_action_desc( 0, from, to ) << std::endl; ss << "expect the two items to have different invlets" << std::endl; ss << "actually the two items have " << ( item_at( dummy, 0, to ).invlet != item_at( dummy, 0, from ).invlet ? "different" : "the same" ) << " invlets" << std::endl; INFO( ss.str() ); REQUIRE( item_at( dummy, 0, from ).typeId() == tshirt.typeId() ); REQUIRE( item_at( dummy, 0, to ).typeId() == tshirt.typeId() ); // the wielded/worn item should have different invlet from the remaining item CHECK( item_at( dummy, 0, to ).invlet != item_at( dummy, 0, from ).invlet ); // clear invlets assign_invlet( dummy, item_at( dummy, 0, from ), invlet, NONE ); assign_invlet( dummy, item_at( dummy, 0, to ), invlet, NONE ); }
void player_activity::do_turn( player &p ) { // Should happen before activity or it may fail du to 0 moves if( *this && type->will_refuel_fires() ) { try_refuel_fire( p ); } if( type->based_on() == based_on_type::TIME ) { moves_left -= 100; } else if( type->based_on() == based_on_type::SPEED ) { if( p.moves <= moves_left ) { moves_left -= p.moves; p.moves = 0; } else { p.moves -= moves_left; moves_left = 0; } } // This might finish the activity (set it to null) type->call_do_turn( this, &p ); if( *this && type->rooted() ) { p.rooted(); p.pause(); } if( *this && moves_left <= 0 ) { // Note: For some activities "finish" is a misnomer; that's why we explicitly check if the // type is ACT_NULL below. if( !( type->call_finish( this, &p ) ) ) { // "Finish" is never a misnomer for any activity without a finish function set_to_null(); } } if( !*this ) { // Make sure data of previous activity is cleared p.activity = player_activity(); if( !p.backlog.empty() && p.backlog.front().auto_resume ) { p.activity = p.backlog.front(); p.backlog.pop_front(); } // If whatever activity we were doing forced us to pick something up to // handle it, drop any overflow that may have caused p.drop_invalid_inventory(); } }
std::list<act_item> convert_to_items( const player &p, const drop_indexes &drop, int min_pos, int max_pos ) { std::list<act_item> res; for( const auto &rec : drop ) { const auto pos = rec.first; const auto count = rec.second; if( pos < min_pos || pos > max_pos ) { continue; } else if( pos >= 0 ) { int obtained = 0; for( const auto &it : p.inv.const_stack( pos ) ) { if( obtained >= count ) { break; } const int qty = it.count_by_charges() ? std::min<int>( it.charges, count - obtained ) : 1; obtained += qty; res.emplace_back( &it, qty, 100 ); // TODO: Use a calculated cost } } else { res.emplace_back( &p.i_at( pos ), count, ( pos == -1 ) ? 0 : 100 ); // TODO: Use a calculated cost } } return res; }
//DESENHA TUDO NO BUFFER void desenhar_jogo(){ int largura, altura, ax = 0, ay = 0; int bx = 0; int by = 0; switch(lugar){ case 1: bx = 160; by = 160; largura = 480; altura = 325; break; case 2: //BOSQUE ax = desloca_mapa_x; ay = desloca_mapa_y; largura = 800; altura = 600; break; case 3: //BOSQUE2 ax = desloca_mapa_x; ay = desloca_mapa_y; largura = 800; altura = 600; break; default: break; } blit(fundo, buffer, ax, ay, bx, by, 800, 600); jogadorr.desenha(); masked_blit(alto, buffer, ax, ay, bx, by, 800, 600); }
int item::reload_time(player &u) { int ret = 0; if (is_gun()) { it_gun* reloading = dynamic_cast<it_gun*>(type); ret = reloading->reload_time; if (charges == 0) { int spare_mag = has_gunmod(itm_spare_mag); if (spare_mag != -1 && contents[spare_mag].charges > 0) ret -= double(ret) * 0.9; } double skill_bonus = double(u.sklevel[reloading->skill_used]) * .075; if (skill_bonus > .75) skill_bonus = .75; ret -= double(ret) * skill_bonus; } else if (is_tool()) ret = 100 + volume() + weight(); if (has_flag(IF_STR_RELOAD)) ret -= u.str_cur * 20; if (ret < 25) ret = 25; ret += u.encumb(bp_hands) * 30; return ret; }
void start(){ one.symbol = '@'; two.symbol = '*'; #ifdef PATCHED #else one.lenname = lenofname; two.lenname = lenofname; #endif if (transmit_all(1, ONE, sizeof(ONE)-1) != 0) { _terminate(0); } #ifdef PATCHED if (receive_delim(0, one.name, sizeof(one.name), '\n', &(one.namelen)) != 0) { _terminate(0); } one.namelen--; #else if (receive_delim(0, one.name, 64, '\n', &rxlen) != 0) { _terminate(0); } #endif if (transmit_all(1, TWO, sizeof(TWO)-1) != 0) { _terminate(0); } #ifdef PATCHED if (receive_delim(0, two.name, sizeof(two.name), '\n', &(two.namelen)) != 0) { _terminate(0); } two.namelen--; #else if (receive_delim(0, two.name, 64, '\n', &rxlen) != 0) { _terminate(0); } #endif #ifdef PATCHED doname(one.name, one.namelen); doname(two.name, two.namelen); #else doname(one.name, one.lenname(one.name)); doname(two.name, two.lenname(two.name)); #endif init_board(); print_board(); }
bool monster::is_fleeing(player &u) const { if (has_effect("run")) return true; monster_attitude att = attitude(&u); return (att == MATT_FLEE || (att == MATT_FOLLOW && rl_dist( pos(), u.pos() ) <= 4)); }
// Whether or not, in the current state, the player can see the trap. bool trap::can_see( const tripoint &pos, const player &p ) const { if( is_null() ) { // There is no trap at all, so logically one can not see it. return false; } return visibility < 0 || p.knows_trap( pos ); }
void mission::assign( player &u ) { if( player_id == u.getID() ) { debugmsg( "strange: player is already assigned to mission %d", uid ); return; } if( player_id != -1 ) { debugmsg( "tried to assign mission %d to player, but mission is already assigned to %d", uid, player_id ); return; } player_id = u.getID(); u.on_mission_assignment( *this ); if( status == mission_status::yet_to_start ) { type->start( this ); status = mission_status::in_progress; } }
void game_menus::inv::reassign_letter( player &p, item &it ) { while( true ) { const long invlet = popup_getkey( _( "Enter new letter (press SPACE for none, ESCAPE to cancel)." ) ); if( invlet == KEY_ESCAPE ) { break; } else if( invlet == ' ' ) { p.reassign_item( it, 0 ); break; } else if( inv_chars.valid( invlet ) ) { p.reassign_item( it, invlet ); break; } } }
std::list<item> obtain_activity_items( player_activity &act, player &p ) { std::list<item> res; auto items = reorder_for_dropping( p, convert_to_indexes( act ) ); debug_drop_list( items ); while( !items.empty() && ( p.is_npc() || p.moves > 0 || items.front().consumed_moves == 0 ) ) { const auto &ait = items.front(); p.mod_moves( -ait.consumed_moves ); if( p.is_worn( *ait.it ) ) { p.takeoff( *ait.it, &res ); } else if( ait.it->count_by_charges() ) { res.push_back( p.reduce_charges( const_cast<item *>( ait.it ), ait.count ) ); } else { res.push_back( p.i_rem( ait.it ) ); } items.pop_front(); } // Avoid tumbling to the ground. Unload cleanly. const units::volume excessive_volume = p.volume_carried() - p.volume_capacity(); if( excessive_volume > 0 ) { const auto excess = p.inv.remove_randomly_by_volume( excessive_volume ); res.insert( res.begin(), excess.begin(), excess.end() ); } // Load anything that remains (if any) into the activity act.values.clear(); if( !items.empty() ) { for( const auto &drop : convert_to_indexes( p, items ) ) { act.values.push_back( drop.first ); act.values.push_back( drop.second ); } } // And either cancel if it's empty, or restart if it's not. if( act.values.empty() ) { p.cancel_activity(); } else { p.assign_activity( act ); } return res; }