bool repair_part( vehicle &veh, vehicle_part &pt, Character &who_c ) { // @todo: Get rid of this cast after moving relevant functions down to Character player &who = ( player & )who_c; int part_index = veh.index_of_part( &pt ); auto &vp = pt.info(); // @todo: Expose base part damage somewhere, don't recalculate it here const auto reqs = pt.is_broken() ? vp.install_requirements() : vp.repair_requirements() * pt.damage_level( 4 ); inventory map_inv; map_inv.form_from_map( who.pos(), PICKUP_RANGE ); if( !reqs.can_make_with_inventory( who.crafting_inventory() ) ) { who.add_msg_if_player( m_info, _( "You don't meet the requirements to repair the %s." ), pt.name().c_str() ); return false; } // consume items extracting any base item (which we will need if replacing broken part) item base( vp.item ); for( const auto &e : reqs.get_components() ) { for( auto &obj : who.consume_items( who.select_item_component( e, 1, map_inv ), 1 ) ) { if( obj.typeId() == vp.item ) { base = obj; } } } for( const auto &e : reqs.get_tools() ) { who.consume_tools( who.select_tool_component( e, 1, map_inv ), 1 ); } who.invalidate_crafting_inventory(); for( const auto &sk : pt.is_broken() ? vp.install_skills : vp.repair_skills ) { who.practice( sk.first, calc_xp_gain( vp, sk.first ) ); } // If part is broken, it will be destroyed and references invalidated std::string partname = pt.name(); if( pt.is_broken() ) { const int dir = pt.direction; point loc = pt.mount; auto replacement_id = pt.info().get_id(); g->m.spawn_items( who.pos(), pt.pieces_for_broken_part() ); veh.remove_part( part_index ); const int partnum = veh.install_part( loc, replacement_id, std::move( base ) ); veh.parts[partnum].direction = dir; veh.part_removal_cleanup(); } else { veh.set_hp( pt, pt.info().durability ); } // @todo: NPC doing that who.add_msg_if_player( m_good, _( "You repair the %1$s's %2$s." ), veh.name.c_str(), partname.c_str() ); return true; }
RESCUER::RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject ) { get_components( m_components ); m_prj = &aProject; m_libs = m_prj->SchLibs(); m_edit_frame = &aEditFrame; }
InstrumentComponent* Instrument::get_component( int DrumkitComponentID ) { for (std::vector<InstrumentComponent*>::iterator it = get_components()->begin() ; it != get_components()->end(); ++it) { if( (*it)->get_drumkit_componentID() == DrumkitComponentID ) return *it; } return NULL; }
void craft_command::execute() { if( empty() ) { return; } bool need_selections = true; inventory map_inv; map_inv.form_from_map( crafter->pos(), PICKUP_RANGE ); if( has_cached_selections() ) { std::vector<comp_selection<item_comp>> missing_items = check_item_components_missing( map_inv ); std::vector<comp_selection<tool_comp>> missing_tools = check_tool_components_missing( map_inv ); if( missing_items.empty() && missing_tools.empty() ) { // All items we used previously are still there, so we don't need to do selection. need_selections = false; } else if( !query_continue( missing_items, missing_tools ) ) { return; } } const auto needs = rec->requirements(); if( need_selections ) { item_selections.clear(); for( const auto &it : needs.get_components() ) { comp_selection<item_comp> is = crafter->select_item_component( it, batch_size, map_inv, true ); if( is.use_from == cancel ) { return; } item_selections.push_back( is ); } tool_selections.clear(); for( const auto &it : needs.get_tools() ) { comp_selection<tool_comp> ts = crafter->select_tool_component( it, batch_size, map_inv, DEFAULT_HOTKEYS, true ); if( ts.use_from == cancel ) { return; } tool_selections.push_back( ts ); } } auto activity = player_activity( is_long ? ACT_LONGCRAFT : ACT_CRAFT, rec->batch_time( batch_size ), -1, INT_MIN, rec->ident() ); activity.values.push_back( batch_size ); crafter->assign_activity( activity ); /* legacy support for lua bindings to last_batch and lastrecipe */ crafter->last_batch = batch_size; crafter->lastrecipe = rec->ident(); }
void Instrument::unload_samples() { for (std::vector<InstrumentComponent*>::iterator it = get_components()->begin() ; it != get_components()->end(); ++it) { InstrumentComponent* component = *it; for ( int i=0; i<MAX_LAYERS; i++ ) { InstrumentLayer* layer = component->get_layer( i ); if( layer ) layer->unload_sample(); } } }
static VALUE components(VALUE self) { struct png_data *reader; png_structp png_ptr; png_infop info_ptr; int c; Data_Get_Struct(self, struct png_data, reader); png_ptr = reader->png_ptr; info_ptr = reader->info_ptr; c = get_components(png_ptr, info_ptr); if (c == 0) return Qnil; return INT2FIX(c); }
void player::complete_disassemble( int item_pos, const tripoint &loc, bool from_ground, const recipe &dis ) { // Get the proper recipe - the one for disassembly, not assembly const auto dis_requirements = dis.disassembly_requirements(); item &org_item = get_item_for_uncraft( *this, item_pos, loc, from_ground ); bool filthy = org_item.is_filthy(); if( org_item.is_null() ) { add_msg( _( "The item has vanished." ) ); activity.set_to_null(); return; } if( org_item.typeId() != dis.result ) { add_msg( _( "The item might be gone, at least it is not at the expected position anymore." ) ); activity.set_to_null(); return; } // Make a copy to keep its data (damage/components) even after it // has been removed. item dis_item = org_item; float component_success_chance = std::min( std::pow( 0.8, dis_item.damage() ), 1.0 ); add_msg( _( "You disassemble the %s into its components." ), dis_item.tname().c_str() ); // Remove any batteries, ammo and mods first remove_ammo( &dis_item, *this ); remove_radio_mod( dis_item, *this ); if( dis_item.count_by_charges() ) { // remove the charges that one would get from crafting it org_item.charges -= dis.create_result().charges; } // remove the item, except when it's counted by charges and still has some if( !org_item.count_by_charges() || org_item.charges <= 0 ) { if( from_ground ) { g->m.i_rem( loc, item_pos ); } else { i_rem( item_pos ); } } // Consume tool charges for( const auto &it : dis_requirements.get_tools() ) { consume_tools( it ); } // add the components to the map // Player skills should determine how many components are returned int skill_dice = 2 + get_skill_level( dis.skill_used ) * 3; skill_dice += get_skill_level( dis.skill_used ); // Sides on dice is 16 plus your current intelligence ///\EFFECT_INT increases success rate for disassembling items int skill_sides = 16 + int_cur; int diff_dice = dis.difficulty; int diff_sides = 24; // 16 + 8 (default intelligence) // disassembly only nets a bit of practice if( dis.skill_used ) { practice( dis.skill_used, ( dis.difficulty ) * 2, dis.difficulty ); } for( const auto &altercomps : dis_requirements.get_components() ) { const item_comp comp = find_component( altercomps, dis_item ); int compcount = comp.count; item newit( comp.type, calendar::turn ); // Counted-by-charge items that can be disassembled individually // have their component count multiplied by the number of charges. if( dis_item.count_by_charges() && dis.has_flag( "UNCRAFT_SINGLE_CHARGE" ) ) { compcount *= std::min( dis_item.charges, dis.create_result().charges ); } // Compress liquids and counted-by-charges items into one item, // they are added together on the map anyway and handle_liquid // should only be called once to put it all into a container at once. if( newit.count_by_charges() || newit.made_of( LIQUID ) ) { newit.charges = compcount; compcount = 1; } else if( !newit.craft_has_charges() && newit.charges > 0 ) { // tools that can be unloaded should be created unloaded, // tools that can't be unloaded will keep their default charges. newit.charges = 0; } for( ; compcount > 0; compcount-- ) { const bool comp_success = ( dice( skill_dice, skill_sides ) > dice( diff_dice, diff_sides ) ); if( dis.difficulty != 0 && !comp_success ) { add_msg( m_bad, _( "You fail to recover %s." ), newit.tname().c_str() ); continue; } const bool dmg_success = component_success_chance > rng_float( 0, 1 ); if( !dmg_success ) { // Show reason for failure (damaged item, tname contains the damage adjective) //~ %1s - material, %2$s - disassembled item add_msg( m_bad, _( "You fail to recover %1$s from the %2$s." ), newit.tname().c_str(), dis_item.tname().c_str() ); continue; } // Use item from components list, or (if not contained) // use newit, the default constructed. item act_item = newit; if( filthy ) { act_item.item_tags.insert( "FILTHY" ); } for( item::t_item_vector::iterator a = dis_item.components.begin(); a != dis_item.components.end(); ++a ) { if( a->type == newit.type ) { act_item = *a; dis_item.components.erase( a ); break; } } int veh_part = -1; vehicle *veh = g->m.veh_at( pos(), veh_part ); if( veh != nullptr ) { veh_part = veh->part_with_feature( veh_part, "CARGO" ); } if( act_item.made_of( LIQUID ) ) { g->handle_all_liquid( act_item, PICKUP_RANGE ); } else if( veh_part != -1 && veh->add_item( veh_part, act_item ) ) { // add_item did put the items in the vehicle, nothing further to be done } else { // TODO: For items counted by charges, add as much as we can to the vehicle, and // the rest on the ground (see dropping code and @vehicle::add_charges) g->m.add_item_or_charges( pos(), act_item ); } } } if( !dis.learn_by_disassembly.empty() && !knows_recipe( &dis ) ) { if( can_decomp_learn( dis ) ) { // @todo: make this depend on intelligence if( one_in( 4 ) ) { learn_recipe( &recipe_dict[ dis.ident() ] ); add_msg( m_good, _( "You learned a recipe from disassembling it!" ) ); } else { add_msg( m_info, _( "You might be able to learn a recipe if you disassemble another." ) ); } } else { add_msg( m_info, _( "If you had better skills, you might learn a recipe next time." ) ); } } }
static void process(SSDATA *d,int n,double *t) { PROPERTIES p; int choice; enum {Next,Time,Mass,Bounds,ComPos,ComVel,AngMom,VelDsp,Color,Units, Offsets,Masses,Radii,End}; while (/*CONSTCOND*/1) { ss_analyze(d,n,&p); (void) printf("%2i. Time = %g\n",Time,*t); (void) printf("%2i. Total mass = %g\n",Mass,p.total_mass); (void) printf("%2i. Bounds: x=[%g,%g]\n" " y=[%g,%g]\n" " z=[%g,%g]\n",Bounds, p.bnd_min[X],p.bnd_max[X], p.bnd_min[Y],p.bnd_max[Y], p.bnd_min[Z],p.bnd_max[Z]); (void) printf("%2i. Centre-of-mass position = %g %g %g\n",ComPos, p.com_pos[X],p.com_pos[Y],p.com_pos[Z]); (void) printf("%2i. Centre-of-mass velocity = %g %g %g\n",ComVel, p.com_vel[X],p.com_vel[Y],p.com_vel[Z]); (void) printf("%2i. Specific angular momentum = %g %g %g\n",AngMom, p.ang_mom[X],p.ang_mom[Y],p.ang_mom[Z]); (void) printf("%2i. Velocity dispersion = %g %g %g\n",VelDsp, p.vel_dsp[X],p.vel_dsp[Y],p.vel_dsp[Z]); (void) printf("%2i. Dominant color = %i (%s)\n",Color,p.color, color_str(p.color)); (void) printf("%2i. Units\n",Units); (void) printf("%2i. Offsets\n",Offsets); (void) printf("%2i. Particle masses\n",Masses); (void) printf("%2i. Particle radii\n",Radii); do { (void) printf("Enter number to change (or 0 to continue): "); (void) scanf("%i",&choice); } while (choice < Next || choice >= End); (void) getchar(); if (choice == Next) return; switch(choice) { case Time: do { (void) printf("Enter new time: "); (void) scanf("%lf",t); (void) getchar(); } while (*t < 0); break; case Mass: { double f; do get_scaling(&f,NegativeOK); while (f == 0); if (f < 0) f = -f/p.total_mass; scale_mass(d,n,f); break; } case Bounds: { double f,min,max; int i,choice; do { do { (void) printf("%i. Change x bounds (now [%g,%g])\n",X + 1, p.bnd_min[X],p.bnd_max[X]); (void) printf("%i. Change y bounds (now [%g,%g])\n",Y + 1, p.bnd_min[Y],p.bnd_max[Y]); (void) printf("%i. Change z bounds (now [%g,%g])\n",Z + 1, p.bnd_min[Z],p.bnd_max[Z]); (void) printf("Your choice (or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < 0 || choice > N_DIM); if (choice == 0) break; --choice; /* put back in range [X,Z] */ if (p.bnd_min[choice] == p.bnd_max[choice]) { (void) printf("Chosen dimension is degenerate\n"); continue; } do { (void) printf("Enter new bounds (min max): "); (void) scanf("%lf%lf",&min,&max); (void) getchar(); } while (min > max); if (min == max && get_yn("Zero velocities for this component","y")) for (i=0;i<n;i++) d[i].vel[choice] = 0; f = (max - min)/(p.bnd_max[choice] - p.bnd_min[choice]); for (i=0;i<n;i++) d[i].pos[choice] = (d[i].pos[choice] - p.bnd_min[choice])*f + min; p.bnd_min[choice] = min; p.bnd_max[choice] = max; } while (/*CONSTCOND*/1); break; } case ComPos: { VECTOR v; if (MAG(p.com_pos) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_pos,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_pos(d,n,&p,v); break; } case ComVel: { VECTOR v; if (MAG(p.com_vel) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_vel,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_vel(d,n,&p,v); break; } case AngMom: { VECTOR v; (void) printf("NOTE: specific angular momentum is measured with\n" "respect to fixed space frame centred at (0,0,0)\n" "and does not take particle spins into account\n"); if (MAG(p.ang_mom) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.ang_mom,v); if (f < 0) f = -f/MAG(p.ang_mom); SCALE_VEC(v,f); } else if (get_yn("Scale the components","y")) { VECTOR u; int k; get_component_scaling(u); for (k=0;k<N_DIM;k++) v[k] = u[k]*p.ang_mom[k]; } else get_components(v); adj_ang_mom(d,n,&p,v); break; } case VelDsp: { VECTOR v; (void) printf("NOTE: velocity dispersion is context dependent,\n" "for now relative ONLY to center-of-mass velocity,\n" "i.e. without considering bulk rotation or shear\n"); if (!MAG(p.vel_dsp)) { (void) printf("Zero velocity dispersion -- cannot adjust\n"); break; } if (get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); if (f < 0) f = -f/MAG(p.vel_dsp); SET_VEC(v,f,f,f); } else get_component_scaling(v); scale_vel_dsp(d,n,&p,v); break; } case Color: { int c; (void) printf("Color scheme:\n"); for (c=BLACK;c<FIRST_GRAY;c++) (void) printf("%2i. %s\n",c,color_str(c)); (void) printf("[values from %i to %i are levels of gray]\n", FIRST_GRAY,LAST_GRAY); do { (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); } while (c < 0 || c >= NUM_COLORS); change_color(d,n,c); break; } case Units: { enum {N,M,L,T,V,E}; double f; int i,choice; (void) printf("NOTE: It is up to you to ensure dimensions are\n" "internally consistent. pkdgrav assumes G == 1.\n"); do { do { (void) printf("%i. Mass (particle masses)\n",M); (void) printf("%i. Length (particle radii, pos'ns)\n",L); (void) printf("%i. Time (time,particle spins)\n",T); (void) printf("%i. Velocity (particle velocities)\n",V); (void) printf("Select dimension to scale " "(or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < N || choice >= E); if (choice == N) break; switch (choice) { case M: (void) printf("M_Sun = 1.9891e30 kg\n" "M_Earth = 5.9742e24 kg\n" "M_Jupiter = 1.8992e27 kg\n" "M_Saturn = 5.6864e26 kg\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) d[i].mass *= f; break; case L: (void) printf("1 AU = 1.49597892e11 m\n" "R_Earth = 6.37814e6 m\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) { d[i].radius *= f; SCALE_VEC(d[i].pos,f); } break; case T: (void) printf("1 yr = 3.15576e7 s\n" "1 yr / 2 pi = 5.02255e6 s\n"); get_scaling(&f,PositiveOnly); *t *= f; for (i=0;i<n;i++) NORM_VEC(d[i].spin,f); break; case V: (void) printf("V_Earth = 2.97852586e4 m/s\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) SCALE_VEC(d[i].vel,f); break; default: assert(0); } } while (/*CONSTCOND*/1); break; } case Offsets: { VECTOR v; int i; (void) printf("POSITION OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].pos,v,d[i].pos); (void) printf("VELOCITY OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].vel,v,d[i].vel); break; } case Masses: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_masses(d,n,f); break; } case Radii: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_radii(d,n,f); break; } default: assert(0); } } }