WeaponRoller.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 <weapons/WeaponRoller.h>
00022 #include <weapons/AccessoryStore.h>
00023 #include <weapons/Shield.h>
00024 #include <actions/ShotBounce.h>
00025 #include <common/Defines.h>
00026 #include <engine/ActionController.h>
00027 #include <target/TargetContainer.h>
00028 #include <target/TargetShield.h>
00029 #include <target/TargetLife.h>
00030 #include <landscapemap/LandscapeMaps.h>
00031 #include <math.h>
00032 
00033 REGISTER_ACCESSORY_SOURCE(WeaponRoller);
00034 
00035 WeaponRoller::WeaponRoller() : 
00036         shieldHurtFactor_(0), windFactor_(1), 
00037         maintainVelocity_(false), roll_(true),
00038         dampenVelocityExp_(1)
00039 {
00040 
00041 }
00042 
00043 WeaponRoller::~WeaponRoller()
00044 {
00045 
00046 }
00047 
00048 bool WeaponRoller::parseXML(AccessoryCreateContext &context, XMLNode *accessoryNode)
00049 {
00050         if (!Weapon::parseXML(context, accessoryNode)) return false;
00051 
00052         // Get number of rollers
00053         if (!accessoryNode->getNamedChild("numberrollers", numberRollers_)) return false;
00054 
00055         // Get life time
00056         if (!accessoryNode->getNamedChild("time", timeExp_)) return false;
00057 
00058     // Get the hurt factor (if any)
00059     accessoryNode->getNamedChild("shieldhurtfactor", shieldHurtFactorExp_, false);
00060 
00061         // Get the wind factor (if any)
00062         accessoryNode->getNamedChild("windfactor", windFactorExp_, false);
00063 
00064         // Get the maintianvelocity (if any)
00065         accessoryNode->getNamedChild("maintainvelocity", maintainVelocity_, false);
00066 
00067         // Get the velocity dampening factor (if any)
00068         accessoryNode->getNamedChild("dampenvelocity", dampenVelocityExp_, false);
00069 
00070         // Get if we are to roll
00071         accessoryNode->getNamedChild("roll", roll_, false);
00072 
00073         XMLNode *subNode = 0;
00074         if (!accessoryNode->getNamedChild("collisionaction", subNode)) return false;
00075 
00076         AccessoryPart *accessory = context.getAccessoryStore().
00077                 createAccessoryPart(context, parent_, subNode);
00078         if (!accessory || accessory->getType() != AccessoryPart::AccessoryWeapon)
00079         {
00080                 return subNode->returnError("Failed to find sub weapon, not a weapon");
00081         }
00082         collisionAction_ = (Weapon*) accessory;
00083 
00084         // Get the weapon model
00085         XMLNode *modelNode = 0;
00086         if (!accessoryNode->getNamedChild("rollermodel", modelNode)) return false;
00087         if (!rollerModelId_.initFromNode("data/accessories", modelNode)) return false;
00088 
00089         return true;
00090 }
00091 
00092 fixed WeaponRoller::getWindFactor(ScorchedContext &context)
00093 {
00094         return windFactor_;
00095 }
00096 
00097 fixed WeaponRoller::getTime(ScorchedContext &context)
00098 {
00099         return timeExp_.getValue(context);
00100 }
00101 
00102 fixed WeaponRoller::getShieldHurtFactor(ScorchedContext &context)
00103 {
00104         return shieldHurtFactor_;
00105 }
00106 
00107 void WeaponRoller::fireWeapon(ScorchedContext &context,
00108         WeaponFireContext &weaponContext, FixedVector &oldposition, FixedVector &velocity)
00109 {
00110         // Get the values from the numberparser expressions
00111         // leaving time in the sim loop so that individual rollers can
00112         //  have different times
00113         // time_ = timeExp_.getValue(context);
00114         
00115         shieldHurtFactor_ = shieldHurtFactorExp_.getValue(context, shieldHurtFactor_);
00116         windFactor_ = windFactorExp_.getValue(context, windFactor_);
00117 
00118         dampenVelocity_ = dampenVelocityExp_.getValue(context, dampenVelocity_);
00119 
00120         fixed minHeight = context.getLandscapeMaps().getGroundMaps().getInterpHeight(
00121                 oldposition[0], oldposition[1]);
00122 
00123         // Make sure position is not underground
00124         if (oldposition[2] < minHeight)
00125         {
00126                 if (minHeight - oldposition[2] > 10) // Give room for shields as well
00127                 {
00128                         return;
00129                 }
00130         }
00131 
00132         RandomGenerator &random = context.getActionController().getRandom();
00133         int numberRollers = numberRollers_.getUInt(context);
00134         for (int i=0; i<numberRollers; i++)
00135         {
00136                 FixedVector position = oldposition;
00137                 position[2] += fixed(true, 1500);
00138                 
00139                 // Make a slightly different starting position
00140                 position[0] += random.getRandFixed() * 2 - 1;
00141                 position[1] += random.getRandFixed() * 2 - 1;
00142                 fixed minHeight = context.getLandscapeMaps().getGroundMaps().getInterpHeight(
00143                         position[0], position[1]) + 1;
00144                 if (position[2] < minHeight) position[2] = minHeight;
00145                                 
00146                 // Check if we have hit the roof (quite litteraly)
00147                 {
00148                         fixed maxHeight = context.getLandscapeMaps().getRoofMaps().getInterpRoofHeight(
00149                                 position[0] / 4, position[1] / 4);
00150                         if (position[2] > maxHeight - 1)
00151                         {
00152                                 position[2] = maxHeight - 1;
00153                         }
00154                 }
00155 
00156                 // Make sure this new position is not inside a tank's shields
00157                 bool ok = false;
00158                 while (!ok)
00159                 {
00160                         ok = true;
00161                         std::map<unsigned int, Target *> &targets = 
00162                                 context.getTargetContainer().getTargets();
00163                         std::map<unsigned int, Target *>::iterator itor;
00164                         for (itor = targets.begin();
00165                                 itor != targets.end();
00166                                 itor++)
00167                         {
00168                                 Target *current = (*itor).second;
00169                                 FixedVector &tankPos = 
00170                                         current->getLife().getTargetPosition();
00171                                 Accessory *accessory = 
00172                                         current->getShield().getCurrentShield();
00173                                 if (accessory)
00174                                 {
00175                                         Shield *shield = (Shield *) accessory->getAction();
00176                                         FixedVector offset = position - tankPos;
00177                                         if (shield->inShield(offset))
00178                                         {
00179                                                 ok = false;
00180                                                 position[2] += 1;
00181                                         }
00182                                 }
00183                         }
00184                 }
00185                 
00186                 addRoller(context, weaponContext, position, velocity);
00187         }
00188 }
00189 
00190 void WeaponRoller::addRoller(ScorchedContext &context,
00191         WeaponFireContext &weaponContext,
00192         FixedVector &position, FixedVector &velocity)
00193 {
00194         RandomGenerator &random = context.getActionController().getRandom();
00195 
00196         FixedVector newVelocity;
00197         if (maintainVelocity_)
00198         {
00199                 newVelocity = velocity * dampenVelocity_;
00200         }
00201         else
00202         {
00203                 newVelocity[0] = random.getRandFixed() - fixed(true, 5000);
00204                 newVelocity[1] = random.getRandFixed() - fixed(true, 5000);
00205                 newVelocity[2] = random.getRandFixed() * 2;
00206         }
00207         
00208         context.getActionController().addAction(
00209                 new ShotBounce(this, position, newVelocity, weaponContext));
00210 }

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