00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <weapons/WeaponRoller.h>
00022 #include <weapons/AccessoryStore.h>
00023 #include <weapons/Shield.h>
00024 #include <actions/ShotBounce.h>
00025 #include <common/Defines.h>
00026 #include <engine/ActionController.h>
00027 #include <target/TargetContainer.h>
00028 #include <target/TargetShield.h>
00029 #include <target/TargetLife.h>
00030 #include <landscapemap/LandscapeMaps.h>
00031 #include <math.h>
00032
00033 REGISTER_ACCESSORY_SOURCE(WeaponRoller);
00034
00035 WeaponRoller::WeaponRoller() :
00036 shieldHurtFactor_(0), windFactor_(1),
00037 maintainVelocity_(false), roll_(true),
00038 dampenVelocityExp_(1)
00039 {
00040
00041 }
00042
00043 WeaponRoller::~WeaponRoller()
00044 {
00045
00046 }
00047
00048 bool WeaponRoller::parseXML(AccessoryCreateContext &context, XMLNode *accessoryNode)
00049 {
00050 if (!Weapon::parseXML(context, accessoryNode)) return false;
00051
00052
00053 if (!accessoryNode->getNamedChild("numberrollers", numberRollers_)) return false;
00054
00055
00056 if (!accessoryNode->getNamedChild("time", timeExp_)) return false;
00057
00058
00059 accessoryNode->getNamedChild("shieldhurtfactor", shieldHurtFactorExp_, false);
00060
00061
00062 accessoryNode->getNamedChild("windfactor", windFactorExp_, false);
00063
00064
00065 accessoryNode->getNamedChild("maintainvelocity", maintainVelocity_, false);
00066
00067
00068 accessoryNode->getNamedChild("dampenvelocity", dampenVelocityExp_, false);
00069
00070
00071 accessoryNode->getNamedChild("roll", roll_, false);
00072
00073 XMLNode *subNode = 0;
00074 if (!accessoryNode->getNamedChild("collisionaction", subNode)) return false;
00075
00076 AccessoryPart *accessory = context.getAccessoryStore().
00077 createAccessoryPart(context, parent_, subNode);
00078 if (!accessory || accessory->getType() != AccessoryPart::AccessoryWeapon)
00079 {
00080 return subNode->returnError("Failed to find sub weapon, not a weapon");
00081 }
00082 collisionAction_ = (Weapon*) accessory;
00083
00084
00085 XMLNode *modelNode = 0;
00086 if (!accessoryNode->getNamedChild("rollermodel", modelNode)) return false;
00087 if (!rollerModelId_.initFromNode("data/accessories", modelNode)) return false;
00088
00089 return true;
00090 }
00091
00092 fixed WeaponRoller::getWindFactor(ScorchedContext &context)
00093 {
00094 return windFactor_;
00095 }
00096
00097 fixed WeaponRoller::getTime(ScorchedContext &context)
00098 {
00099 return timeExp_.getValue(context);
00100 }
00101
00102 fixed WeaponRoller::getShieldHurtFactor(ScorchedContext &context)
00103 {
00104 return shieldHurtFactor_;
00105 }
00106
00107 void WeaponRoller::fireWeapon(ScorchedContext &context,
00108 WeaponFireContext &weaponContext, FixedVector &oldposition, FixedVector &velocity)
00109 {
00110
00111
00112
00113
00114
00115 shieldHurtFactor_ = shieldHurtFactorExp_.getValue(context, shieldHurtFactor_);
00116 windFactor_ = windFactorExp_.getValue(context, windFactor_);
00117
00118 dampenVelocity_ = dampenVelocityExp_.getValue(context, dampenVelocity_);
00119
00120 fixed minHeight = context.getLandscapeMaps().getGroundMaps().getInterpHeight(
00121 oldposition[0], oldposition[1]);
00122
00123
00124 if (oldposition[2] < minHeight)
00125 {
00126 if (minHeight - oldposition[2] > 10)
00127 {
00128 return;
00129 }
00130 }
00131
00132 RandomGenerator &random = context.getActionController().getRandom();
00133 int numberRollers = numberRollers_.getUInt(context);
00134 for (int i=0; i<numberRollers; i++)
00135 {
00136 FixedVector position = oldposition;
00137 position[2] += fixed(true, 1500);
00138
00139
00140 position[0] += random.getRandFixed() * 2 - 1;
00141 position[1] += random.getRandFixed() * 2 - 1;
00142 fixed minHeight = context.getLandscapeMaps().getGroundMaps().getInterpHeight(
00143 position[0], position[1]) + 1;
00144 if (position[2] < minHeight) position[2] = minHeight;
00145
00146
00147 {
00148 fixed maxHeight = context.getLandscapeMaps().getRoofMaps().getInterpRoofHeight(
00149 position[0] / 4, position[1] / 4);
00150 if (position[2] > maxHeight - 1)
00151 {
00152 position[2] = maxHeight - 1;
00153 }
00154 }
00155
00156
00157 bool ok = false;
00158 while (!ok)
00159 {
00160 ok = true;
00161 std::map<unsigned int, Target *> &targets =
00162 context.getTargetContainer().getTargets();
00163 std::map<unsigned int, Target *>::iterator itor;
00164 for (itor = targets.begin();
00165 itor != targets.end();
00166 itor++)
00167 {
00168 Target *current = (*itor).second;
00169 FixedVector &tankPos =
00170 current->getLife().getTargetPosition();
00171 Accessory *accessory =
00172 current->getShield().getCurrentShield();
00173 if (accessory)
00174 {
00175 Shield *shield = (Shield *) accessory->getAction();
00176 FixedVector offset = position - tankPos;
00177 if (shield->inShield(offset))
00178 {
00179 ok = false;
00180 position[2] += 1;
00181 }
00182 }
00183 }
00184 }
00185
00186 addRoller(context, weaponContext, position, velocity);
00187 }
00188 }
00189
00190 void WeaponRoller::addRoller(ScorchedContext &context,
00191 WeaponFireContext &weaponContext,
00192 FixedVector &position, FixedVector &velocity)
00193 {
00194 RandomGenerator &random = context.getActionController().getRandom();
00195
00196 FixedVector newVelocity;
00197 if (maintainVelocity_)
00198 {
00199 newVelocity = velocity * dampenVelocity_;
00200 }
00201 else
00202 {
00203 newVelocity[0] = random.getRandFixed() - fixed(true, 5000);
00204 newVelocity[1] = random.getRandFixed() - fixed(true, 5000);
00205 newVelocity[2] = random.getRandFixed() * 2;
00206 }
00207
00208 context.getActionController().addAction(
00209 new ShotBounce(this, position, newVelocity, weaponContext));
00210 }