コード例 #1
0
ファイル: mondeath.cpp プロジェクト: vbilty/Cataclysm-DDA
void mdeath::normal(monster *z)
{
    if ((g->u.sees(*z)) && (!z->no_corpse_quiet)) {
        add_msg(m_good, _("The %s dies!"),
                z->name().c_str()); //Currently it is possible to get multiple messages that a monster died.
    }
    if ( z->type->in_species( ZOMBIE )) {
            sfx::play_variant_sound( "mon_death", "zombie_death", sfx::get_heard_volume(z->pos()));
        }
    m_size monSize = (z->type->size);
    bool leaveCorpse = !((z->type->has_flag(MF_VERMIN)) || (z->no_corpse_quiet));

    // leave some blood if we have to
    if (!z->has_flag(MF_VERMIN)) {
        field_id type_blood = z->bloodType();
        if (type_blood != fd_null) {
            g->m.add_field( z->pos(), type_blood, 1, 0 );
        }
    }

    int maxHP = z->get_hp_max();
    if (!maxHP) {
        maxHP = 1;
    }

    float overflowDamage = std::max( -z->get_hp(), 0 );
    float corpseDamage = 5 * (overflowDamage / (maxHP * 2));

    if (leaveCorpse) {
        int gibAmount = int(floor(corpseDamage)) - 1;
        // allow one extra gib per 5 HP
        int gibLimit = 1 + (maxHP / 5.0);
        if (gibAmount > gibLimit) {
            gibAmount = gibLimit;
        }
        bool pulverized = (corpseDamage > 5 && overflowDamage > 150);
        if (!pulverized) {
            make_mon_corpse(z, int(floor(corpseDamage)));
        } else if (monSize >= MS_MEDIUM) {
            gibAmount += rng(1, 6);
            sfx::play_variant_sound( "mon_death", "zombie_gibbed", sfx::get_heard_volume(z->pos()));
        }
        // Limit chunking to flesh, veggy and insect creatures until other kinds are supported.
        bool leaveGibs = (z->made_of("flesh") || z->made_of("hflesh") || z->made_of("veggy") ||
                          z->made_of("iflesh"));
        if (leaveGibs) {
            make_gibs( z, gibAmount );
        }
    }
}
コード例 #2
0
ファイル: mondeath.cpp プロジェクト: 9600bauds/Cataclysm-DDA
void mdeath::normal(monster *z) {
    if (g->u_see(z)) {
        g->add_msg(_("The %s dies!"), z->name().c_str());
    }
    if(z->type->difficulty >= 30) {
        // TODO: might not be killed by the player (g->u)!
        g->u.add_memorial_log(pgettext("memorial_male","Killed a %s."),
            pgettext("memorial_female", "Killed a %s."),
            z->name().c_str());
    }

    m_size monSize = (z->type->size);
    bool isFleshy = (z->made_of("flesh") || z->made_of("hflesh"));
    bool leaveCorpse = !(z->type->has_flag(MF_VERMIN));

    // leave some blood if we have to
    if (isFleshy && z->has_flag(MF_WARM) && !z->has_flag(MF_VERMIN)) {
        g->m.add_field(z->posx(), z->posy(), fd_blood, 1);
    }

    int maxHP = z->type->hp;
    if (!maxHP) {
        maxHP = 1;
    }

    float overflowDamage = -(z->hp);
    float corpseDamage = 5 * (overflowDamage / (maxHP * 2));

    if (leaveCorpse) {
        int gibAmount = int(floor(corpseDamage)) - 1;
        // allow one extra gib per 5 HP
        int gibLimit = 1 + (maxHP / 5.0);
        if (gibAmount > gibLimit) {
            gibAmount = gibLimit;
        }
        bool pulverized = (corpseDamage > 5 && overflowDamage > 150);
        if (!pulverized) {
            make_mon_corpse(z, int(floor(corpseDamage)));
        } else if (monSize >= MS_MEDIUM) {
            gibAmount += rng(1,6);
        }
        // Limit chunking to flesh and veggy creatures until other kinds are supported.
        bool leaveGibs = (isFleshy || z->made_of("veggy"));
        if (leaveGibs) {
            make_gibs( z, gibAmount);
        }
    }
}
コード例 #3
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::normal(monster *z)
{
    if (g->u_see(z)) {
        add_msg(m_good, _("The %s dies!"),
                z->name().c_str()); //Currently it is possible to get multiple messages that a monster died.
    }

    m_size monSize = (z->type->size);
    bool leaveCorpse = !(z->type->has_flag(MF_VERMIN));

    // leave some blood if we have to
    if (!z->has_flag(MF_VERMIN)) {
        field_id type_blood = z->bloodType();
        if (type_blood != fd_null) {
            g->m.add_field(z->posx(), z->posy(), type_blood, 1);
        }
    }

    int maxHP = z->type->hp;
    if (!maxHP) {
        maxHP = 1;
    }

    float overflowDamage = -(z->hp);
    float corpseDamage = 5 * (overflowDamage / (maxHP * 2));

    if (leaveCorpse) {
        int gibAmount = int(floor(corpseDamage)) - 1;
        // allow one extra gib per 5 HP
        int gibLimit = 1 + (maxHP / 5.0);
        if (gibAmount > gibLimit) {
            gibAmount = gibLimit;
        }
        bool pulverized = (corpseDamage > 5 && overflowDamage > 150);
        if (!pulverized) {
            make_mon_corpse(z, int(floor(corpseDamage)));
        } else if (monSize >= MS_MEDIUM) {
            gibAmount += rng(1, 6);
        }
        // Limit chunking to flesh, veggy and insect creatures until other kinds are supported.
        bool leaveGibs = (z->made_of("flesh") || z->made_of("hflesh") || z->made_of("veggy") ||
                          z->made_of("iflesh"));
        if (leaveGibs) {
            make_gibs( z, gibAmount );
        }
    }
}
コード例 #4
0
ファイル: mondeath.cpp プロジェクト: ymber/Cataclysm-DDA
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() );
    }

    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, static_cast<int>( std::floor( corpse_damage * itype::damage_scale ) ) );
    }
    // if mdeath::splatter was set along normal makes sure it is not called twice
    bool splatt = false;
    for( const auto &deathfunction : z.type->dies ) {
        if( deathfunction == mdeath::splatter ) {
            splatt = true;
        }
    }
    if( !splatt ) {
        splatter( z );
    }
}
コード例 #5
0
ファイル: mondeath.cpp プロジェクト: AreasAside/Cataclysm-DDA
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 );
            }
        }
    }
}