SmokeParticle::SmokeParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const color_t hue_adjust, const color_t saturation_adjust, const coord_t _sqrt_scale, const coord_t _max_size, const coord_t size_scalar, const alpha_t alpha_scale) : Particle(_effect, _mover, _pos, _velocity, size_scalar * (0.5f + randcoord())) { sqrt_scale = _sqrt_scale; max_size = _max_size; const color_t color_scale= square(randcolor(0.6)); color_t hue, saturation, value; hue = randcolor(1.0); // saturation = 1.0 - (color_scale + 0.15) / (0.15 + color_scale + square(randcolor(0.15))); saturation = color_scale; value = square(randcolor(0.15)) + color_scale + 0.15; // color[0] = square(randcolor(0.15)) + color_scale + 0.15; // color[1] = square(randcolor(0.15)) + color_scale + 0.15; // color[2] = square(randcolor(0.15)) + color_scale + 0.15; hue += hue_adjust; if (hue > 1.0) hue -= 1.0; saturation = std::min(1.0f, saturation * saturation_adjust); hsv_to_rgb(hue, saturation, value, color[0], color[1], color[2]); alpha = std::min(1.0f, (0.05f + randcoord(0.1f)) * alpha_scale); flare_max = 1.0; flare_exp = 1.0; flare_frequency = 1.0; state = 0; }
CloudEffect::CloudEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const color_t _hue_adjust, const color_t _saturation_adjust, const float _density, BoundingRange* bounding_range, const Uint16 _LOD) { if (EC_DEBUG) std::cout << "CloudEffect (" << this << ") created (" << *_pos << ", " << bounding_range->get_radius(0.0) << ")." << std::endl; base = _base; dead = _dead; pos = _pos; center = *pos; hue_adjust = _hue_adjust; saturation_adjust = _saturation_adjust; LOD = base->last_forced_LOD; desired_LOD = _LOD; bounds = bounding_range; mover = new BoundingMover(this, center, bounding_range, 1.0); spawner = new NoncheckingFilledBoundingSpawner(bounding_range); // count = (int)(spawner->get_area() * 0.03 * (LOD + 1)); count = (int)(MAX_DRAW_DISTANCE_SQUARED * PI * 0.03 * (LOD + 1)); if (count < 21) count = 21; alpha = 0.1725 / (1.0 / _density + 0.15); size_scalar = 110.0 * invsqrt(LOD + 1); for (int i = 0; i < count; i++) { Vec3 coords = spawner->get_new_coords(); if (coords.x == -32768.0) break; coords += center + Vec3(0.0, randcoord(5.0), 0.0); Vec3 velocity; velocity.randomize(0.15); velocity.y /= 3; const coord_t size = size_scalar + randcoord(size_scalar); Particle * p = new CloudParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, center.y, center.y + 20.0, size, alpha); if (!base->push_back_particle(p)) break; } // Load one neighbor for each one. It'll get more on its own. for (std::map<Particle*, bool>::iterator iter = particles.begin(); iter != particles.end(); iter++) { CloudParticle* p = (CloudParticle*)iter->first; CloudParticle* next; std::map<Particle*, bool>::iterator iter2 = iter; iter2++; if (iter2 != particles.end()) next = (CloudParticle*)iter2->first; else next = (CloudParticle*)particles.begin()->first; p->neighbors.push_back(next); next->add_incoming_neighbor(p); } }
CandleParticle::CandleParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const color_t hue_adjust, const color_t saturation_adjust, const float _scale, const Uint16 _LOD) : Particle(_effect, _mover, _pos, _velocity) { LOD = _LOD; color_t hue, saturation, value; hue = 0.03 + randcolor(0.08); saturation = 0.78; value = 0.9; hue += hue_adjust; if (hue > 1.0) hue -= 1.0; saturation *= saturation_adjust; if (saturation > 1.0) saturation = 1.0; hsv_to_rgb(hue, saturation, value, color[0], color[1], color[2]); size = 6.0 * (2.0 + randcoord()) / (LOD + 2); alpha = 0.4 * 5 / size / (LOD + 2); if (alpha > 1.0) alpha = 1.0; size *= _scale; flare_max = 1.0; flare_exp = 0.0; flare_frequency = 2.0; state = ((rand() % 3) == 0); }
bool TeleporterEffect::idle(const Uint64 usec) { if ((recall) && (particles.size() == 0)) return false; if (recall) return true; while (((int)particles.size() < LOD * 50) && (pow_randfloat((float)usec / 100000 * LOD) < 0.5)) { const Vec3 coords = spawner->get_new_coords() + *pos + Vec3(0.0, randcoord() * randcoord() * 8.0 * sqrt_LOD, 0.0); Vec3 velocity; velocity.randomize(0.2); Particle * p = new TeleporterParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, size_scalar); if (!base->push_back_particle(p)) break; } for (int i = 0; i < (int)targets.size();) { std::vector< std::pair<float *, Uint64> >::iterator iter = targets.begin() + i; Uint64 age = get_time() - iter->second; if (age < 500000) { *(iter->first) = 1.0 - (age / 500000.0);; i++; } else if (age < 1000000) { *(iter->first) = (age - 500000.0) / 500000.0;; i++; } else { *(iter->first) = 1.0; targets.erase(iter); } } return true; }
SwordParticle::SwordParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, const color_t red, const color_t green, const color_t blue, TextureEnum _texture, const Uint16 _LOD) : Particle(_effect, _mover, _pos, _velocity, std::min(1.0f, _size * (0.2f + randcoord()))) { color[0] = std::max(0.0f, std::min(1.0f, red + randcolor(0.25f) - 0.125f)); color[1] = std::max(0.0f, std::min(1.0f, green + randcolor(0.25f) - 0.125f)); color[2] = std::max(0.0f, std::min(1.0f, blue + randcolor(0.25f) - 0.125f)); texture = _texture; alpha = _alpha; velocity /= size; flare_max = 1.6; flare_exp = 0.2; flare_frequency = 2.0; LOD = _LOD; }
HarvestingParticle::HarvestingParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, const color_t red, const color_t green, const color_t blue, TextureEnum _texture, const Uint16 _LOD, const HarvestingEffect::HarvestingType _type) : Particle(_effect, _mover, _pos, _velocity, _size * (0.5 + randcoord()) * 15 / (_LOD + 5)) { type = _type; color[0] = red; color[1] = green; color[2] = blue; texture = _texture; alpha = _alpha; flare_max = 5.0; flare_exp = 0.1; flare_frequency = 3.0; LOD = _LOD; state = 0; }
BreathParticle::BreathParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, const color_t red, const color_t green, const color_t blue, TextureEnum _texture, const Uint16 _LOD, const BreathEffect::BreathType _type) : Particle(_effect, _mover, _pos, _velocity, _size * (0.2 + randcoord()) * 15 / _LOD) { type = _type; color[0] = red; color[1] = green; color[2] = blue; texture = _texture; // alpha = _alpha; alpha = _alpha * 2 / size; flare_max = 8.0; flare_exp = 0.5; flare_frequency = 3.0; LOD = _LOD; state = 0; }
TeleporterParticle::TeleporterParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const color_t hue_adjust, const color_t saturation_adjust, const coord_t size_scalar) : Particle(_effect, _mover, _pos, _velocity, size_scalar * (0.5 + 1.5 * randcoord())) { color_t hue, saturation, value; hue = randcolor(1.0); saturation = randfloat(0.2); value = 0.9; hue += hue_adjust; if (hue > 1.0) hue -= 1.0; saturation = std::min(1.0f, saturation * saturation_adjust); hsv_to_rgb(hue, saturation, value, color[0], color[1], color[2]); alpha = std::min(1.0f, 5.0f / size); velocity /= size; flare_max = 1.6; flare_exp = 0.2; flare_frequency = 2.0; }
ImpactParticle::ImpactParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, const color_t red, const color_t green, const color_t blue, TextureEnum _texture, const Uint16 _LOD, const ImpactEffect::ImpactType _type) : Particle(_effect, _mover, _pos, _velocity, (0.3 + randcoord()) * 15 / 3.16 / std::sqrt(_LOD)) { type = _type; color[0] = red; color[1] = green; color[2] = blue; texture = _texture; alpha = _alpha; velocity /= size; size *= _size; // std::cout << ": " << velocity << std::endl; flare_max = 1.0; flare_exp = 0.1; flare_frequency = 50.0; LOD = _LOD; state = 0; }
FountainParticle::FountainParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const color_t hue_adjust, const color_t saturation_adjust, const coord_t _base_height, const bool _backlight, const float _sqrt_scale, const coord_t _max_size, const coord_t size_scalar) : Particle(_effect, _mover, _pos, _velocity) { base_height = _base_height; backlight = _backlight; sqrt_scale = _sqrt_scale; max_size = _max_size; color_t hue, saturation, value; hue = 0.6; saturation = 0.3; value = 0.85; hue += hue_adjust; if (hue > 1.0) hue -= 1.0; saturation *= saturation_adjust; if (saturation > 1.0) saturation = 1.0; hsv_to_rgb(hue, saturation, value, color[0], color[1], color[2]); color[0] *= 2.0; color[1] *= 2.0; color[2] *= 2.0; size = size_scalar * (0.5 + 5 * randcoord()); alpha = sqrt_scale * 3.5 / size; if (backlight) alpha /= 9; if (alpha > 1.0) alpha = 1.0; flare_max = 1.5; flare_exp = 0.3; flare_frequency = 5.0; state = 0; }
MissileParticle::MissileParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, const color_t red, const color_t green, #ifdef NEW_TEXTURES const color_t blue, TextureEnum _texture, const Uint16 _LOD, #else /* NEW_TEXTURES */ const color_t blue, Texture* _texture, const Uint16 _LOD, #endif /* NEW_TEXTURES */ const MissileEffect::MissileType _type) : Particle(_effect, _mover, _pos, _velocity) { color[0] = red + randcolor(0.25) - 0.125; if (color[0] > 1.0) color[0] = 1.0; else if (color[0] < 0.0) color[0] = 0.0; color[1] = green + randcolor(0.25) - 0.125; if (color[1] > 1.0) color[1] = 1.0; else if (color[1] < 0.0) color[1] = 0.0; color[2] = blue + randcolor(0.25) - 0.125; if (color[2] > 1.0) color[2] = 1.0; else if (color[2] < 0.0) color[2] = 0.0; texture = _texture; size = std::max(1.0f, (float)(_size * (0.25 + randcoord(1.25)))); // size >= 1.0 alpha = std::max(0.25f, (float)_alpha); // at least 25% alpha velocity /= size; flare_max = 1.6; flare_exp = 0.2; flare_frequency = 2.0; LOD = _LOD; type = _type; }
ImpactEffect::ImpactEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const Vec3 _angle, const ImpactType _type, const Uint16 _LOD, const float _strength) { if (EC_DEBUG) std::cout << "ImpactEffect (" << this << ") created." << std::endl; base = _base; dead = _dead; pos = _pos; center = *pos; angle = _angle; type = _type; LOD = base->last_forced_LOD; desired_LOD = _LOD; spawner = NULL; bounds = NULL; mover = NULL; strength = _strength; const coord_t size_scalar = strength * 1.3; const coord_t vel_scalar= std::sqrt(strength) * 0.44; switch (type) { case MAGIC_PROTECTION: { angle.normalize(2.0 * vel_scalar); mover = new ParticleMover(this); for (int i = 0; i < 50 * LOD; i++) { Vec3 velocity = -angle; Vec3 offset; offset.randomize(0.3); velocity += offset; Particle * p = new ImpactParticle(this, mover, center, velocity, 0.3 * size_scalar, 1.0, 0.7, 0.2, 0.4, EC_SHIMMER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case SHIELD: { angle.normalize(2.0 * vel_scalar); mover = new ParticleMover(this); for (int i = 0; i < 50 * LOD; i++) { Vec3 velocity = -angle; Vec3 offset; offset.randomize(0.3); velocity += offset; Particle * p = new ImpactParticle(this, mover, center, velocity, 0.3 * size_scalar, 1.0, 0.9, 0.9, 0.9, EC_SHIMMER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case MAGIC_IMMUNITY: { angle.normalize(2.5 * vel_scalar); mover = new ParticleMover(this); for (int i = 0; i < 50 * LOD; i++) { Vec3 velocity = -angle; Vec3 offset; offset.randomize(0.4); velocity += offset; Particle * p = new ImpactParticle(this, mover, center, velocity, 0.35 * size_scalar, 1.0, randcolor(1.0), randcolor(1.0), randcolor(1.0), EC_VOID, LOD, type); if (!base->push_back_particle(p)) break; } break; } case POISON: { angle.normalize(1.0 * vel_scalar); mover = new ParticleMover(this); for (int i = 0; i < 50 * LOD; i++) { Vec3 velocity = -angle; Vec3 offset; offset.randomize(0.7); velocity += offset; Particle* p; if (randfloat() < 0.4) { p = new ImpactParticle(this, mover, center, velocity, 0.6 * size_scalar, 0.5, 0.2 + randcolor(0.2), 0.5 + randcolor(0.3), 0.2, EC_FLARE, LOD, type); p->state = 1; } else { p = new ImpactParticle(this, mover, center, velocity, 0.3 * size_scalar, 1.0, randcolor(0.1), 0.2 + randcolor(0.1), 0.2, EC_WATER, LOD, type); p->state = 0; } if (!base->push_back_particle(p)) break; } break; } case BLOOD: { angle.normalize(0.8 * vel_scalar); mover = new SimpleGravityMover(this); for (int i = 0; i < 20 * LOD; i++) { Vec3 velocity = -angle; Vec3 offset; offset.randomize(0.7); // std::cout << velocity << ", " << angle << ", " << vel_scalar << std::endl; velocity += offset; velocity.normalize(0.8 * vel_scalar); // std::cout << velocity << std::endl; Particle * p = new ImpactParticle(this, mover, center, velocity, square(square(randcoord(0.85))) * size_scalar, 0.5, 0.3 + randcolor(0.7), 0.15 + randcolor(0.1), 0.15 + randcolor(0.1), EC_WATER, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } break; } } }
bool CloudEffect::idle(const Uint64 usec) { if (recall && (particles.size() == 0)) return false; if (recall) return true; const int start_count = particles.size(); if (start_count == count) return true; if (particles.size()) { CloudParticle* last = (CloudParticle*)(particles.rbegin()->first); for (int i = count - (int)particles.size(); i >= 0; i--) { Vec3 coords = spawner->get_new_coords(); if (coords.x == -32768.0) continue; coords += center + Vec3(0.0, randcoord(5.0), 0.0); Vec3 velocity; velocity.randomize(0.15); velocity.y /= 3; const coord_t size = size_scalar + randcoord(size_scalar); CloudParticle * p = new CloudParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, center.y, center.y + 20.0, size, alpha); if (!base->push_back_particle(p)) break; p->neighbors.push_back(last); last->add_incoming_neighbor(p); } } else { for (int i = count - (int)particles.size(); i >= 0; i--) { Vec3 coords = spawner->get_new_coords(); if (coords.x == -32768.0) continue; coords += center + Vec3(0.0, randcoord(5.0), 0.0); Vec3 velocity; velocity.randomize(0.15); velocity.y /= 3; const coord_t size = size_scalar + randcoord(size_scalar); Particle * p = new CloudParticle(this, mover, coords, velocity, hue_adjust, saturation_adjust, center.y, center.y + 20.0, size, alpha); if (!base->push_back_particle(p)) break; } // Load one neighbor for each one. It'll get more on its own. for (std::map<Particle*, bool>::iterator iter = particles.begin(); iter != particles.end(); iter++) { CloudParticle* p = (CloudParticle*)iter->first; CloudParticle* next; std::map<Particle*, bool>::iterator iter2 = iter; iter2++; if (iter2 != particles.end()) next = (CloudParticle*)iter2->first; else next = (CloudParticle*)particles.begin()->first; p->neighbors.push_back(next); next->add_incoming_neighbor(p); } } return true; }
BreathSmokeParticle::BreathSmokeParticle(Effect* _effect, ParticleMover* _mover, const Vec3 _pos, const Vec3 _velocity, const coord_t _size, const alpha_t _alpha, TextureEnum _texture, const Uint16 _LOD, const BreathEffect::BreathType _type) : Particle(_effect, _mover, _pos, _velocity) { texture = _texture; type = _type; switch (type) { case BreathEffect::FIRE: { const color_t color_scale= randcolor(0.1); color[0] = randcolor(0.1) + color_scale; color[1] = randcolor(0.1) + color_scale; color[2] = randcolor(0.1) + color_scale; break; } case BreathEffect::ICE: { const color_t color_scale= randcolor(0.2); color[0] = 0.3 + randcolor(0.1) + color_scale; color[1] = 0.3 + randcolor(0.1) + color_scale; color[2] = 1.0; break; } case BreathEffect::POISON: { const color_t color_scale= randcolor(0.1); color[0] = randcolor(0.0) + color_scale; color[1] = randcolor(0.0) + color_scale; color[2] = randcolor(0.0) + color_scale; texture = EC_SIMPLE; break; } case BreathEffect::MAGIC: { color[0] = randcolor(0.35); color[1] = randcolor(0.35); color[2] = randcolor(0.35); break; } case BreathEffect::LIGHTNING: // Impossible; lightning doesn't use smoke. { break; } case BreathEffect::WIND: { const color_t color_scale= randcolor(0.4); color[0] = randcolor(0.1) + color_scale; color[1] = randcolor(0.1) + color_scale; color[2] = randcolor(0.1) + color_scale; break; } } size = _size * (0.5 + randcoord()) * 10 / _LOD; alpha = _alpha; flare_max = 1.0; flare_exp = 1.0; flare_frequency = 1.0; state = 0; }
MineEffect::MineEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const MineType _type, const Uint16 _LOD) { if (EC_DEBUG) std::cout << "MineEffect (" << this << ") created (" << type << ")." << std::endl; base = _base; dead = _dead; pos = _pos; effect_center = *pos; type = _type; LOD = base->last_forced_LOD; desired_LOD = _LOD; spawner = NULL; bounds = NULL; mover = NULL; spawner2 = NULL; mover2 = NULL; switch (type) { case DETONATE_MAGIC_IMMUNITY_REMOVAL: { spawner = new FilledSphereSpawner(0.1); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 150) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(0.5); velocity.y = 0.2; Particle * p = #ifdef NEW_TEXTURES new MineParticle(this, mover, coords, velocity, 0.2, 1.0, 3.0, 3.0, 3.0, EC_SIMPLE, LOD, type); #else /* NEW_TEXTURES */ new MineParticle(this, mover, coords, velocity, 0.2, 1.0, 3.0, 3.0, 3.0, &(base->TexSimple), LOD, type); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } break; } case DETONATE_UNINVIZIBILIZER: { effect_center.y += 1.8; spawner = new HollowDiscSpawner(0.3); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 200) { Vec3 coords = spawner->get_new_coords(); Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); coords += effect_center; coords.y = randfloat(1.8); Particle * p = #ifdef NEW_TEXTURES new MineParticle(this, mover, coords, velocity, 1.2, 1.0, 3.0, 3.0, 3.0, EC_SIMPLE, LOD, type); #else /* NEW_TEXTURES */ new MineParticle(this, mover, coords, velocity, 1.2, 1.0, 3.0, 3.0, 3.0, &(base->TexSimple), LOD, type); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } break; } case DETONATE_MANA_DRAINER: { effect_center.y += 1.6; spawner = new HollowDiscSpawner(0.3); mover = new SimpleGravityMover(this); while ((int)particles.size() < LOD * 50) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); Particle * p = #ifdef NEW_TEXTURES new MineParticle(this, mover, coords, velocity, 0.3, 1.0, 0.8, 0.35, 0.7, EC_SIMPLE, LOD, type); #else /* NEW_TEXTURES */ new MineParticle(this, mover, coords, velocity, 0.3, 1.0, 0.8, 0.35, 0.7, &(base->TexSimple), LOD, type); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } break; } case DETONATE_MANA_BURNER: { effect_center.y += 1.0; spawner = new FilledSphereSpawner(0.5); mover = new GravityMover(this, &effect_center, 8e9); while ((int)particles.size() < LOD * 100) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(0.9); Particle * p = #ifdef NEW_TEXTURES new MineParticle(this, mover, coords, velocity, 0.5, 0.5, 0.8, 0.35, 0.7, EC_TWINFLARE, LOD, type); #else /* NEW_TEXTURES */ new MineParticle(this, mover, coords, velocity, 0.5, 0.5, 0.8, 0.35, 0.7, &(base->TexTwinflare), LOD, type); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } break; } case DETONATE_CALTROP: case DETONATE_CALTROP_POISON: { effect_center.y += 0.05; mover = new SimpleGravityMover(this); spawner = new HollowSphereSpawner(0.1); for (int i = 0; i < LOD * 10; i++) { const Vec3 coords = spawner->get_new_coords() + effect_center; const Vec3 velocity(0.0, 5.0, 0.0); #ifdef NEW_TEXTURES Particle* p = new MineParticle(this, mover, coords, velocity, 0.75, 0.6, 0.4, (type == DETONATE_CALTROP ? 0.3 : 0.5), 0.3, EC_TWINFLARE, LOD, type); #else /* NEW_TEXTURES */ Particle* p = new MineParticle(this, mover, coords, velocity, 0.75, 0.6, 0.4, (type == DETONATE_CALTROP ? 0.3 : 0.5), 0.3, &(base->TexTwinflare), LOD, type); #endif /* NEW_TEXTURES */ p->state = 1; if (!base->push_back_particle(p)) break; } break; } case DETONATE_TRAP: { effect_center.y += 1.25; mover = new OrbitalMover(this, effect_center); spawner = new HollowSphereSpawner(1.25); Particle* p; for (int i = 0; i < LOD * 100; i++) { Vec3 c = effect_center; c.y = -0.3 + (i * 0.05); Vec3 vel; vel.randomize(); vel.normalize(2.0); vel *= randfloat() * 4.0; #ifdef NEW_TEXTURES p = new MineParticle(this, mover, c, vel, 0.2, 1.0, 1.0, 1.0, 1.0, EC_VOID, LOD, type); #else /* NEW_TEXTURES */ p = new MineParticle(this, mover, c, vel, 0.2, 1.0, 1.0, 1.0, 1.0, &(base->TexVoid), LOD, type); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; dynamic_cast<OrbitalMover*>(mover)->setParticleData(p, OrbitalParticleData(i, 10, 0.45, 10) ); } break; } case DETONATE_TYPE1_SMALL: case DETONATE_TYPE1_MEDIUM: case DETONATE_TYPE1_LARGE: { spawner = new FilledSphereSpawner(0.1); mover = new ParticleMover(this); const float scale = (type == DETONATE_TYPE1_SMALL ? 0.75 : type == DETONATE_TYPE1_MEDIUM ? 1.25 : 2.0); Vec3 wind; wind.randomize(); wind.normalize(0.25); wind.y = 0; for (int i = 0; i < LOD * 100 * scale; i++) { Vec3 coords = spawner->get_new_coords(); Vec3 velocity = coords * 10.0 * sqrt(scale); velocity.y = fabs(velocity.y) * 3.0f; coords += effect_center; coords.y -= 0.1; #ifdef NEW_TEXTURES Particle * p = new MineParticleFire(this, mover, coords, velocity, 0.5, 1.0, 1.0, randcolor(0.75), 0.0, EC_FLARE, LOD); #else /* NEW_TEXTURES */ Particle * p = new MineParticleFire(this, mover, coords, velocity, 0.5, 1.0, 1.0, randcolor(0.75), 0.0, &(base->TexFlare), LOD); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } spawner = new FilledSphereSpawner(0.5 * std::sqrt(scale)); for (int i = 0; i < LOD * 32 * scale; i++) { Vec3 coords = spawner->get_new_coords(); Vec3 velocity; coords += effect_center; float grey = randcolor(0.5); velocity.randomize(); velocity.normalize(0.25 * scale); velocity.y = fabs(velocity.y) * 6.0f; velocity += wind; #ifdef NEW_TEXTURES Particle *p = new MineParticleSmoke(this, mover, coords, velocity, 3.0 + randcoord(3.0 * scale), 0.0, grey, grey, grey, EC_SIMPLE, LOD); #else /* NEW_TEXTURES */ Particle *p = new MineParticleSmoke(this, mover, coords, velocity, 3.0 + randcoord(3.0 * scale), 0.0, grey, grey, grey, &(base->TexSimple), LOD); #endif /* NEW_TEXTURES */ if (!base->push_back_particle(p)) break; } break; } } }
HarvestingEffect::HarvestingEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const HarvestingType _type, const Uint16 _LOD) { if (EC_DEBUG) std::cout << "HarvestingEffect (" << this << ") created (" << type << ")." << std::endl; base = _base; dead = _dead; pos = _pos; effect_center = *pos; type = _type; LOD = base->last_forced_LOD; desired_LOD = _LOD; spawner = NULL; bounds = NULL; mover = NULL; spawner2 = NULL; mover2 = NULL; direction = Vec3(0.0, 0.0, 0.0); switch (type) { case TOOL_BREAK: { // handled in other constructor break; } case RADON_POUCH: { effect_center.y += 0.5; spawner = new FilledSphereSpawner(0.9); mover = new GravityMover(this, &effect_center, 8e9); while ((int)particles.size() < LOD * 50) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(0.8); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 5.25, 0.5, 0.6, 0.7, 0.2, EC_FLARE, LOD, type); p->state = 0; if (!base->push_back_particle(p)) break; } while ((int)particles.size() < LOD * 100) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(1.5); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 4.5, 0.5 + randalpha(0.4), 0.7, 0.6, 0.5, EC_WATER, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } break; } case CAVERN_WALL: { effect_center.y += 15.0; spawner = new FilledSphereSpawner(1.0); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 50) { Vec3 coords = spawner->get_new_coords(); coords.y *= 8.0; Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); velocity.y *= 3.0; velocity.y -= 9.0; coords += effect_center; const color_t scalar= randcolor(0.4); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 8.0 + randcoord(12.0), 1.0, scalar + randcolor(0.1), scalar + randcolor(0.1), scalar + randcolor(0.1), EC_SIMPLE, LOD, type); if (!base->push_back_particle(p)) break; } while ((int)particles.size() < LOD * 100) { Vec3 coords = spawner->get_new_coords(); coords.y *= 8.0; Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); velocity.y *= 3.0; velocity.y -= 9.0; coords += effect_center; Particle * p = new HarvestingParticle(this, mover, coords, velocity, 3.0 + randcoord(6.0), 0.4 + randalpha(0.4), 0.2 + randcolor(0.2), 0.2 + randcolor(0.2), 0.2 + randcolor(0.2), EC_WATER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case MOTHER_NATURE: { effect_center.y += 0.2; spawner = new HollowDiscSpawner(0.1); mover = new SpiralMover(this, &effect_center, 18.0, 11.0); while ((int)particles.size() < LOD * 100) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(0.3); velocity.y *= 3; velocity.y += 1.4; Particle * p = new HarvestingParticle(this, mover, coords, velocity, 3.0, 0.2, 1.0, 0.5 + randcolor(0.5), 0.5, EC_TWINFLARE, LOD, type); if (!base->push_back_particle(p)) break; } break; } case QUEEN_OF_NATURE: { effect_center.y += 0.2; spawner = new FilledDiscSpawner(0.5); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 100) { Vec3 coords = spawner->get_new_coords() + effect_center; coords.y += (coord_t)(randfloat(2.0) * randfloat(2.0) * randfloat(2.0)); const Vec3 velocity(0.0, 0.0, 0.0); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 2.0 + randcoord(1.0), 1.0, randcolor(1.0), randcolor(1.0), randcolor(1.0), EC_SHIMMER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case BEES: { spawner = new FilledSphereSpawner(0.75); mover = new GravityMover(this, &effect_center, 8e9); direction.randomize(); direction.y = 0; while ((int)particles.size() < LOD * 4) { const Vec3 coords = spawner->get_new_coords() + effect_center - direction; Vec3 velocity; velocity.randomize(); velocity.normalize(0.75); velocity.x += randfloat(direction.x); velocity.z += randfloat(direction.z); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 0.5 + randfloat(0.25), 1.0, 0.9, 0.7, 0.3, EC_TWINFLARE, LOD, type); if (!base->push_back_particle(p)) break; } break; } case BAG_OF_GOLD: { mover = new GravityMover(this, &effect_center, 2e10); spawner = new HollowSphereSpawner(0.3); for (int i = 0; i < LOD * 60; i++) { Vec3 coords = spawner->get_new_coords(); const Vec3 velocity = coords / 10.0; coords += effect_center; Particle* p = new HarvestingParticle(this, mover, coords, velocity, 1.05, 0.75, randcolor(0.3) + 0.7, randcolor(0.3) + 0.5, randcolor(0.3) + 0.3, EC_FLARE, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } Particle* p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.0, 0.0), 8.0, 1.0, 0.8, 0.7, 0.3, EC_SHIMMER, LOD, type); base->push_back_particle(p); break; } case RARE_STONE: { mover = new ParticleMover(this); spawner = new HollowSphereSpawner(0.3); for (int i = 0; i < LOD * 60; i++) { Vec3 coords = spawner->get_new_coords(); const Vec3 velocity = coords / 10.0; coords += effect_center; Particle* p = new HarvestingParticle(this, mover, coords, velocity, 0.75, 0.05, randcolor(0.3) + 0.7, randcolor(0.3) + 0.5, randcolor(0.3) + 0.3, EC_FLARE, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } Particle* p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.0, 0.0), 7.5, 1.0, 1.0, 1.0, 1.0, EC_VOID, LOD, type); if (!base->push_back_particle(p)) break; p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.01, 0.0), 7.5, 1.0, 1.0, 1.0, 1.0, EC_VOID, LOD, type); base->push_back_particle(p); break; } } }