void activity_handlers::washing_finish( player_activity *act, player *p ) { auto items = reorder_for_dropping( *p, convert_to_indexes( *act ) ); // Check again that we have enough water and soap incase the amount in our inventory changed somehow // Consume the water and soap units::volume total_volume = 0_ml; for( const act_item &filthy_item : items ) { total_volume += filthy_item.it->volume(); } washing_requirements required = washing_requirements_for_volume( total_volume ); const auto is_liquid_crafting_component = []( const item & it ) { return is_crafting_component( it ) && ( !it.count_by_charges() || it.made_of( LIQUID ) || it.contents_made_of( LIQUID ) ); }; const inventory &crafting_inv = p->crafting_inventory(); if( !crafting_inv.has_charges( "water", required.water, is_liquid_crafting_component ) && !crafting_inv.has_charges( "water_clean", required.water, is_liquid_crafting_component ) ) { p->add_msg_if_player( _( "You need %1$i charges of water or clean water to wash these items." ), required.water ); act->set_to_null(); return; } else if( !crafting_inv.has_charges( "soap", required.cleanser ) && !crafting_inv.has_charges( "detergent", required.cleanser ) ) { p->add_msg_if_player( _( "You need %1$i charges of cleansing agent to wash these items." ), required.cleanser ); act->set_to_null(); return; } for( const auto &ait : items ) { item *filthy_item = const_cast<item *>( ait.it ); filthy_item->item_tags.erase( "FILTHY" ); p->on_worn_item_washed( *filthy_item ); } std::vector<item_comp> comps; comps.push_back( item_comp( "water", required.water ) ); comps.push_back( item_comp( "water_clean", required.water ) ); p->consume_items( comps, 1, is_liquid_crafting_component ); std::vector<item_comp> comps1; comps1.push_back( item_comp( "soap", required.cleanser ) ); comps1.push_back( item_comp( "detergent", required.cleanser ) ); p->consume_items( comps1 ); p->add_msg_if_player( m_good, _( "You washed your clothing." ) ); // Make sure newly washed components show up as available if player attempts to craft immediately p->invalidate_crafting_inventory(); act->set_to_null(); }
void activity_handlers::washing_finish( player_activity *act, player *p ) { auto items = reorder_for_dropping( *p, convert_to_indexes( *act ) ); // Check again that we have enough water and soap incase the amount in our inventory changed somehow // Consume the water and soap int required_water = 0; int required_cleanser = 0; for( const act_item &filthy_item : items ) { required_water += filthy_item.it->volume() / 125_ml; required_cleanser += filthy_item.it->volume() / 1000_ml; } if( required_cleanser < 1 ) { required_cleanser = 1; } const inventory &crafting_inv = p->crafting_inventory(); if( !crafting_inv.has_charges( "water", required_water ) && !crafting_inv.has_charges( "water_clean", required_water ) ) { p->add_msg_if_player( _( "You need %1$i charges of water or clean water to wash these items." ), required_water ); act->set_to_null(); return; } else if( !crafting_inv.has_charges( "soap", required_cleanser ) && !crafting_inv.has_charges( "detergent", required_cleanser ) ) { p->add_msg_if_player( _( "You need %1$i charges of cleansing agent to wash these items." ), required_cleanser ); act->set_to_null(); return; } for( const auto &ait : items ) { item *filthy_item = const_cast<item *>( ait.it ); filthy_item->item_tags.erase( "FILTHY" ); } std::vector<item_comp> comps; comps.push_back( item_comp( "water", required_water ) ); comps.push_back( item_comp( "water_clean", required_water ) ); p->consume_items( comps ); std::vector<item_comp> comps1; comps1.push_back( item_comp( "soap", required_cleanser ) ); comps1.push_back( item_comp( "detergent", required_cleanser ) ); p->consume_items( comps1 ); p->add_msg_if_player( m_good, _( "You washed your clothing." ) ); act->set_to_null(); }
void mission::wrap_up() { auto &u = g->u; if( u.getID() != player_id ) { // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission // that have been assigned to the current player. debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", player_id, u.getID() ); } status = mission_status::success; u.on_mission_finished( *this ); std::vector<item_comp> comps; switch( type->goal ) { case MGOAL_FIND_ITEM: comps.push_back(item_comp(type->item_id, item_count)); u.consume_items(comps); break; case MGOAL_FIND_ANY_ITEM: u.remove_mission_items( uid ); break; default: //Suppress warnings break; } type->end( this ); }
void finalize_constructions() { std::vector<item_comp> frame_items; for( const auto &e : vpart_info::all() ) { const vpart_info &vp = e.second; if( !vp.has_flag( "INITIAL_PART" ) ) { continue; } frame_items.push_back( item_comp( vp.item, 1 ) ); } if( frame_items.empty() ) { debugmsg( "No valid frames detected for vehicle construction" ); } for( construction &con : constructions ) { if( con.post_special == &construct::done_vehicle ) { const_cast<requirement_data &>( con.requirements.obj() ).get_components().push_back( frame_items ); } } constructions.erase( std::remove_if( constructions.begin(), constructions.end(), [&]( const construction &c ) { return c.requirements->is_blacklisted(); } ), constructions.end() ); for( size_t i = 0; i < constructions.size(); i++ ) { constructions[ i ].id = i; } }
void talk_function::bionic_install( npc &p ) { std::vector<item *> bionic_inv = g->u.items_with( []( const item & itm ) { return itm.is_bionic(); } ); if( bionic_inv.empty() ) { popup( _( "You have no bionics to install!" ) ); return; } std::vector<itype_id> bionic_types; std::vector<std::string> bionic_names; for( auto &bio : bionic_inv ) { if( std::find( bionic_types.begin(), bionic_types.end(), bio->typeId() ) == bionic_types.end() ) { if( !g->u.has_bionic( bionic_id( bio->typeId() ) ) || bio->typeId() == "bio_power_storage" || bio->typeId() == "bio_power_storage_mkII" ) { bionic_types.push_back( bio->typeId() ); bionic_names.push_back( bio->tname() + " - " + format_money( bio->price( true ) * 2 ) ); } } } // Choose bionic if applicable int bionic_index = uilist( _( "Which bionic do you wish to have installed?" ), bionic_names ); // Did we cancel? if( bionic_index < 0 ) { popup( _( "You decide to hold off..." ) ); return; } const item tmp = item( bionic_types[bionic_index], 0 ); const itype &it = *tmp.type; unsigned int price = tmp.price( true ) * 2; if( price > g->u.cash ) { popup( _( "You can't afford the procedure..." ) ); return; } //Makes the doctor awesome at installing but not perfect if( g->u.install_bionics( it, p, false, 20 ) ) { g->u.cash -= price; p.cash += price; g->u.amount_of( bionic_types[bionic_index] ); std::vector<item_comp> comps; comps.push_back( item_comp( tmp.typeId(), 1 ) ); g->u.consume_items( comps, 1 ); } }
void mission::wrap_up() { auto &u = g->u; if( u.getID() != player_id ) { // This is called from npctalk.cpp, the npc should only offer the option to wrap up mission // that have been assigned to the current player. debugmsg( "mission::wrap_up called, player %d was assigned, but current player is %d", player_id, u.getID() ); } status = mission_status::success; u.on_mission_finished( *this ); std::vector<item_comp> comps; switch( type->goal ) { case MGOAL_FIND_ITEM_GROUP: { inventory tmp_inv = u.crafting_inventory(); std::vector<item *> items = std::vector<item *>(); tmp_inv.dump( items ); Group_tag grp_type = type->group_id; itype_id container = type->container_id; bool specific_container_required = container != "null"; bool remove_container = type->remove_container; itype_id empty_container = type->empty_container; std::map<itype_id, int> matches = std::map<itype_id, int>(); get_all_item_group_matches( items, grp_type, matches, container, itype_id( "null" ), specific_container_required ); std::map<std::string, int>::iterator cnt_it; for( cnt_it = matches.begin(); cnt_it != matches.end(); cnt_it++ ) { comps.push_back( item_comp( cnt_it->first, cnt_it->second ) ); } u.consume_items( comps ); if( remove_container ) { std::vector<item_comp> container_comp = std::vector<item_comp>(); if( empty_container != "null" ) { container_comp.push_back( item_comp( empty_container, type->item_count ) ); u.consume_items( container_comp ); } else { container_comp.push_back( item_comp( container, type->item_count ) ); u.consume_items( container_comp ); } } } break; case MGOAL_FIND_ITEM: comps.push_back( item_comp( type->item_id, item_count ) ); u.consume_items( comps ); break; case MGOAL_FIND_ANY_ITEM: u.remove_mission_items( uid ); break; default: //Suppress warnings break; } type->end( this ); }