Laser.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <actions/Laser.h>
00022 #include <actions/TankDamage.h>
00023 #include <engine/ScorchedContext.h>
00024 #include <engine/ActionController.h>
00025 #include <weapons/AccessoryStore.h>
00026 #include <weapons/Shield.h>
00027 #include <actions/ShieldHit.h>
00028 #include <target/TargetContainer.h>
00029 #include <target/TargetShield.h>
00030 #include <target/TargetLife.h>
00031 #include <target/TargetSpace.h>
00032 #include <common/Defines.h>
00033 #include <common/Logger.h>
00034 #ifndef S3D_SERVER
00035         #include <GLEXT/GLState.h>
00036 #endif
00037 #include <math.h>
00038 #include <set>
00039 
00040 Laser::Laser(Weapon *weapon, LaserParams *params,
00041                 FixedVector &position, FixedVector &direction,
00042                 WeaponFireContext &weaponContext) :
00043         ActionReferenced("Laser"),
00044         params_(params),
00045         totalTime_(0),
00046         drawLength_(0),
00047         firstTime_(true),
00048         weaponContext_(weaponContext), 
00049         weapon_(weapon),
00050         position_(position), 
00051         direction_(direction)
00052 {
00053 }
00054 
00055 Laser::~Laser()
00056 {
00057         delete params_;
00058 }
00059 
00060 void Laser::init()
00061 {
00062         fixed per = direction_.Magnitude() / 50;
00063         length_ = params_->getMinimumDistance() + 
00064                 (params_->getMaximumDistance() - params_->getMinimumDistance()) * per;
00065         damage_ = params_->getMinimumHurt() + 
00066                 (params_->getMaximumHurt() - params_->getMinimumHurt()) * (fixed(1) - per);
00067 
00068         FixedVector dir = direction_.Normalize();
00069 
00070         angXY_ = 180.0f - atan2f(dir[0].asFloat(), dir[1].asFloat()) / 3.14f * 180.0f;
00071         angYZ_ = acosf(dir[2].asFloat()) / 3.14f * 180.0f;
00072 }
00073 
00074 std::string Laser::getActionDetails()
00075 {
00076         return S3D::formatStringBuffer("%i,%i,%i %i,%i,%i %s",
00077                 position_[0].getInternal(), position_[1].getInternal(), position_[2].getInternal(),
00078                 direction_[0].getInternal(), direction_[1].getInternal(), direction_[2].getInternal(),
00079                 weapon_->getParent()->getName());
00080 }
00081 
00082 void Laser::simulate(fixed frameTime, bool &remove)
00083 {
00084         if (firstTime_)
00085         {
00086                 firstTime_ = false;
00087                 
00088                 // preset some values from the numberparser expressions
00089                 laserTime_ = params_->getTotalTime();
00090                 hurtRadius_ = params_->getHurtRadius();
00091 
00092                 if (damage_ > 0 && direction_.Magnitude() > 0)
00093                 {
00094                         std::set<unsigned int> damagedTargets_;
00095 
00096                         // Build a set of all tanks in the path of the laser
00097                         FixedVector pos = position_;
00098                         FixedVector dir = direction_.Normalize() / 4;
00099                         bool end = false;
00100                         while (!end)
00101                         {
00102                                 std::map<unsigned int, Target *> collisionTargets;
00103                                 context_->getTargetSpace().getCollisionSet(pos, 
00104                                         fixed(params_->getHurtRadius()), collisionTargets);
00105                                 std::map<unsigned int, Target *>::iterator itor;
00106                                 for (itor = collisionTargets.begin();
00107                                         itor != collisionTargets.end();
00108                                         itor++)
00109                                 {
00110                                         Target *current = (*itor).second;
00111                                         if (current->getAlive() &&
00112                                                 ((current->getPlayerId() != weaponContext_.getPlayerId()) ||
00113                                                 params_->getHurtFirer()))
00114                                         {
00115                                                 Shield::ShieldLaserProofType laserProof = Shield::ShieldLaserProofNone;
00116                                                 if (current->getShield().getCurrentShield())
00117                                                 {
00118                                                         Shield *shield = (Shield *)
00119                                                                 current->getShield().getCurrentShield()->getAction();
00120                                                         if (shield->getLaserProof() != Shield::ShieldLaserProofNone)
00121                                                         {
00122                                                                 laserProof = shield->getLaserProof();
00123                                                                 FixedVector offset = current->getLife().getTargetPosition() - pos;
00124                                                                 if (shield->inShield(offset))
00125                                                                 {
00126                                                                         context_->getActionController().addAction(
00127                                                                                 new ShieldHit(current->getPlayerId(), pos, 0));
00128 
00129                                                                         end = true;
00130                                                                         break;
00131                                                                 }
00132                                                         }
00133                                                 }
00134 
00135                                                 if (laserProof != Shield::ShieldLaserProofTotal)
00136                                                 {
00137                                                         FixedVector offset = current->getLife().getTargetPosition() - pos;
00138                                                         fixed targetDistance = offset.Magnitude();
00139 
00140                                                         if (targetDistance < params_->getHurtRadius() + 
00141                                                                 MAX(current->getLife().getSize()[0], current->getLife().getSize()[1]))
00142                                                         {
00143                                                                 damagedTargets_.insert(current->getPlayerId());
00144                                                         }
00145                                                 }
00146                                         }
00147                                 }
00148 
00149                                 if (!end)
00150                                 {
00151                                         pos += dir;
00152                                         drawLength_ = (pos - position_).Magnitude();
00153                                         if (drawLength_ > length_) end = true;
00154                                 }
00155                         }
00156 
00157                         // Subtract set amount from all tanks
00158                         std::set<unsigned int>::iterator itor;
00159                         for (itor = damagedTargets_.begin();
00160                                 itor != damagedTargets_.end();
00161                                 itor++)
00162                         {
00163                                 unsigned int damagedTarget = (*itor);
00164                                 context_->getActionController().addAction(
00165                                         new TankDamage(
00166                                                 weapon_, damagedTarget, weaponContext_,
00167                                                 damage_, false, false, false));
00168                         }
00169                 }
00170         }
00171 
00172         totalTime_ += frameTime;
00173 
00174         remove = (totalTime_ > laserTime_);
00175         Action::simulate(frameTime, remove);
00176 }
00177 
00178 void Laser::draw()
00179 {
00180 #ifndef S3D_SERVER
00181         if (!context_->getServerMode() && (drawLength_ > 0))
00182         {
00183                 static GLUquadric *obj = 0;
00184                 if (!obj)
00185                 {
00186                         obj = gluNewQuadric();
00187                 }
00188                 float timePer = (1.0f - totalTime_.asFloat() / laserTime_.asFloat()) * 0.5f;
00189                 float radius1 = 0.05f / 2.0f * hurtRadius_.asFloat();
00190                 float radius2 = 0.2f / 2.0f * hurtRadius_.asFloat();
00191 
00192                 GLState glState(GLState::TEXTURE_OFF | GLState::BLEND_ON);
00193                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00194                 glColor4f(1.0f, 1.0f, 1.0f,     timePer);
00195                 glPushMatrix();
00196                         glTranslatef(
00197                                 position_[0].asFloat(), 
00198                                 position_[1].asFloat(), 
00199                                 position_[2].asFloat());
00200                         glRotatef(angXY_, 0.0f, 0.0f, 1.0f);
00201                         glRotatef(angYZ_, 1.0f, 0.0f, 0.0f);
00202 
00203                         glColor4f(1.0f, 1.0f, 1.0f,     timePer);
00204                         gluCylinder(obj, radius1, radius1, drawLength_.asFloat(), 3, 1);
00205 
00206                         glColor4f(
00207                                 params_->getColor()[0],
00208                                 params_->getColor()[1],
00209                                 params_->getColor()[2],
00210                                 timePer);
00211                         gluCylinder(obj, radius2, radius2, drawLength_.asFloat(), 5, 1);
00212                 glPopMatrix();
00213                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00214         }
00215 #endif // #ifndef S3D_SERVER
00216 }

Generated on Mon Feb 16 15:14:48 2009 for Scorched3D by  doxygen 1.5.3