void Creature::bleed() const { g->m.add_splatter( bloodType(), pos() ); }
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 ); } } } }