00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tank/Tank.h>
00022 #include <tank/TankLib.h>
00023 #include <tank/TankType.h>
00024 #include <tank/TankModelStore.h>
00025 #include <tank/TankPosition.h>
00026 #include <tank/TankModelContainer.h>
00027 #include <target/TargetLife.h>
00028 #include <engine/ScorchedContext.h>
00029 #include <engine/ActionController.h>
00030 #include <common/Defines.h>
00031 #include <common/OptionsScorched.h>
00032
00033 TankPosition::TankPosition(ScorchedContext &context) :
00034 turretRotXY_(0), turretRotYZ_(0),
00035 oldTurretRotXY_(0), oldTurretRotYZ_(0),
00036 power_(1000), oldPower_(1000),
00037 maxPower_(1000),
00038 tank_(0), context_(context),
00039 selectPositionX_(0), selectPositionY_(0)
00040 {
00041
00042 oldTurretRotXY_ = turretRotXY_ = 0;
00043 oldTurretRotYZ_ = turretRotYZ_ = 45;
00044 }
00045
00046 TankPosition::~TankPosition()
00047 {
00048 }
00049
00050 std::vector<TankPosition::ShotEntry> &TankPosition::getOldShots()
00051 {
00052 std::vector<ShotEntry>::iterator itor;
00053 for (itor = oldShots_.begin();
00054 itor != oldShots_.end();
00055 itor++)
00056 {
00057 ShotEntry &entry = *itor;
00058 entry.current =
00059 (entry.ele == oldTurretRotYZ_ &&
00060 entry.rot == oldTurretRotXY_ &&
00061 entry.power == oldPower_);
00062 }
00063
00064 return oldShots_;
00065 }
00066
00067 void TankPosition::newGame()
00068 {
00069 TankType *type = context_.getTankModels().getTypeByName(
00070 tank_->getModelContainer().getTankTypeName());
00071
00072 maxPower_ = type->getPower();
00073 }
00074
00075 void TankPosition::clientNewGame()
00076 {
00077 TankType *type = context_.getTankModels().getTypeByName(
00078 tank_->getModelContainer().getTankTypeName());
00079
00080 maxPower_ = type->getPower();
00081 oldPower_ = power_ = maxPower_;
00082 oldShots_.clear();
00083 madeShot();
00084 }
00085
00086 void TankPosition::madeShot()
00087 {
00088 oldPower_ = power_;
00089 oldTurretRotXY_ = turretRotXY_;
00090 oldTurretRotYZ_ = turretRotYZ_;
00091
00092 if (oldShots_.empty() ||
00093 oldShots_.back().power != power_ ||
00094 oldShots_.back().rot != turretRotXY_ ||
00095 oldShots_.back().ele != turretRotYZ_)
00096 {
00097 oldShots_.push_back(ShotEntry(power_, turretRotXY_, turretRotYZ_));
00098 }
00099
00100 if (oldShots_.size() > 15)
00101 {
00102 oldShots_.erase(oldShots_.begin());
00103 }
00104 }
00105
00106 void TankPosition::revertSettings(unsigned int index)
00107 {
00108 if (index < oldShots_.size())
00109 {
00110 int newIndex = (oldShots_.size() - 1) - index;
00111 rotateGunXY(oldShots_[newIndex].rot, false);
00112 rotateGunYZ(oldShots_[newIndex].ele, false);
00113 changePower(oldShots_[newIndex].power, false);
00114
00115 oldPower_ = power_;
00116 oldTurretRotXY_ = turretRotXY_;
00117 oldTurretRotYZ_ = turretRotYZ_;
00118 }
00119 }
00120
00121 void TankPosition::undo()
00122 {
00123 rotateGunXY(oldTurretRotXY_, false);
00124 rotateGunYZ(oldTurretRotYZ_, false);
00125 changePower(oldPower_, false);
00126 }
00127
00128 FixedVector &TankPosition::getTankGunPosition()
00129 {
00130 static FixedVector tankGunPosition;
00131 tankGunPosition = TankLib::getGunPosition(
00132 getRotationGunXY(), getRotationGunYZ());
00133 tankGunPosition += getTankTurretPosition();
00134
00135 return tankGunPosition;
00136 }
00137
00138 FixedVector &TankPosition::getTankTurretPosition()
00139 {
00140 static FixedVector tankTurretPosition;
00141 tankTurretPosition = getTankPosition();
00142 tankTurretPosition[2] += 1;
00143
00144 return tankTurretPosition;
00145 }
00146
00147 FixedVector &TankPosition::getTankPosition()
00148 {
00149 return tank_->getLife().getTargetPosition();
00150 }
00151
00152 FixedVector &TankPosition::getVelocityVector()
00153 {
00154 return TankLib::getVelocityVector(
00155 getRotationGunXY(), getRotationGunYZ());
00156 }
00157
00158 fixed TankPosition::rotateGunXY(fixed angle, bool diff)
00159 {
00160 if (diff) turretRotXY_ += angle;
00161 else turretRotXY_ = angle;
00162
00163 if (turretRotXY_ <= 0) turretRotXY_ = turretRotXY_ + 360;
00164 else if (turretRotXY_ > 360) turretRotXY_ = turretRotXY_ - 360;
00165
00166 return turretRotXY_;
00167 }
00168
00169 fixed TankPosition::rotateGunYZ(fixed angle, bool diff)
00170 {
00171 if (diff) turretRotYZ_ += angle;
00172 else turretRotYZ_ = angle;
00173
00174 if (turretRotYZ_ < 0) turretRotYZ_ = 0;
00175 else if (turretRotYZ_ > 90) turretRotYZ_ = 90;
00176
00177 return turretRotYZ_;
00178 }
00179
00180 fixed TankPosition::changePower(fixed power, bool diff)
00181 {
00182 if (diff) power_ += power;
00183 else power_ = power;
00184
00185 if (power_ < 0) power_ = 0;
00186 if (context_.getOptionsGame().getLimitPowerByHealth())
00187 {
00188 fixed maxPosPower =
00189 tank_->getLife().getLife() / tank_->getLife().getMaxLife() * maxPower_;
00190 if (power_ > maxPosPower) power_ = maxPosPower;
00191 }
00192 if (power_ > maxPower_) power_ = maxPower_;
00193
00194 return power_;
00195 }
00196
00197 fixed TankPosition::getRotationXYDiff()
00198 {
00199 fixed rotDiff = (fixed(360) - turretRotXY_) - (fixed(360) - oldTurretRotXY_);
00200 if (rotDiff > 180) rotDiff -= 360;
00201 else if (rotDiff < -180) rotDiff += 360;
00202 return rotDiff;
00203 }
00204
00205 fixed TankPosition::getRotationYZDiff()
00206 {
00207 return turretRotYZ_ - oldTurretRotYZ_;
00208 }
00209
00210 fixed TankPosition::getPowerDiff()
00211 {
00212 return power_ - oldPower_;
00213 }
00214
00215 const char *TankPosition::getRotationString()
00216 {
00217 static char messageBuffer[255];
00218 fixed rotDiff = getRotationXYDiff();
00219
00220 snprintf(messageBuffer, 255, "%+.1f (%+.1f)",
00221 (fixed(360) - getRotationGunXY()).asFloat(),
00222 rotDiff.asFloat());
00223 return messageBuffer;
00224 }
00225
00226 const char *TankPosition::getElevationString()
00227 {
00228 static char messageBuffer[255];
00229 fixed rotDiff = getRotationYZDiff();
00230
00231 snprintf(messageBuffer, 255, "%+.1f (%+.1f)",
00232 getRotationGunYZ().asFloat(),
00233 rotDiff.asFloat());
00234 return messageBuffer;
00235 }
00236
00237 const char *TankPosition::getPowerString()
00238 {
00239 static char messageBuffer[255];
00240 fixed powDiff = getPowerDiff();
00241
00242 snprintf(messageBuffer, 255, "%+.1f (%+.1f)",
00243 getPower().asFloat(),
00244 powDiff.asFloat());
00245 return messageBuffer;
00246 }
00247
00248 bool TankPosition::writeMessage(NetBuffer &buffer)
00249 {
00250 buffer.addToBuffer(maxPower_);
00251 return true;
00252 }
00253
00254 bool TankPosition::readMessage(NetBufferReader &reader)
00255 {
00256 if (!reader.getFromBuffer(maxPower_)) return false;
00257 return true;
00258 }