00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <weapons/WeaponAimedUnder.h>
00022 #include <weapons/AccessoryStore.h>
00023 #include <engine/ActionController.h>
00024 #include <landscapemap/LandscapeMaps.h>
00025 #include <tank/TankLib.h>
00026 #include <tank/Tank.h>
00027 #include <tank/TankPosition.h>
00028 #include <common/Defines.h>
00029 #include <list>
00030 #include <math.h>
00031
00032 REGISTER_ACCESSORY_SOURCE(WeaponAimedUnder);
00033
00034 WeaponAimedUnder::WeaponAimedUnder() : warHeads_(0), moveUnderground_(true)
00035 {
00036
00037 }
00038
00039 WeaponAimedUnder::~WeaponAimedUnder()
00040 {
00041
00042 }
00043
00044 bool WeaponAimedUnder::parseXML(AccessoryCreateContext &context, XMLNode *accessoryNode)
00045 {
00046 if (!Weapon::parseXML(context, accessoryNode)) return false;
00047
00048
00049 if (!accessoryNode->getNamedChild("nowarheads", warHeads_)) return false;
00050
00051
00052 XMLNode *subNode = 0;
00053 if (!accessoryNode->getNamedChild("aimedweapon", subNode)) return false;
00054
00055
00056 AccessoryPart *accessory = context.getAccessoryStore().
00057 createAccessoryPart(context, parent_, subNode);
00058 if (!accessory || accessory->getType() != AccessoryPart::AccessoryWeapon)
00059 {
00060 return subNode->returnError("Failed to find sub weapon, not a weapon");
00061 }
00062 aimedWeapon_ = (Weapon*) accessory;
00063
00064
00065 if (!accessoryNode->getNamedChild("maxaimdistance", maxAimedDistance_)) return false;
00066
00067
00068 if (!accessoryNode->getNamedChild("percentagemiss", percentageMissChance_)) return false;
00069
00070
00071 if (!accessoryNode->getNamedChild("inaccuracy", maxInacuracy_)) return false;
00072
00073
00074 accessoryNode->getNamedChild("moveunderground", moveUnderground_, false);
00075
00076 return true;
00077 }
00078
00079 void WeaponAimedUnder::fireWeapon(ScorchedContext &context,
00080 WeaponFireContext &weaponContext, FixedVector &position, FixedVector &oldvelocity)
00081 {
00082
00083
00084 if (moveUnderground_)
00085 {
00086 fixed height = context.getLandscapeMaps().getGroundMaps().
00087 getInterpHeight(position[0], position[1]);
00088 if (position[2] < height + 1)
00089 {
00090 position[2] = context.getLandscapeMaps().getGroundMaps().
00091 getInterpHeight(position[0], position[1]) / 2;
00092 }
00093 }
00094
00095
00096 std::list<std::pair<fixed, Tank *> > sortedTanks;
00097 TankLib::getTanksSortedByDistance(
00098 context,
00099 position,
00100 sortedTanks,
00101 0,
00102 maxAimedDistance_.getValue(context));
00103
00104
00105 fixed totalDist = 0;
00106 std::list<std::pair<fixed, Tank *> >::iterator itor;
00107 for (itor = sortedTanks.begin();
00108 itor != sortedTanks.end();
00109 itor++)
00110 {
00111 totalDist += (*itor).first;
00112 }
00113
00114
00115 fixed maxDist = 0;
00116 if (sortedTanks.size() == 1)
00117 {
00118 maxDist = totalDist;
00119 }
00120 else
00121 {
00122 for (itor = sortedTanks.begin();
00123 itor != sortedTanks.end();
00124 itor++)
00125 {
00126 (*itor).first = totalDist - (*itor).first;
00127 maxDist += (*itor).first;
00128 }
00129 }
00130
00131
00132 maxDist *= (percentageMissChance_.getValue(context)/ 100) + 1;
00133
00134 RandomGenerator &random = context.getActionController().getRandom();
00135
00136
00137 for (int i=0; i<warHeads_; i++)
00138 {
00139
00140 fixed dist = maxDist * random.getRandFixed();
00141
00142
00143 Tank *shootAt = 0;
00144 fixed distC = 0;
00145 for (itor = sortedTanks.begin();
00146 itor != sortedTanks.end();
00147 itor++)
00148 {
00149 distC += (*itor).first;
00150 if (dist < distC)
00151 {
00152 shootAt = (*itor).second;
00153 break;
00154 }
00155 }
00156
00157
00158 fixed angleXYDegs = random.getRandFixed() * 360;
00159 fixed angleYZDegs = random.getRandFixed() * 30 + 50;
00160 fixed power = 1000;
00161 if (shootAt)
00162 {
00163
00164
00165 TankLib::getSniperShotTowardsPosition(
00166 context,
00167 position,
00168 shootAt->getPosition().getTankPosition(), -1,
00169 angleXYDegs, angleYZDegs, power);
00170
00171 angleXYDegs += (random.getRandFixed() * maxInacuracy_.getValue(context)) -
00172 (maxInacuracy_.getValue(context) / 2);
00173 angleYZDegs += (random.getRandFixed() * maxInacuracy_.getValue(context)) -
00174 (maxInacuracy_.getValue(context) / 2);
00175 }
00176
00177
00178 FixedVector &velocity = TankLib::getVelocityVector(
00179 angleXYDegs, angleYZDegs);
00180 velocity *= power;
00181
00182 aimedWeapon_->fireWeapon(context, weaponContext, position, velocity);
00183 }
00184 }