Accessory.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 <common/ToolTip.h>
00022 #include <common/ModelID.h>
00023 #include <weapons/Accessory.h>
00024 #include <weapons/AccessoryStore.h>
00025 #include <common/Defines.h>
00026 #include <common/OptionsScorched.h>
00027 #include <lang/LangResource.h>
00028 #include <stdlib.h>
00029 
00030 unsigned int Accessory::nextAccessoryId_ = 0;
00031 
00032 #ifndef S3D_SERVER
00033 #include <3dsparse/Model.h>
00034 #include <3dsparse/ModelStore.h>
00035 #include <tankgraph/TargetRendererImplTank.h>
00036 #include <tankgraph/MissileMesh.h>
00037 #include <image/ImageFactory.h>
00038 #endif
00039 
00040 Accessory::Accessory() :
00041         accessoryId_(++nextAccessoryId_),
00042         name_("NONAME"), description_("NODESC"), 
00043         toolTip_(ToolTip::ToolTipHelp, LangString(), LangString()),
00044         price_(0), bundle_(1), armsLevel_(9), freemarketLimits_(150),
00045         modelScale_(1),
00046         positionSelect_(ePositionSelectNone), positionSelectLimit_(10),
00047         maximumNumber_(0),
00048         startingNumber_(0),
00049         useNumber_(1),
00050         muzzleFlash_(true),
00051         aiOnly_(false),
00052         botOnly_(false),
00053         noBuy_(false)
00054 {
00055 #ifndef S3D_SERVER
00056         texture_ = 0;
00057 #endif
00058 }
00059 
00060 Accessory::~Accessory()
00061 {
00062 }
00063 
00064 bool Accessory::parseXML(AccessoryCreateContext &context, XMLNode *accessoryNode)
00065 {
00066         // Get the accessory name
00067         if (!accessoryNode->getNamedChild("name", name_)) return false;
00068 
00069         // Get the accessory armslevel
00070         accessoryNode->getNamedChild("armslevel", armsLevel_, false);
00071 
00072         // Get the optional muzzleflash
00073         XMLNode *muzzleFlashNode = 0;
00074         accessoryNode->getNamedChild("nomuzzleflash", muzzleFlashNode, false);
00075         if (muzzleFlashNode) muzzleFlash_ = false;
00076 
00077         // Get the accessory description
00078         accessoryNode->getNamedChild("description", description_, false);
00079         toolTip_.setText(ToolTip::ToolTipHelp, LANG_STRING(getName()), LANG_STRING(getDescription()));
00080 
00081         // Get the accessory icon
00082         if (accessoryNode->getNamedChild("icon", iconName_, false))
00083         {
00084                 if (!S3D::checkDataFile(S3D::formatStringBuffer("data/textures/wicons/%s", getIconName()))) return false;
00085         }
00086 
00087         // Get the accessory sound 
00088         if (accessoryNode->getNamedChild("activationsound", activationSound_, false))
00089         {
00090                 if (!S3D::checkDataFile(S3D::formatStringBuffer("data/wav/%s", getActivationSound()))) return false;
00091         }
00092 
00093         // Get the accessory bundle
00094         accessoryNode->getNamedChild("bundlesize", bundle_, false);
00095 
00096         // Get ai only
00097         accessoryNode->getNamedChild("aionly", aiOnly_, false);
00098 
00099         // Get bot only (ie: only for bots, not for tank objects)
00100         accessoryNode->getNamedChild("botonly", botOnly_, false);
00101 
00102         // Get no buy 
00103         accessoryNode->getNamedChild("nobuy", noBuy_, false);
00104 
00105         // Get the maximum number
00106         maximumNumber_ = context.getOptionsGame().getMaxNumberWeapons();
00107         accessoryNode->getNamedChild("maximumnumber", maximumNumber_, false);
00108 
00109         // Get the starting number
00110         accessoryNode->getNamedChild("startingnumber", startingNumber_, false);
00111 
00112         // Get the number to use of firing
00113         accessoryNode->getNamedChild("usenumber", useNumber_, false);
00114 
00115         // Freemarket limits
00116         accessoryNode->getNamedChild("freemarketlimits", freemarketLimits_, false);
00117 
00118         // Get the accessory cost
00119         accessoryNode->getNamedChild("cost", price_, false);
00120 
00121         // Get the weapon model scale
00122         accessoryNode->getNamedChild("modelscale", modelScale_, false);
00123 
00124         // Get the weapon model
00125         XMLNode *modelNode = 0;
00126         if (accessoryNode->getNamedChild("model", modelNode, false))
00127         {
00128                 if (!modelId_.initFromNode("data/accessories", modelNode)) return false;
00129         }
00130 
00131         // Get action
00132         XMLNode *subNode = 0;
00133         if (!accessoryNode->getNamedChild("accessoryaction", subNode)) return false;
00134         accessoryAction_ = context.getAccessoryStore().createAccessoryPart(context, this, subNode);
00135         if (!accessoryAction_)
00136         {
00137                 S3D::dialogMessage("Accessory", S3D::formatStringBuffer(
00138                         "Failed to create action \"%s\"", name_.c_str()));
00139                 return false;
00140         }
00141 
00142         // Setup price
00143         sellPrice_ = 0;
00144         if (price_ > 0 && bundle_ > 0) sellPrice_ = int((price_ / bundle_) * 0.8f);
00145         originalPrice_ = price_;
00146         originalSellPrice_ = sellPrice_;
00147 
00148         // Position Selection Type
00149         std::string positionSelection;
00150         if (accessoryNode->getNamedChild("positionselection", positionSelection, false))
00151         {
00152                 if (0 == strcmp(positionSelection.c_str(), "none"))
00153                 {
00154                         positionSelect_ = ePositionSelectNone;
00155                 }
00156                 else if (0 == strcmp(positionSelection.c_str(), "generic"))
00157                 {
00158                         positionSelect_ = ePositionSelectGeneric;
00159                 }
00160                 else if (0 == strcmp(positionSelection.c_str(), "fuel"))
00161                 {
00162                         positionSelect_ = ePositionSelectFuel;
00163 
00164                         // Make sure there is a "WeaponMoveTank" under here somewhere
00165                         if (!context.getAccessoryStore().findAccessoryPartByAccessoryId(
00166                                 getAccessoryId(), "WeaponMoveTank"))
00167                         {
00168                                 return accessoryNode->returnError(
00169                                         "Fuel selection can only be used with WeaponMoveTank weapons");
00170                         }
00171                 }
00172                 else if (0 == strcmp(positionSelection.c_str(), "fuellimit"))
00173                 {
00174                         positionSelect_ = ePositionSelectFuelLimit;
00175                         if (!accessoryNode->getNamedChild("positionselectionlimit", positionSelectLimit_)) return false;
00176                 }
00177                 else if (0 == strcmp(positionSelection.c_str(), "limit"))
00178                 {
00179                         positionSelect_ = ePositionSelectLimit;
00180                         if (!accessoryNode->getNamedChild("positionselectionlimit", positionSelectLimit_)) return false;
00181                 }
00182                 else
00183                 {
00184                         return accessoryNode->returnError(S3D::formatStringBuffer(
00185                                 "Unknown accessory position selection type \"%s\"", 
00186                                 positionSelection.c_str()));
00187                 }
00188         }
00189 
00190         // Get the accessory tabgroupname
00191         if (!accessoryNode->getNamedChild("tabgroup", tabGroupName_, false))
00192         {
00193                 if (accessoryAction_->getType() == AccessoryPart::AccessoryWeapon)
00194                 {
00195                         tabGroupName_ = "weapon";
00196                 }
00197                 else
00198                 {
00199                         tabGroupName_ = "defense";
00200                 }
00201         }
00202 
00203         // Get the accessory groupname
00204         if (!accessoryNode->getNamedChild("group", groupName_, false))
00205         {
00206                 switch (accessoryAction_->getType())
00207                 {
00208                 case AccessoryPart::AccessoryWeapon:
00209                         groupName_ = "weapon";
00210                         break;
00211                 case AccessoryPart::AccessoryParachute:
00212                         groupName_ = "parachute";
00213                         break;
00214                 case AccessoryPart::AccessoryShield:
00215                         groupName_ = "shield";
00216                         break;
00217                 case AccessoryPart::AccessoryAutoDefense:
00218                         groupName_ = "autodefense";
00219                         break;
00220                 case AccessoryPart::AccessoryBattery:
00221                         groupName_ = "battery";
00222                         break;
00223                 default:
00224                         groupName_ = "none";
00225                         break;
00226                 }
00227         }
00228 
00229         return true;
00230 }
00231 
00232 LangString &Accessory::getStringName()
00233 {
00234         if (stringName_.size() == 0)
00235         {
00236                 stringName_ = LANG_RESOURCE(getName(), getName());
00237         }
00238         return stringName_;
00239 }
00240 
00241 const char *Accessory::getActivationSound()
00242 {
00243         if (!activationSound_.c_str()[0]) return 0;
00244         return activationSound_.c_str();
00245 }
00246 
00247 #ifndef S3D_SERVER
00248 
00249 GLTexture *Accessory::getTexture()
00250 {
00251         if (texture_) return texture_;
00252 
00253         GLTexture *texture = 0;
00254         if (getIconName()[0])
00255         {
00256                 ImageHandle bmap =
00257                         ImageFactory::loadAlphaImageHandle(
00258                                 S3D::getDataFile(S3D::formatStringBuffer("data/textures/wicons/%s", getIconName())));
00259                 texture = new GLTexture();
00260                 texture->create(bmap, false);
00261         }
00262         else
00263         {
00264                 ImageHandle bmap =
00265                         ImageFactory::loadAlphaImageHandle(
00266                                 S3D::getDataFile(S3D::formatStringBuffer("data/textures/wicons/%s", "tracer.bmp")));
00267                 texture = new GLTexture();
00268                 texture->create(bmap, false);
00269         }
00270         texture_ = texture;
00271         return texture;
00272 }
00273 
00274 
00275 std::map<std::string, MissileMesh *> Accessory::loadedMeshes_;
00276 
00277 MissileMesh *Accessory::getWeaponMesh(ModelID &id, Tank *currentPlayer)
00278 {
00279         // Set the default model to use if neither the tank
00280         // or weapon have one
00281         static ModelID defaultModelId;
00282         if (!defaultModelId.modelValid())
00283         {
00284                 defaultModelId.initFromString(
00285                         "MilkShape",
00286                         "data/accessories/v2missile/v2missile.txt",
00287                         "");
00288         }
00289 
00290         // Set the model to use as the default model id
00291         ModelID *usedModelId = &defaultModelId;
00292 
00293         // Get the model to use from the weapon (if there is one)
00294         if (id.modelValid())
00295         {
00296                 usedModelId = &id;
00297         }
00298         else
00299         {
00300                 // The weapon does not have a model defined for it
00301                 // check the player to see if they have a default model
00302                 if (currentPlayer)
00303                 {
00304                         TargetRendererImplTank *renderer = (TargetRendererImplTank *) 
00305                                 currentPlayer->getRenderer();
00306                         if (renderer && 
00307                                 renderer->getModel()->getProjectileModelID().modelValid())
00308                         {
00309                                 usedModelId = &renderer->getModel()->getProjectileModelID();
00310                         }
00311                 }
00312         }
00313 
00314         // Load or find the correct missile mesh
00315         MissileMesh *mesh = 0;
00316         const char *name = usedModelId->getStringHash();
00317         std::map<std::string, MissileMesh *>::iterator itor =
00318                 loadedMeshes_.find(name);
00319         if (itor == loadedMeshes_.end())
00320         {
00321                 mesh = new MissileMesh(*usedModelId);
00322                 loadedMeshes_[name] = mesh;
00323         }
00324         else
00325         {
00326                 // Find
00327                 mesh = (*itor).second;
00328         }
00329         return mesh;
00330 }
00331 #endif // S3D_SERVER

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