00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00067 if (!accessoryNode->getNamedChild("name", name_)) return false;
00068
00069
00070 accessoryNode->getNamedChild("armslevel", armsLevel_, false);
00071
00072
00073 XMLNode *muzzleFlashNode = 0;
00074 accessoryNode->getNamedChild("nomuzzleflash", muzzleFlashNode, false);
00075 if (muzzleFlashNode) muzzleFlash_ = false;
00076
00077
00078 accessoryNode->getNamedChild("description", description_, false);
00079 toolTip_.setText(ToolTip::ToolTipHelp, LANG_STRING(getName()), LANG_STRING(getDescription()));
00080
00081
00082 if (accessoryNode->getNamedChild("icon", iconName_, false))
00083 {
00084 if (!S3D::checkDataFile(S3D::formatStringBuffer("data/textures/wicons/%s", getIconName()))) return false;
00085 }
00086
00087
00088 if (accessoryNode->getNamedChild("activationsound", activationSound_, false))
00089 {
00090 if (!S3D::checkDataFile(S3D::formatStringBuffer("data/wav/%s", getActivationSound()))) return false;
00091 }
00092
00093
00094 accessoryNode->getNamedChild("bundlesize", bundle_, false);
00095
00096
00097 accessoryNode->getNamedChild("aionly", aiOnly_, false);
00098
00099
00100 accessoryNode->getNamedChild("botonly", botOnly_, false);
00101
00102
00103 accessoryNode->getNamedChild("nobuy", noBuy_, false);
00104
00105
00106 maximumNumber_ = context.getOptionsGame().getMaxNumberWeapons();
00107 accessoryNode->getNamedChild("maximumnumber", maximumNumber_, false);
00108
00109
00110 accessoryNode->getNamedChild("startingnumber", startingNumber_, false);
00111
00112
00113 accessoryNode->getNamedChild("usenumber", useNumber_, false);
00114
00115
00116 accessoryNode->getNamedChild("freemarketlimits", freemarketLimits_, false);
00117
00118
00119 accessoryNode->getNamedChild("cost", price_, false);
00120
00121
00122 accessoryNode->getNamedChild("modelscale", modelScale_, false);
00123
00124
00125 XMLNode *modelNode = 0;
00126 if (accessoryNode->getNamedChild("model", modelNode, false))
00127 {
00128 if (!modelId_.initFromNode("data/accessories", modelNode)) return false;
00129 }
00130
00131
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
00143 sellPrice_ = 0;
00144 if (price_ > 0 && bundle_ > 0) sellPrice_ = int((price_ / bundle_) * 0.8f);
00145 originalPrice_ = price_;
00146 originalSellPrice_ = sellPrice_;
00147
00148
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
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
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
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
00280
00281 static ModelID defaultModelId;
00282 if (!defaultModelId.modelValid())
00283 {
00284 defaultModelId.initFromString(
00285 "MilkShape",
00286 "data/accessories/v2missile/v2missile.txt",
00287 "");
00288 }
00289
00290
00291 ModelID *usedModelId = &defaultModelId;
00292
00293
00294 if (id.modelValid())
00295 {
00296 usedModelId = &id;
00297 }
00298 else
00299 {
00300
00301
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
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
00327 mesh = (*itor).second;
00328 }
00329 return mesh;
00330 }
00331 #endif // S3D_SERVER