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