void RandomModel::antennasProduce() { Direction tad(0,0,1); Direction tarp(0,0,0); Direction taPolar(sqrt(double(2))/2, 0, sqrt(double(2))/2); Antenna ta(tad, tarp, taPolar, 10); this->tAntennas.push_back(ta); Direction rad(0,0,1); Direction rarp(0,0,0); Direction raVPolar(1, 0, 0); Direction raHPolar(0, 0, 1); Antenna ra(rad, rarp, raVPolar, raHPolar); this->rAntennas.push_back(ra); }
void scatter_chunks( const std::string &chunk_name, int chunk_amt, monster &z, int distance, int pile_size = 1 ) { // can't have less than one item in a pile or it would cause an infinite loop pile_size = std::max( pile_size, 1 ); // can't have more items in a pile than total items pile_size = std::min( chunk_amt, pile_size ); distance = abs( distance ); const item chunk( chunk_name, calendar::turn, pile_size ); for( int i = 0; i < chunk_amt; i += pile_size ) { bool drop_chunks = true; tripoint tarp( z.pos() + point( rng( -distance, distance ), rng( -distance, distance ) ) ); const auto traj = line_to( z.pos(), tarp ); for( size_t j = 0; j < traj.size(); j++ ) { tarp = traj[j]; if( one_in( 2 ) && z.bloodType() != fd_null ) { g->m.add_splatter( z.bloodType(), tarp ); } else { g->m.add_splatter( z.gibType(), tarp, rng( 1, j + 1 ) ); } if( g->m.impassable( tarp ) ) { g->m.bash( tarp, distance ); if( g->m.impassable( tarp ) ) { // Target is obstacle, not destroyed by bashing, // stop trajectory in front of it, if this is the first // point (e.g. wall adjacent to monster), don't drop anything on it if( j > 0 ) { tarp = traj[j - 1]; } else { drop_chunks = false; } break; } } } if( drop_chunks ) { g->m.add_item_or_charges( tarp, chunk ); } } }
// 随机模型1 Model randomModel(double length, double width, double margin, double sMaxH, double sMinH, double sMaxW, double sMinW, double surfaceInterval, double vRange, int dFlag) { Direction* tdp; Direction* rdp; switch(dFlag) { case 1: tdp = new Direction(0, 1, 0); rdp = new Direction(0, 1, 0); break; case 2: tdp = new Direction(0, -1, 0); rdp = new Direction(0, -1, 0); break; case 3: tdp = new Direction(0, 1, 0); rdp = new Direction(0, -1, 0); break; case 4: tdp = new Direction(0, -1, 0); rdp = new Direction(0, 1, 0); break; default: double ty = plusOrMinus(); double ry = plusOrMinus(); Direction td(0, ty, 0); Direction rd(0, ry, 0); break; } Vehicle tx = randomVehicle(0, width, *tdp, vRange); Vehicle rx = randomVehicle(length, width, *rdp, vRange); vector<Material> materials = materialList(); vector<Surface> surfaces; double totalLength = 0; srand((int)time(0)); while (totalLength <= length) { double x0 = (width / 2) + random((int)margin); double y0 = totalLength; double z0 = sMinH + random(int(sMaxH - sMinH)); Point p0(x0, y0, z0); double sWidth = sMinW + random((int)(sMaxW - sMinW)); double x1 = x0; double y1 = y0 + sWidth; double z1 = 0; Point p1(x1, y1, z1); Surface s(p0, p1); surfaces.push_back(s); totalLength = y0 + sWidth + random((int)surfaceInterval); } totalLength = 0; while (totalLength <= length) { double x0 = -((width / 2) + random((int)margin)); double y0 = totalLength; double z0 = sMinH + random(int(sMaxH - sMinH)); Point p0(x0, y0, z0); double sWidth = sMinW + random((int)(sMaxW - sMinW)); double x1 = x0; double y1 = y0 + sWidth; double z1 = 0; Point p1(x1, y1, z1); Surface s(p0, p1); surfaces.push_back(s); totalLength = y0 + sWidth + random((int)surfaceInterval); } int sizeM = materials.size(); for (int i = 0; i < (int)surfaces.size(); i++) { int indexM = random(sizeM); surfaces[i].setMaterial(materials[indexM]); surfaces[i].init(); } Direction tad(0,0,1); Direction tarp(0,0,0); Direction taPolar(sqrt(double(2))/2, 0, sqrt(double(2))/2); Antenna ta(tad, tarp, taPolar, 10); vector<Antenna> tas; tas.push_back(ta); Direction rad(0,0,1); Direction rarp(0,0,0); Direction raVPolar(1, 0, 0); Direction raHPolar(0, 0, 1); Antenna ra(rad, rarp, raVPolar, raHPolar); vector<Antenna> ras; ras.push_back(ra); Model model(tx, rx, surfaces, tas, ras); return model; }
void mdeath::normal( monster &z ) { if( z.no_corpse_quiet ) { return; } if( z.type->in_species( ZOMBIE ) ) { sfx::play_variant_sound( "mon_death", "zombie_death", sfx::get_heard_volume( z.pos() ) ); } if( g->u.sees( z ) ) { //Currently it is possible to get multiple messages that a monster died. add_msg( m_good, _( "The %s dies!" ), z.name().c_str() ); } const int max_hp = std::max( z.get_hp_max(), 1 ); const float overflow_damage = std::max( -z.get_hp(), 0 ); const float corpse_damage = 2.5 * overflow_damage / max_hp; const bool pulverized = corpse_damage > 5 && overflow_damage > z.get_hp_max(); z.bleed(); // leave some blood if we have to if( !pulverized ) { make_mon_corpse( z, int( std::floor( corpse_damage ) ) ); } // Limit chunking to flesh, veggy and insect creatures until other kinds are supported. const std::vector<material_id> gib_mats = {{ material_id( "flesh" ), material_id( "hflesh" ), material_id( "veggy" ), material_id( "iflesh" ), material_id( "bone" ) }}; const bool gibbable = !z.type->has_flag( MF_NOGIB ) && std::any_of( gib_mats.begin(), gib_mats.end(), [&z]( const material_id &gm ) { return z.made_of( gm ); } ); const field_id type_blood = z.bloodType(); const field_id type_gib = z.gibType(); if( gibbable ) { const auto area = g->m.points_in_radius( z.pos(), 1 ); int number_of_gibs = std::min( std::floor( corpse_damage ) - 1, 1 + max_hp / 5.0f ); if( pulverized && z.type->size >= MS_MEDIUM ) { number_of_gibs += rng( 1, 6 ); sfx::play_variant_sound( "mon_death", "zombie_gibbed", sfx::get_heard_volume( z.pos() ) ); } for( int i = 0; i < number_of_gibs; ++i ) { g->m.add_splatter( type_gib, random_entry( area ), rng( 1, i + 1 ) ); g->m.add_splatter( type_blood, random_entry( area ) ); } } const int num_chunks = z.type->get_meat_chunks_count(); if( pulverized && gibbable ) { const itype_id meat = z.type->get_meat_itype(); const item chunk( meat ); for( int i = 0; i < num_chunks; i++ ) { tripoint tarp( z.pos() + point( rng( -3, 3 ), rng( -3, 3 ) ) ); const auto traj = line_to( z.pos(), tarp ); for( size_t j = 0; j < traj.size(); j++ ) { tarp = traj[j]; if( one_in( 2 ) && type_blood != fd_null ) { g->m.add_splatter( type_blood, tarp ); } else { g->m.add_splatter( type_gib, tarp, rng( 1, j + 1 ) ); } if( g->m.impassable( tarp ) ) { g->m.bash( tarp, 3 ); if( g->m.impassable( tarp ) ) { // Target is obstacle, not destroyed by bashing, // stop trajectory in front of it, if this is the first // point (e.g. wall adjacent to monster) , make it invalid. if( j > 0 ) { tarp = traj[j - 1]; } else { tarp = tripoint_min; } break; } } } if( tarp != tripoint_min ) { g->m.add_item_or_charges( tarp, chunk ); } } } }
void mdeath::splatter( monster &z ) { // Limit chunking to flesh, veggy and insect creatures until other kinds are supported. const std::vector<material_id> gib_mats = {{ material_id( "flesh" ), material_id( "hflesh" ), material_id( "veggy" ), material_id( "iflesh" ), material_id( "bone" ) } }; const bool gibbable = !z.type->has_flag( MF_NOGIB ) && std::any_of( gib_mats.begin(), gib_mats.end(), [&z]( const material_id & gm ) { return z.made_of( gm ); } ); const int max_hp = std::max( z.get_hp_max(), 1 ); const float overflow_damage = std::max( -z.get_hp(), 0 ); const float corpse_damage = 2.5 * overflow_damage / max_hp; bool pulverized = corpse_damage > 5 && overflow_damage > z.get_hp_max(); // make sure that full splatter happens when this is a set death function, not part of normal for( const auto &deathfunction : z.type->dies ) { if( deathfunction == mdeath::splatter ) { pulverized = true; } } const field_id type_blood = z.bloodType(); const field_id type_gib = z.gibType(); if( gibbable ) { const auto area = g->m.points_in_radius( z.pos(), 1 ); int number_of_gibs = std::min( std::floor( corpse_damage ) - 1, 1 + max_hp / 5.0f ); if( pulverized && z.type->size >= MS_MEDIUM ) { number_of_gibs += rng( 1, 6 ); sfx::play_variant_sound( "mon_death", "zombie_gibbed", sfx::get_heard_volume( z.pos() ) ); } for( int i = 0; i < number_of_gibs; ++i ) { g->m.add_splatter( type_gib, random_entry( area ), rng( 1, i + 1 ) ); g->m.add_splatter( type_blood, random_entry( area ) ); } } int num_chunks = rng( 0, z.type->get_meat_chunks_count() / 4 ); num_chunks = std::min( num_chunks, 10 ); if( pulverized && gibbable ) { const itype_id meat = z.type->get_meat_itype(); const item chunk( meat ); for( int i = 0; i < num_chunks; i++ ) { bool drop_chunks = true; tripoint tarp( z.pos() + point( rng( -3, 3 ), rng( -3, 3 ) ) ); const auto traj = line_to( z.pos(), tarp ); for( size_t j = 0; j < traj.size(); j++ ) { tarp = traj[j]; if( one_in( 2 ) && type_blood != fd_null ) { g->m.add_splatter( type_blood, tarp ); } else { g->m.add_splatter( type_gib, tarp, rng( 1, j + 1 ) ); } if( g->m.impassable( tarp ) ) { g->m.bash( tarp, 3 ); if( g->m.impassable( tarp ) ) { // Target is obstacle, not destroyed by bashing, // stop trajectory in front of it, if this is the first // point (e.g. wall adjacent to monster), don't drop anything on it if( j > 0 ) { tarp = traj[j - 1]; } else { drop_chunks = false; } break; } } } if( drop_chunks ) { g->m.add_item_or_charges( tarp, chunk ); } } } }