00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <weapons/AccessoryStore.h>
00022 #include <tank/TankModelStore.h>
00023 #include <tank/TankModelContainer.h>
00024 #include <tank/TankAccessories.h>
00025 #include <tank/TankType.h>
00026 #include <tank/Tank.h>
00027 #include <target/TargetParachute.h>
00028 #include <target/TargetShield.h>
00029 #include <target/TargetLife.h>
00030 #ifndef S3D_SERVER
00031 #include <tankgraph/TankKeyboardControlUtil.h>
00032 #endif
00033 #include <common/OptionsScorched.h>
00034 #include <common/OptionsTransient.h>
00035 #include <lang/LangResource.h>
00036
00037 TankAccessories::TankAccessories(ScorchedContext &context) :
00038 context_(context),
00039 tankWeapon_(context),
00040 tankAuto_(context),
00041 tankBatteries_(context)
00042 {
00043 }
00044
00045 TankAccessories::~TankAccessories()
00046 {
00047 }
00048
00049 void TankAccessories::setTank(Tank *tank)
00050 {
00051 tank_ = tank;
00052 tankWeapon_.setTank(tank);
00053 tankAuto_.setTank(tank);
00054 tankBatteries_.setTank(tank);
00055 }
00056
00057 void TankAccessories::newMatch()
00058 {
00059 clearAccessories();
00060
00061 tankWeapon_.newMatch();
00062 tankAuto_.newMatch();
00063 tankBatteries_.newMatch();
00064
00065
00066
00067
00068 {
00069 std::list<Accessory *> accessories =
00070 context_.getAccessoryStore().getAllAccessories();
00071 std::list<Accessory *>::iterator itor;
00072 for (itor = accessories.begin();
00073 itor != accessories.end();
00074 itor++)
00075 {
00076 Accessory *accessory = (*itor);
00077 if (accessory->getMaximumNumber() > 0)
00078 {
00079 int startingNumber = accessory->getStartingNumber();
00080 if (context_.getOptionsGame().getGiveAllWeapons())
00081 {
00082 startingNumber = -1;
00083 }
00084
00085 if (startingNumber != 0)
00086 {
00087 add_(accessory, startingNumber, true);
00088 }
00089 }
00090 }
00091 }
00092
00093
00094 {
00095 TankType *type = context_.getTankModels().getTypeByName(
00096 tank_->getModelContainer().getTankTypeName());
00097 std::map<Accessory *, int> accessories = type->getAccessories();
00098 std::map<Accessory *, int>::iterator itor;
00099 for (itor = accessories.begin();
00100 itor != accessories.end();
00101 itor++)
00102 {
00103 Accessory *accessory = (*itor).first;
00104 int count = (*itor).second;
00105
00106 add_(accessory, count, true);
00107 }
00108 }
00109
00110 changed();
00111 }
00112
00113 void TankAccessories::clearAccessories()
00114 {
00115 accessories_.clear();
00116
00117 std::map<std::string, AccessoryList*>::iterator groupsItor;
00118 for (groupsItor = accessoryGroups_.begin();
00119 groupsItor != accessoryGroups_.end();
00120 groupsItor++)
00121 {
00122 delete (*groupsItor).second;
00123 }
00124 accessoryGroups_.clear();
00125
00126 std::map<AccessoryPart::AccessoryType, AccessoryList*>::iterator typesItor;
00127 for (typesItor = accessoryTypes_.begin();
00128 typesItor != accessoryTypes_.end();
00129 typesItor++)
00130 {
00131 delete (*typesItor).second;
00132 }
00133 accessoryTypes_.clear();
00134
00135 }
00136
00137 void TankAccessories::getAllAccessories(std::list<Accessory *> &result)
00138 {
00139 std::map<Accessory *, int>::iterator itor;
00140 for (itor = accessories_.begin();
00141 itor != accessories_.end();
00142 itor++)
00143 {
00144 Accessory *accessory = (*itor).first;
00145 result.push_back(accessory);
00146 }
00147 }
00148
00149 std::list<Accessory *> &TankAccessories::getAllAccessoriesByType(
00150 AccessoryPart::AccessoryType type)
00151 {
00152 std::map<AccessoryPart::AccessoryType, AccessoryList*>::iterator itor =
00153 accessoryTypes_.find(type);
00154 if (itor != accessoryTypes_.end())
00155 {
00156 return *((*itor).second);
00157 }
00158
00159 static std::list<Accessory *> emptyList;
00160 return emptyList;
00161 }
00162
00163 std::list<Accessory *> &TankAccessories::getAllAccessoriesByGroup(
00164 const char *groupName)
00165 {
00166 std::map<std::string, AccessoryList*>::iterator itor =
00167 accessoryGroups_.find(groupName);
00168 if (itor != accessoryGroups_.end())
00169 {
00170 return *((*itor).second);
00171 }
00172
00173 static std::list<Accessory *> emptyList;
00174 return emptyList;
00175 }
00176
00177 bool TankAccessories::canUse(Accessory *accessory)
00178 {
00179 int count = getAccessoryCount(accessory);
00180 if (count == 0) return false;
00181 if (count == -1 || count >= accessory->getUseNumber()) return true;
00182 return false;
00183 }
00184
00185 int TankAccessories::getAccessoryCount(Accessory *accessory)
00186 {
00187 std::map<Accessory *, int>::iterator foundAccessory =
00188 accessories_.find(accessory);
00189 int currentNumber = 0;
00190 if (foundAccessory != accessories_.end())
00191 {
00192 currentNumber = foundAccessory->second;
00193 }
00194 return currentNumber;
00195 }
00196
00197 bool TankAccessories::accessoryAllowed(Accessory *accessory, int count)
00198 {
00199
00200 TankType *type = context_.getTankModels().getTypeByName(
00201 tank_->getModelContainer().getTankTypeName());
00202 if (type->getAccessoryDisabled(accessory)) return false;
00203
00204
00205 if (accessory->getMaximumNumber() == 0) return false;
00206 int currentCount = getAccessoryCount(accessory);
00207 if (currentCount + count >
00208 accessory->getMaximumNumber())
00209 {
00210 return false;
00211 }
00212
00213
00214 if (10 - accessory->getArmsLevel() >
00215 context_.getOptionsTransient().getArmsLevel())
00216 {
00217 return false;
00218 }
00219
00220
00221 if (currentCount == -1)
00222 {
00223 return false;
00224 }
00225
00226
00227 if (accessory->getAIOnly())
00228 {
00229 if (!tank_->isTemp())
00230 {
00231 return false;
00232 }
00233 }
00234
00235
00236 if (accessory->getBotOnly())
00237 {
00238 if(tank_->getDestinationId() != 0)
00239 {
00240 return false;
00241 }
00242 }
00243
00244 return true;
00245 }
00246
00247 void TankAccessories::add(Accessory *accessory, int count, bool check)
00248 {
00249 add_(accessory, count, check);
00250 changed();
00251 }
00252
00253 void TankAccessories::add_(Accessory *accessory, int count, bool check)
00254 {
00255 if (check)
00256 {
00257
00258 if (!accessoryAllowed(accessory, count)) return;
00259 }
00260 else
00261 {
00262
00263 if (getAccessoryCount(accessory) == -1)
00264 {
00265 return;
00266 }
00267 }
00268
00269
00270 std::map<Accessory *, int>::iterator itor = accessories_.find(accessory);
00271 if (itor == accessories_.end() || count < 0)
00272 {
00273 accessories_[accessory] = count;
00274 }
00275 else
00276 {
00277 accessories_[accessory] += count;
00278 }
00279
00280
00281 {
00282 std::map<std::string, AccessoryList*>::iterator groupItor =
00283 accessoryGroups_.find(accessory->getGroupName());
00284 if (groupItor != accessoryGroups_.end())
00285 {
00286 (*groupItor).second->remove(accessory);
00287 (*groupItor).second->push_back(accessory);
00288 }
00289 else
00290 {
00291 AccessoryList *newList = new AccessoryList();
00292 accessoryGroups_[accessory->getGroupName()] = newList;
00293 newList->push_back(accessory);
00294 }
00295 }
00296
00297
00298 {
00299 std::map<AccessoryPart::AccessoryType, AccessoryList*>::iterator typeItor =
00300 accessoryTypes_.find(accessory->getType());
00301 if (typeItor != accessoryTypes_.end())
00302 {
00303 (*typeItor).second->remove(accessory);
00304 (*typeItor).second->push_back(accessory);
00305 }
00306 else
00307 {
00308 AccessoryList *newList = new AccessoryList();
00309 accessoryTypes_[accessory->getType()] = newList;
00310 newList->push_back(accessory);
00311 }
00312 }
00313 }
00314
00315 void TankAccessories::rm(Accessory *accessory, int count)
00316 {
00317 std::map<Accessory *, int>::iterator itor =
00318 accessories_.find(accessory);
00319 if (itor != accessories_.end())
00320 {
00321 if (accessories_[accessory] > 0)
00322 {
00323 accessories_[accessory] -= count;
00324 if (accessories_[accessory] <= 0)
00325 {
00326 accessories_.erase(accessory);
00327
00328 {
00329 std::map<std::string, AccessoryList*>::iterator groupItor =
00330 accessoryGroups_.find(accessory->getGroupName());
00331 if (groupItor != accessoryGroups_.end())
00332 {
00333 (*groupItor).second->remove(accessory);
00334 }
00335 }
00336 {
00337 std::map<AccessoryPart::AccessoryType, AccessoryList*>::iterator typeItor =
00338 accessoryTypes_.find(accessory->getType());
00339 if (typeItor != accessoryTypes_.end())
00340 {
00341 (*typeItor).second->remove(accessory);
00342 }
00343 }
00344 }
00345 }
00346 }
00347
00348 changed();
00349 }
00350
00351 LangString TankAccessories::getAccessoryCountString(Accessory *accessory)
00352 {
00353 int count = getAccessoryCount(accessory);
00354 LangString buffer;
00355 if (count >= 0)
00356 {
00357 buffer.append(LANG_STRING(S3D::formatStringBuffer("%i", count)));
00358 }
00359 else
00360 {
00361 LANG_RESOURCE_VAR(INF, "INF", "In");
00362 buffer.append(INF);
00363 }
00364
00365 return buffer;
00366 }
00367
00368 LangString TankAccessories::getAccessoryAndCountString(Accessory *accessory)
00369 {
00370 int count = getAccessoryCount(accessory);
00371 LangString buffer;
00372 buffer.append(LANG_RESOURCE(accessory->getName(), accessory->getName())).
00373 append(LANG_STRING(" ("));
00374 buffer.append(getAccessoryCountString(accessory));
00375 buffer.append(LANG_STRING(")"));
00376
00377 return buffer;
00378 }
00379
00380 void TankAccessories::changed()
00381 {
00382
00383 tankAuto_.changed();
00384 tankWeapon_.changed();
00385 tankBatteries_.changed();
00386 }
00387
00388 bool TankAccessories::writeMessage(NetBuffer &buffer, bool writeAccessories)
00389 {
00390
00391 if (!writeAccessories)
00392 {
00393 buffer.addToBuffer((int) -1);
00394 return true;
00395 }
00396
00397
00398 std::map<unsigned int, int> ordered;
00399 std::map<unsigned int, int>::iterator itor2;
00400 std::map<Accessory *, int>::iterator itor;
00401 for (itor = accessories_.begin();
00402 itor != accessories_.end();
00403 itor++)
00404 {
00405 ordered[itor->first->getAccessoryId()] = itor->second;
00406 }
00407
00408
00409 buffer.addToBuffer((int) ordered.size());
00410 for (itor2 = ordered.begin();
00411 itor2 != ordered.end();
00412 itor2++)
00413 {
00414 buffer.addToBuffer(itor2->first);
00415 buffer.addToBuffer(itor2->second);
00416 }
00417
00418 return true;
00419 }
00420
00421 bool TankAccessories::readMessage(NetBufferReader &reader)
00422 {
00423 int totalAccessories = 0;
00424 if (!reader.getFromBuffer(totalAccessories)) return false;
00425
00426
00427 if (totalAccessories == -1)
00428 {
00429 return true;
00430 }
00431
00432
00433 clearAccessories();
00434
00435
00436 for (int w=0; w<totalAccessories; w++)
00437 {
00438 unsigned int accessoryId = 0;
00439 int accessoryCount = 0;
00440 if (!reader.getFromBuffer(accessoryId)) return false;
00441 if (!reader.getFromBuffer(accessoryCount)) return false;
00442
00443 Accessory *accessory =
00444 context_.getAccessoryStore().findByAccessoryId(accessoryId);
00445 if (!accessory)
00446 {
00447 return false;
00448 }
00449
00450 add_(accessory, accessoryCount, false);
00451 }
00452
00453 changed();
00454 return true;
00455 }
00456
00457 void TankAccessories::activate(Accessory *accessory)
00458 {
00459 DIALOG_ASSERT(!context_.getServerMode());
00460
00461 #ifndef S3D_SERVER
00462 switch (accessory->getType())
00463 {
00464 case AccessoryPart::AccessoryParachute:
00465 TankKeyboardControlUtil::parachutesUpDown(
00466 tank_,
00467 (tank_->getParachute().getCurrentParachute()==accessory)?
00468 0:accessory->getAccessoryId());
00469 break;
00470 case AccessoryPart::AccessoryShield:
00471 TankKeyboardControlUtil::shieldsUpDown(
00472 tank_,
00473 (tank_->getShield().getCurrentShield()==accessory)?
00474 0:accessory->getAccessoryId());
00475 break;
00476 case AccessoryPart::AccessoryWeapon:
00477 getWeapons().setWeapon(accessory);
00478 break;
00479 case AccessoryPart::AccessoryBattery:
00480 if (tank_->getLife().getLife() <
00481 tank_->getLife().getMaxLife())
00482 {
00483 TankKeyboardControlUtil::useBattery(
00484 tank_, accessory->getAccessoryId());
00485 }
00486 break;
00487 case AccessoryPart::AccessoryAutoDefense:
00488 default:
00489 break;
00490 }
00491 #endif
00492 }