00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Weapon.hpp"
00020 #include "Singletons.hpp"
00021 #include "Globals.hpp"
00022 #include "MathFuncs.hpp"
00023
00024 #include <cstdio>
00025 #include <cmath>
00026 #include <boost/format.hpp>
00027 #include <libintl.h>
00028 #define _(string) gettext(string)
00029
00030 CWeapon::CWeapon()
00031 : m_ProjectileSpeedX(0.0f),
00032 m_ProjectileSpeedY(0.0f),
00033 m_ProjectileAccelX(0.0f),
00034 m_ProjectileAccelY(0.0f),
00035 m_SpeedLimitX(-99999.0f),
00036 m_SpeedLimitY(-99999.0f),
00037 m_SpeedLimitXSmaller(false),
00038 m_SpeedLimitYSmaller(false),
00039 m_ShootSpeed(0),
00040 m_LastShot(0),
00041 m_Damage(0),
00042 m_WeaponGroupID(0),
00043 m_ProjectileAutoRotate(false),
00044 m_InitiallyEquiped(false),
00045 m_Equiped(false),
00046 m_Foreground(false),
00047 m_X(0),
00048 m_Y(0),
00049 log_(log4cxx::Logger::getLogger("CWeapon"))
00050 {}
00051
00052 CWeapon::~CWeapon()
00053 {
00054 for(std::size_t CurProjectil = 0; CurProjectil < m_Projectiles.size(); CurProjectil++)
00055 {
00056 delete m_Projectiles[CurProjectil];
00057 }
00058 m_Projectiles.clear();
00059 }
00060
00061 void CWeapon::ReadData(const std::string& Name)
00062 {
00063 FILE* ShipFile = std::fopen(Name.c_str(),"r");
00064
00065 if(ShipFile == NULL)
00066 {
00067 LOG4CXX_ERROR(log_, boost::format(_("Could not open Weaponfile \"%1%\"")) % Name);
00068 return;
00069 }
00070
00071 char strBuf[100];
00072 int HelpInt;
00073 std::string HelpString;
00074 std::string OldString;
00075 std::string DataString;
00076 int ProjectileFrameCount = 1;
00077 int FrameWidth = -1;
00078 int FrameHeight = -1;
00079 int FrameDelay = 999999;
00080
00081 while(std::feof(ShipFile) == 0)
00082 {
00083 std::fscanf(ShipFile,"%s",strBuf);
00084 HelpString = strBuf;
00085
00086 if(HelpString == "=")
00087 {
00088 if(OldString == "WeaponName")
00089 {
00090 std::fscanf(ShipFile,"%s",strBuf);
00091 m_Name = strBuf;
00092 }
00093
00094 if(OldString == "X")
00095 {
00096 std::fscanf(ShipFile,"%f",&m_X);
00097 }
00098
00099 if(OldString == "Y")
00100 {
00101 std::fscanf(ShipFile,"%f",&m_Y);
00102 }
00103
00104 if(OldString == "ProjectileSpeedX")
00105 {
00106 std::fscanf(ShipFile,"%f",&m_ProjectileSpeedX);
00107 }
00108
00109 if(OldString == "ProjectileSpeedY")
00110 {
00111 std::fscanf(ShipFile,"%f",&m_ProjectileSpeedY);
00112 }
00113
00114 if(OldString == "ProjectileAccelX")
00115 {
00116 std::fscanf(ShipFile,"%f",&m_ProjectileAccelX);
00117 }
00118
00119 if(OldString == "ProjectileAccelY")
00120 {
00121 std::fscanf(ShipFile,"%f",&m_ProjectileAccelY);
00122 }
00123
00124
00125 if(OldString == "ProjectileSpeedLimitX")
00126 {
00127 std::fscanf(ShipFile,"%s",strBuf);
00128 std::fscanf(ShipFile,"%f",&m_SpeedLimitX);
00129 DataString = strBuf;
00130
00131 m_SpeedLimitXSmaller = false;
00132 if(DataString.find("<") != std::string::npos)
00133 {
00134 m_SpeedLimitXSmaller = true;
00135 }
00136 }
00137
00138 if(OldString == "ProjectileSpeedLimitY")
00139 {
00140 std::fscanf(ShipFile,"%s",strBuf);
00141 std::fscanf(ShipFile,"%f",&m_SpeedLimitY);
00142 DataString = strBuf;
00143
00144 m_SpeedLimitYSmaller = false;
00145 if(DataString.find("<") != std::string::npos)
00146 {
00147 m_SpeedLimitYSmaller = true;
00148 }
00149 }
00150
00151 if(OldString == "ProjectileImage")
00152 {
00153 std::fscanf(ShipFile,"%s",strBuf);
00154 m_ProjectileImageName = strBuf;
00155 }
00156 if(OldString == "ProjectileFrameCount")
00157 {
00158 std::fscanf(ShipFile,"%d",&ProjectileFrameCount);
00159 }
00160 if(OldString == "ProjectileFrameWidth")
00161 {
00162 std::fscanf(ShipFile,"%d",&FrameWidth);
00163 }
00164 if(OldString == "ProjectileFrameHeight")
00165 {
00166 std::fscanf(ShipFile,"%d",&FrameHeight);
00167 }
00168 if(OldString == "ProjectileFrameDelay")
00169 {
00170 std::fscanf(ShipFile,"%d",&FrameDelay);
00171 }
00172
00173 if(OldString == "ShootSpeed")
00174 {
00175 std::fscanf(ShipFile,"%d",&m_ShootSpeed);
00176 }
00177
00178 if(OldString == "Damage")
00179 {
00180 std::fscanf(ShipFile,"%d",&m_Damage);
00181 }
00182
00183 if(OldString == "WeaponGroupID")
00184 {
00185 std::fscanf(ShipFile,"%d",&m_WeaponGroupID);
00186 }
00187
00188 if(OldString == "AutoRotate")
00189 {
00190 std::fscanf(ShipFile,"%d",&HelpInt);
00191 if(HelpInt == 0)
00192 {
00193 m_ProjectileAutoRotate = false;
00194 }
00195 else
00196 {
00197 m_ProjectileAutoRotate = true;
00198 }
00199 }
00200
00201
00202 if(OldString == "CollisionSystem")
00203 {
00204 std::fscanf(ShipFile,"%s",strBuf);
00205 m_ProjectileData.CollisionFile = strBuf;
00206 }
00207
00208
00209 if(OldString == "ShootSound")
00210 {
00211 std::fscanf(ShipFile,"%s",strBuf);
00212 m_ShootSoundFile = strBuf;
00213 m_ShootSound.SetBuffer(sgl::get_sndbuffmgr().get_snd(m_ShootSoundFile));
00214 }
00215
00216 if(OldString == "OnHitSound")
00217 {
00218 std::fscanf(ShipFile,"%s",strBuf);
00219 m_HitSoundFile = strBuf;
00220 m_HitSound.SetBuffer(sgl::get_sndbuffmgr().get_snd(m_HitSoundFile));
00221 }
00222
00223
00224 if(OldString == "InitiallyEquiped")
00225 {
00226 std::fscanf(ShipFile,"%d",&HelpInt);
00227 if(HelpInt == 0)
00228 {
00229 m_Equiped = false;
00230 }
00231 else
00232 {
00233 m_Equiped = true;
00234 }
00235
00236 m_InitiallyEquiped = m_Equiped;
00237 }
00238
00239 if(OldString == "Foreground")
00240 {
00241 std::fscanf(ShipFile,"%d",&HelpInt);
00242 if(HelpInt == 0)
00243 {
00244 m_Foreground = false;
00245 }
00246 else
00247 {
00248 m_Foreground = true;
00249 }
00250 }
00251 }
00252
00253 OldString = HelpString;
00254 }
00255
00256 m_ProjectileData.AccelX = m_ProjectileAccelX;
00257 m_ProjectileData.AccelY = m_ProjectileAccelY;
00258
00259 m_ProjectileData.SpeedX = m_ProjectileSpeedX;
00260 m_ProjectileData.SpeedY = m_ProjectileSpeedY;
00261
00262 m_ProjectileData.SpeedLimitX = m_SpeedLimitX;
00263 m_ProjectileData.SpeedLimitXSmaller = m_SpeedLimitXSmaller;
00264
00265 m_ProjectileData.SpeedLimitY = m_SpeedLimitY;
00266 m_ProjectileData.SpeedLimitYSmaller = m_SpeedLimitYSmaller;
00267
00268 m_ProjectileData.AutoRotate = m_ProjectileAutoRotate;
00269
00270 m_ProjectileData.FileName = m_ProjectileImageName;
00271 m_ProjectileData.FrameCount = ProjectileFrameCount;
00272 m_ProjectileData.FrameWidth = FrameWidth;
00273 m_ProjectileData.FrameHeight = FrameHeight;
00274 m_ProjectileData.FrameDelay = FrameDelay;
00275
00276 std::fclose(ShipFile);
00277 }
00278
00279 void CWeapon::Shoot(float X, float Y)
00280 {
00281 if(m_Equiped == false || sgl::get_clock().GetElapsedTime()*1000 - m_LastShot < m_ShootSpeed)
00282 {
00283 return;
00284 }
00285
00286 m_ShootSound.Play();
00287
00288 m_LastShot = sgl::get_clock().GetElapsedTime()*1000;
00289
00290 m_ProjectileData.X = X + m_X;
00291 m_ProjectileData.Y = Y + m_Y;
00292
00293 CProjectile* Projectile = new CProjectile;
00294 Projectile->Init(m_ProjectileData);
00295
00296 m_Projectiles.push_back(Projectile);
00297 }
00298
00299 void CWeapon::DrawProjectiles()
00300 {
00301 for(std::size_t CurProjectil = 0; CurProjectil < m_Projectiles.size(); CurProjectil++)
00302 {
00303 m_Projectiles[CurProjectil]->Draw();
00304 m_Projectiles[CurProjectil]->Update();
00305
00306 if(m_Projectiles[CurProjectil]->GetXPosition() > (SCREEN_X_SIZE - HUD_SIZE_X) + 50 ||
00307 m_Projectiles[CurProjectil]->GetXPosition() < -50 ||
00308 m_Projectiles[CurProjectil]->GetYPosition() > SCREEN_Y_SIZE + 50 ||
00309 m_Projectiles[CurProjectil]->GetYPosition() < -50)
00310 {
00311 delete m_Projectiles[CurProjectil];
00312 m_Projectiles.erase(m_Projectiles.begin() + CurProjectil);
00313 }
00314 }
00315 }
00316
00317 int CWeapon::CheckCollision(const CCollisionSystem* CounterPart)
00318 {
00319 const CCollisionSystem* CollisionSystem;
00320 int Damage = 0;
00321
00322 for(std::size_t CurProjectil = 0; CurProjectil < m_Projectiles.size(); CurProjectil++)
00323 {
00324 CollisionSystem = m_Projectiles[CurProjectil]->GetCollisionSystem();
00325 if(CollisionSystem->CheckCollision(CounterPart) == true)
00326 {
00327 delete m_Projectiles[CurProjectil];
00328 m_Projectiles.erase(m_Projectiles.begin() + CurProjectil);
00329 Damage += m_Damage;
00330
00331 m_HitSound.Play();
00332 }
00333 }
00334
00335 return Damage;
00336 }
00337
00338
00339 void CWeapon::ClearProjectils()
00340 {
00341 for(std::size_t CurProjectil = 0; CurProjectil < m_Projectiles.size(); CurProjectil++)
00342 {
00343 delete m_Projectiles[CurProjectil];
00344 }
00345 m_Projectiles.clear();
00346 }
00347
00348
00349 int CWeapon::GetProjectilXRel(int YDistance) const
00350 {
00351 float Time = 0.0f;
00352 int TempXAdd = 0;
00353
00354 if(m_ProjectileSpeedY == 0.0f)
00355 {
00356 Time = std::sqrt(2.0f*(YDistance + m_Y) / m_ProjectileAccelY);
00357 }
00358 else
00359 {
00360 if(sgn(m_ProjectileAccelY) != sgn(m_ProjectileSpeedY))
00361 {
00362 float TempTime = std::fabs(m_ProjectileSpeedY / m_ProjectileAccelY);
00363
00364 TempXAdd = 0.5f*m_ProjectileAccelX*TempTime*TempTime + m_ProjectileSpeedX*TempTime;
00365 }
00366
00367 if(m_ProjectileAccelY != 0.0f)
00368 {
00369
00370 float Dis = m_ProjectileSpeedY*m_ProjectileSpeedY - 4.0f*m_ProjectileAccelY*std::fabs(m_Y - YDistance);
00371
00372 Time = std::fabs((m_ProjectileSpeedY + std::sqrt(Dis)) / (2.0f*m_ProjectileAccelY));
00373
00374 if(m_SpeedLimitY != -99999.0f)
00375 {
00376 float TimeVel = std::fabs((m_SpeedLimitY - m_ProjectileSpeedY) / m_ProjectileAccelY);
00377
00378 if(TimeVel < Time)
00379 {
00380 int NewY = 0.5f*m_ProjectileAccelY*TimeVel*TimeVel + m_ProjectileSpeedY*TimeVel;
00381 Time = TimeVel + std::fabs(((float)NewY) / m_ProjectileSpeedY);
00382 }
00383 }
00384 }
00385 else
00386 {
00387 Time = std::fabs(((float)YDistance + m_Y) / m_ProjectileSpeedY);
00388 }
00389 }
00390
00391 int XReturn = 0.5f*m_ProjectileAccelX*Time*Time + m_ProjectileSpeedX*Time + m_X + TempXAdd;
00392
00393 if(m_SpeedLimitX != -99999.0f)
00394 {
00395 float TimeVel = std::fabs((m_SpeedLimitX - m_ProjectileSpeedX) / m_ProjectileAccelX);
00396
00397 XReturn = 0.5f*m_ProjectileAccelX*TimeVel*TimeVel + m_ProjectileSpeedX*TimeVel +
00398 m_SpeedLimitX*(Time-TimeVel) + m_X;
00399 }
00400
00401 return XReturn;
00402 }
00403