WeaponRandomChoice.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/WeaponRandomChoice.h>
00022 #include <weapons/AccessoryStore.h>
00023 #include <engine/ActionController.h>
00024 #include <common/Defines.h>
00025 #include <stdlib.h>
00026 
00027 REGISTER_ACCESSORY_SOURCE(WeaponRandomChoice);
00028 
00029 WeaponRandomChoice::WeaponRandomChoice() : 
00030         totalWeight_(0)
00031 {
00032 }
00033 
00034 WeaponRandomChoice::~WeaponRandomChoice()
00035 {
00036 }
00037 
00038 bool WeaponRandomChoice::parseXML(AccessoryCreateContext &context, XMLNode *accessoryNode)
00039 {
00040         if (!Weapon::parseXML(context, accessoryNode)) return false;
00041 
00042         for (int i=1;;i++)
00043         {
00044                 // Get the next weaponchoice
00045                 char buffer[128];
00046                 snprintf(buffer, 128, "weaponchoice%i", i);
00047                 XMLNode *subNode = 0;
00048                 accessoryNode->getNamedChild(buffer, subNode, false);
00049                 if (!subNode) break;
00050 
00051                 // Get the weight
00052                 int weight = 0;
00053                 if (!subNode->getNamedChild("weight", weight)) return false;
00054 
00055                 // Get the weapon
00056                 XMLNode *weaponNode = 0;
00057                 if (!subNode->getNamedChild("weapon", weaponNode)) return false;
00058                 AccessoryPart *accessory = context.getAccessoryStore().
00059                         createAccessoryPart(context, parent_, weaponNode);
00060                 if (!accessory || accessory->getType() != AccessoryPart::AccessoryWeapon)
00061                 {
00062                         return weaponNode->returnError("Failed to find sub weapon, not a weapon");
00063                 }
00064                 Weapon *weapon = (Weapon*) accessory;
00065 
00066                 // Add this entry
00067                 WeaponWeight weaponWeight = { weight, weapon };
00068                 weaponsChoice_.push_back(weaponWeight);
00069                 totalWeight_ += weight;
00070 
00071                 // Check the node is empty
00072                 if (!subNode->failChildren()) return false;
00073         }
00074 
00075         if (weaponsChoice_.empty())
00076         {
00077                 return accessoryNode->returnError(
00078                         "Must provide at least one random choice");
00079         }
00080 
00081         return accessoryNode->failChildren();
00082 }
00083 
00084 void WeaponRandomChoice::fireWeapon(ScorchedContext &context,
00085         WeaponFireContext &weaponContext, FixedVector &position, FixedVector &velocity)
00086 {
00087         RandomGenerator &random = context.getActionController().getRandom();
00088         unsigned int randWeight = random.getRandUInt() % totalWeight_;
00089         unsigned int currentWeight = 0;
00090 
00091         std::list<WeaponWeight>::iterator itor;
00092         for (itor = weaponsChoice_.begin();
00093                 itor != weaponsChoice_.end();
00094                 itor++)
00095         {
00096                 WeaponWeight &weightEntry = *itor;
00097                 currentWeight += weightEntry.weight;
00098 
00099                 if (currentWeight >= randWeight)
00100                 {
00101                         Weapon *weapon = weightEntry.weapon;
00102                         weapon->fireWeapon(context, weaponContext, position, velocity);
00103                         break;
00104                 }
00105         }
00106 }

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