/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: hdavid, amaechler */ #include "lightning_effect.h" #include "state.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "util/loading/resource_manager.h" #include "effects/billboard.h" #include "glincl.h" #include "parser/tinyxml/tinyxml.h" #include "shell_command.h" #include "light.h" #include "cloud_effect.h" SHELL_COMMAND(activate, LightningEffect, activateLightning); SHELL_COMMAND(deactivate, LightningEffect, deactivateLightning); using namespace std; CREATE_FACTORY(LightningEffect, CL_LIGHTNING_EFFECT); LightningEffect::LightningEffect(const TiXmlElement* root) { this->setClassID(CL_LIGHTNING_EFFECT, "LightningEffect"); this->init(); if (root != NULL) this->loadParams(root); if(this->lightningActivate) this->activate(); } LightningEffect::~LightningEffect() { this->deactivate(); } void LightningEffect::loadParams(const TiXmlElement* root) { WeatherEffect::loadParams(root); LoadParam(root, "coord", this, LightningEffect, coord); LoadParam(root, "frequency", this, LightningEffect, setFlashFrequency); LoadParam(root, "const-time", this, LightningEffect, setFlashConstTime); LoadParam(root, "rising-time", this, LightningEffect, setFlashRisingTime); LoadParam(root, "size", this, LightningEffect, setFlashSize); LoadParam(root, "seed", this, LightningEffect, setFlashSeed); LOAD_PARAM_START_CYCLE(root, element); { LoadParam_CYCLE(element, "option", this, LightningEffect, setLightningOption); } LOAD_PARAM_END_CYCLE(element); } void LightningEffect::init() { //default values this->lightningActivate = false; this->flashFrequency = 4.0f; this->flashFrequencyBase = 4.0f; this->flashFrequencySeed = 2.0f; this->flashHoldTime = 0.1f; this->flashRisingTime = 0.03f; this->seedX = 500.f; this->seedZ = 1000.0f; this->width = 640.0f; this->height = 400.0f; this->seedWidth = 100.0f; this->seedHeight = 100.0f; this->lightningMove = false; this->mainPosX = 0; this->mainPosY = 100; this->mainPosZ = 5; this->time = 0.0; // initialize thunder billboard int i; for (i = 0; i < 4; i++) { this->thunderBolt[i] = new Billboard(NULL); this->thunderBolt[i]->setSize(this->width, this->height); this->thunderBolt[i]->setVisibiliy(false); } this->thunderTextureA = true; this->setTexture(); if (this->lightningMove) { this->cameraCoor = State::getCameraNode()->getAbsCoor(); for (i = 0; i < 4; i++) this->thunderBolt[i]->setAbsCoor(this->cameraCoor.x + this->mainPosX, this->mainPosY, this->cameraCoor.z + this->mainPosZ); } else for (i = 0; i < 4; i++) this->thunderBolt[i]->setAbsCoor(this->mainPosX, this->mainPosY, this->mainPosZ); this->flashLight = new Light(); this->flashLight->setDiffuseColor(0,0,0); this->flashLight->setSpecularColor(0,0,0); //load sound if (this->thunderBuffer != NULL) ResourceManager::getInstance()->unload(this->thunderBuffer); this->thunderBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/atmosphere/thunder.wav", WAV); } void LightningEffect::coord(float x, float y, float z) { int i; if (this->lightningMove) { this->cameraCoor = State::getCameraNode()->getAbsCoor(); for (i = 0; i < 4; i++) this->thunderBolt[i]->setAbsCoor(this->cameraCoor.x+x, y, this->cameraCoor.z+z); } else for (i = 0; i < 4; i++) this->thunderBolt[i]->setAbsCoor(x, y, z); this->mainPosX = x; this->mainPosY = y; this->mainPosZ = z; } void LightningEffect::setFlashSize(float width, float height, float seedWidth, float seedHeight) { this->width = width; this->height = height; this->seedWidth = seedWidth; this->seedHeight = seedHeight; int i; for (i = 0; i < 4; i++) this->thunderBolt[i]->setSize(this->width, this->height); } void LightningEffect::activate() { PRINTF(3)( "Activating LightningEffect\n" ); this->lightningActivate = true; this->time = 0; } void LightningEffect::deactivate() { PRINTF(3)("Deactivating LightningEffect\n"); this->lightningActivate = false; int i; for (i = 0; i < 4; i++) this->thunderBolt[i]->setVisibiliy(false); } void LightningEffect::tick (float dt) { if(!lightningActivate) return; this->time += dt; float x; x = (float)rand()/(float)RAND_MAX; if( this->time > this->flashFrequency) { // Reset timer this->time = 0.0f; // Move thunderBolt to start position this->flashLight->setAbsCoor(this->thunderBolt[0]->getAbsCoor().x, this->thunderBolt[0]->getAbsCoor().y, this->thunderBolt[0]->getAbsCoor().z); // Start a flash & lightning cycle this->thunderBolt[0]->setVisibiliy(true); // Lighten up environment this->flashLight->setDiffuseColor(1,1,1); this->flashLight->setSpecularColor(1,1,1); CloudEffect::flashSky(0.02); // Play thunder sound this->soundSource.play(this->thunderBuffer); } if( this->thunderBolt[0]->isVisible() && this->time > this->flashRisingTime*1/3 ) { this->thunderBolt[0]->setVisibiliy(false); this->thunderBolt[1]->setVisibiliy(true); } else if( this->thunderBolt[1]->isVisible() && this->time > this->flashRisingTime*2/3 ) { this->thunderBolt[1]->setVisibiliy(false); this->thunderBolt[2]->setVisibiliy(true); } else if( this->thunderBolt[2]->isVisible() && this->time > this->flashRisingTime) { this->thunderBolt[2]->setVisibiliy(false); this->thunderBolt[3]->setVisibiliy(true); } if( this->thunderBolt[3]->isVisible() && this->time > this->flashHoldTime) { this->thunderBolt[3]->setVisibiliy(false); this->time = 0.0f; this->flashLight->setDiffuseColor(0,0,0); this->flashLight->setSpecularColor(0,0,0); CloudEffect::changeSkyColor(Vector(0,0,1), 0.02); this->newCoordinates(); } } void LightningEffect::newCoordinates() { float posX, posZ; if(this->lightningMove) { this->cameraCoor = State::getCameraNode()->getAbsCoor(); posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX + this->cameraCoor.x; posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX + this->cameraCoor.z; } else { posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX; posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX; } this->switchTexture(); int i; for (i = 0; i < 4; i++) this->thunderBolt[i]->setAbsCoor(posX, this->mainPosY, posZ); this->flashFrequency = this->flashFrequencyBase + this->flashFrequencySeed * (float)rand()/(float)RAND_MAX; float w = this->width + this->seedWidth * (float)rand()/(float)RAND_MAX; float h = this->height + this->seedHeight * (float)rand()/(float)RAND_MAX; for (i = 0; i < 4; i++) this->thunderBolt[i]->setSize(w, h); } void LightningEffect::setTexture() { if (this->thunderTextureA) { this->thunderBolt[0]->setTexture("maps/thunderbA1.png"); this->thunderBolt[1]->setTexture("maps/thunderbA2.png"); this->thunderBolt[2]->setTexture("maps/thunderbA3.png"); this->thunderBolt[3]->setTexture("maps/thunderbA4.png"); } else { this->thunderBolt[0]->setTexture("maps/thunderbB1.png"); this->thunderBolt[1]->setTexture("maps/thunderbB2.png"); this->thunderBolt[2]->setTexture("maps/thunderbB3.png"); this->thunderBolt[3]->setTexture("maps/thunderbB4.png"); } } void LightningEffect::switchTexture() { if (this->thunderTextureA) this->thunderTextureA = false; else this->thunderTextureA = true; this->setTexture(); }