Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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 );
        }
    }
}
Exemplo n.º 3
0
// 随机模型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;
}
Exemplo n.º 4
0
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 );
            }
        }
    }
}
Exemplo n.º 5
0
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 );
            }
        }
    }
}