void Creature::bleed() const
{
    g->m.add_splatter( bloodType(), pos() );
}
Example #2
0
void monster::explode()
{
    if( is_hallucination() ) {
        //Can't gib hallucinations
        return;
    }
    if( type->has_flag( MF_NOGIB ) || type->has_flag( MF_VERMIN ) ) {
        return;
    }
    // Send body parts and blood all over!
    const itype_id meat = type->get_meat_itype();
    const field_id type_blood = bloodType();
    const field_id type_gib = gibType();
    if( meat != "null" || type_blood != fd_null || type_gib != fd_null ) {
        // Only create chunks if we know what kind to make.
        int num_chunks = 0;
        switch( type->size ) {
            case MS_TINY:
                num_chunks = 1;
                break;
            case MS_SMALL:
                num_chunks = 2;
                break;
            case MS_MEDIUM:
                num_chunks = 4;
                break;
            case MS_LARGE:
                num_chunks = 8;
                break;
            case MS_HUGE:
                num_chunks = 16;
                break;
        }

        for( int i = 0; i < num_chunks; i++ ) {
            int tarx = _posx + rng( -3, 3 ), tary = _posy + rng( -3, 3 );
            std::vector<point> traj = line_to( _posx, _posy, tarx, tary, 0 );

            for( size_t j = 0; j < traj.size(); j++ ) {
                tarx = traj[j].x;
                tary = traj[j].y;
                if( one_in( 2 ) && type_blood != fd_null ) {
                    g->m.add_field( tarx, tary, type_blood, 1 );
                } else if( type_gib != fd_null ) {
                    g->m.add_field( tarx, tary, type_gib, rng( 1, j + 1 ) );
                }
                if( g->m.move_cost( tarx, tary ) == 0 ) {
                    if( !g->m.bash( tarx, tary, 3 ).second ) {
                        // 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 ) {
                            tarx = traj[j - 1].x;
                            tary = traj[j - 1].y;
                        } else {
                            tarx = -1;
                        }
                        break;
                    }
                }
            }
            if( meat != "null" && tarx != -1 ) {
                g->m.spawn_item( tarx, tary, meat, 1, 0, calendar::turn );
            }
        }
    }
}