00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00020
00021
00022
00024
00025
00027
00028 #ifndef SHIP_CPP
00029 #define SHIP_CPP
00030
00031 #include "Ship.hpp"
00032 #include "UpdateFrame.hpp"
00033
00034 #include <boost/format.hpp>
00035
00036 #include <libintl.h>
00037 #define _(string) gettext(string)
00038
00040
00041 CShip::CShip()
00042 : m_CurArmor(0)
00043 , m_Armor(0)
00044 , m_Speed(0.0f)
00045 , m_AniDelay(9999)
00046 , m_DeadEmiterTime(0)
00047 , m_DeadTime(0)
00048 , m_Invulnerable(0)
00049 , log_(log4cxx::Logger::getLogger("CShip"))
00050 , frame_count(1)
00051 {}
00052
00053 CShip::~CShip()
00054 {
00055 CleanUp();
00056 }
00057
00059 void CShip::CleanUp()
00060 {
00061 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00062 {
00063 delete m_Weapons[CurWeapon];
00064 }
00065 m_Weapons.clear();
00066 }
00067
00068 void CShip::Init(const std::string& FileName)
00069 {
00070 CleanUp();
00071
00072 char strBuf[100];
00073 std::string HelpString;
00074 std::string OldString;
00075 std::string DataString;
00076 std::string ImageFile;
00077 int FrameWidth = -1;
00078 int FrameHeight = -1;
00079
00080 FILE* ShipFile = fopen(FileName.c_str(),"r");
00081 if(ShipFile == NULL)
00082 {
00083 LOG4CXX_ERROR(log_, boost::format(_("Could not open Shipfile \"%1%\"")) % FileName);
00084 return;
00085 }
00086
00087
00088 while(feof(ShipFile) == 0)
00089 {
00090 fscanf(ShipFile,"%s",strBuf);
00091 HelpString = strBuf;
00092
00093 if(HelpString == "=")
00094 {
00095
00096 if(OldString == "Image")
00097 {
00098 fscanf(ShipFile,"%s",strBuf);
00099 ImageFile = strBuf;
00100 }
00101
00102 if(OldString == "FrameWidth")
00103 {
00104 fscanf(ShipFile,"%d",&FrameWidth);
00105 }
00106 else if(OldString == "FrameHeight")
00107 {
00108 fscanf(ShipFile,"%d",&FrameHeight);
00109 }
00110 else if(OldString == "FrameCount")
00111 {
00112 fscanf(ShipFile,"%d",&frame_count);
00113 }
00114 else if(OldString == "FrameDelay")
00115 {
00116 fscanf(ShipFile,"%d",&m_AniDelay);
00117 }
00118
00119 else if(OldString == "Armor")
00120 {
00121 fscanf(ShipFile,"%d",&m_Armor);
00122 m_CurArmor = m_Armor;
00123 }
00124 else if(OldString == "Speed")
00125 {
00126 fscanf(ShipFile,"%f",&m_Speed);
00127 }
00128
00129 if(OldString == "EngineEmiter")
00130 {
00131 fscanf(ShipFile,"%s",strBuf);
00132 HelpString = strBuf;
00133 m_EngineEmiter.InitFromFile(HelpString);
00134 }
00135 else if(OldString == "EngineX")
00136 {
00137 fscanf(ShipFile,"%f",&m_EngineX);
00138 }
00139 else if(OldString == "EngineY")
00140 {
00141 fscanf(ShipFile,"%f",&m_EngineY);
00142 }
00143
00144 if(OldString == "OnDeadSound")
00145 {
00146 fscanf(ShipFile,"%s",strBuf);
00147 m_DeadSoundFile = strBuf;
00148 m_DeadSound.SetBuffer(sgl::get_sndbuffmgr().get_snd(m_DeadSoundFile));
00149 m_DeadSoundFile = strBuf;
00150 }
00151
00152 if(OldString == "OnDeadEmiter")
00153 {
00154 fscanf(ShipFile,"%s",strBuf);
00155 HelpString = strBuf;
00156 m_DeadEmiter.InitFromFile(HelpString);
00157 }
00158
00159 if(OldString == "DeadEmiterTime")
00160 {
00161 fscanf(ShipFile,"%d",&m_DeadEmiterTime);
00162 }
00163
00164 if(OldString == "CollisionSystem")
00165 {
00166 fscanf(ShipFile,"%s",strBuf);
00167 DataString = strBuf;
00168 m_CollisionSystem.Init(DataString);
00169 }
00170
00171 if(OldString == "WeaponFile")
00172 {
00173 fscanf(ShipFile,"%s",strBuf);
00174 HelpString = strBuf;
00175
00176 CWeapon* Weapon = new CWeapon;
00177 Weapon->Init(HelpString);
00178
00179 m_Weapons.push_back(Weapon);
00180 }
00181
00182 }
00183
00184 OldString = HelpString;
00185 }
00186
00187 m_Sprite.SetImage(sgl::get_imagemgr().get_img(ImageFile));
00188 m_Sprite.SetSubRect(sf::IntRect(0, 0, FrameWidth, FrameHeight));
00189
00190 fclose(ShipFile);
00191 }
00192
00193
00194
00195 void CShip::Draw()
00196 {
00197 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00198 {
00199 if(m_Weapons[CurWeapon]->IsForeground() == false)
00200 {
00201 m_Weapons[CurWeapon]->DrawProjectiles();
00202 }
00203 }
00204
00205 if(sgl::get_clock().GetElapsedTime()*1000 - m_LastAniUpdate > m_AniDelay)
00206 {
00207 update_frame(m_Sprite, frame_count);
00208 m_LastAniUpdate = sgl::get_clock().GetElapsedTime()*1000;
00209 }
00210
00211 if(IsDead() == false)
00212 {
00213 sgl::get_window().Draw(m_Sprite);
00214 m_CollisionSystem.Draw();
00215 m_CollisionSystem.SetPosition(m_Sprite.GetPosition().x + m_Sprite.GetSize().x/2, m_Sprite.GetPosition().y + m_Sprite.GetSize().y/2);
00216 }
00217 else
00218 {
00219 m_EngineEmiter.Activate(false);
00220
00221 if(sgl::get_clock().GetElapsedTime()*1000 - m_DeadTime > m_DeadEmiterTime)
00222 {
00223 m_DeadEmiter.Activate(false);
00224 }
00225
00226 m_DeadEmiter.SetPosition(m_Sprite.GetPosition().x + m_Sprite.GetSize().x/2, m_Sprite.GetPosition().y + m_Sprite.GetSize().y/2);
00227 m_DeadEmiter.Update();
00228 m_DeadEmiter.Draw();
00229 }
00230
00231 m_EngineEmiter.SetPosition(m_Sprite.GetPosition().x + m_Sprite.GetSize().x/2 + m_EngineX, m_Sprite.GetPosition().y + m_Sprite.GetSize().y/2 + m_EngineY);
00232 m_EngineEmiter.Update();
00233 m_EngineEmiter.Draw();
00234
00235 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00236 {
00237 if(m_Weapons[CurWeapon]->IsForeground() == true)
00238 {
00239 m_Weapons[CurWeapon]->DrawProjectiles();
00240 }
00241 }
00242 }
00243
00244 void CShip::Shoot()
00245 {
00246 if(IsDead())
00247 {
00248 return;
00249 }
00250
00251 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00252 {
00253 m_Weapons[CurWeapon]->Shoot(m_Sprite.GetPosition().x + m_Sprite.GetSize().x/2,m_Sprite.GetPosition().y+m_Sprite.GetSize().y/2);
00254 }
00255 }
00256
00257 void CShip::EquipWeapon(std::string Name)
00258 {
00259 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00260 {
00261 if(m_Weapons[CurWeapon]->GetName() == Name)
00262 {
00263 m_Weapons[CurWeapon]->Equip();
00264
00265 for(std::size_t CurOldWeapon = 0; CurOldWeapon < m_Weapons.size(); CurOldWeapon++)
00266 {
00267 if(m_Weapons[CurOldWeapon]->GetGroupID() == m_Weapons[CurWeapon]->GetGroupID() &&
00268 m_Weapons[CurOldWeapon]->GetName() != Name)
00269 {
00270 m_Weapons[CurOldWeapon]->Equip(false);
00271 }
00272 }
00273 }
00274 }
00275 }
00276
00277 void CShip::EquipWeapon(int GroupID)
00278 {
00279 int CurID = -1;
00280 std::size_t CurWeapon = 0;
00281 std::string OldName = "";
00282
00283 for(CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00284 {
00285 if(m_Weapons[CurWeapon]->GetGroupID() == GroupID && m_Weapons[CurWeapon]->IsEquiped() == true)
00286 {
00287 CurID = CurWeapon;
00288 OldName = m_Weapons[CurWeapon]->GetName();
00289 break;
00290 }
00291 }
00292
00293 for(CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00294 {
00296 if(m_Weapons[CurWeapon]->GetGroupID() == GroupID && CurID < CurWeapon && OldName != m_Weapons[CurWeapon]->GetName())
00297 {
00298 EquipWeapon(m_Weapons[CurWeapon]->GetName());
00299 return;
00300 }
00301 }
00302 }
00303
00304 void CShip::ResetWeapons()
00305 {
00306 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00307 {
00308 m_Weapons[CurWeapon]->Reset();
00309 }
00310 }
00311
00312 void CShip::MoveX(int Direction)
00313 {
00314 if(IsDead() == true)
00315 {
00316 return;
00317 }
00318
00319 m_Sprite.Move(m_Speed*Direction,0.0f);
00320 }
00321
00322 void CShip::MoveY(int Direction)
00323 {
00324 if(IsDead() == true)
00325 {
00326 return;
00327 }
00328
00329 m_Sprite.Move(0.0f, m_Speed*Direction);
00330 }
00331
00332 bool CShip::CheckCollision(CPowerUp* CounterPart)
00333 {
00334 if(IsDead() == true)
00335 {
00336 return false;
00337 }
00338
00339 if(m_CollisionSystem.CheckCollision(CounterPart->GetCollisionSystem()))
00340 {
00341 EquipWeapon(CounterPart->GetEquipWeapon());
00342 EquipWeapon(CounterPart->GetWeaponGroupID());
00343 Repair(CounterPart->GetRepair());
00344
00345 return true;
00346 }
00347
00348 return false;
00349 }
00350
00351 bool CShip::CheckCollision(CShip* CounterPart)
00352 {
00353 int Damage = 0;
00354
00355 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00356 {
00357 Damage = m_Weapons[CurWeapon]->CheckCollision(CounterPart->GetCollisionSystem());
00358
00359 if(CounterPart->Damage(Damage) == true)
00360 {
00361 return true;
00362 }
00363 }
00364
00365 return false;
00366 }
00367
00368 void CShip::Repair(int Repair)
00369 {
00370 if(IsDead() == true)
00371 {
00372 return;
00373 }
00374
00375 m_CurArmor += Repair;
00376
00377 if(m_CurArmor > m_Armor)
00378 {
00379 m_CurArmor = m_Armor;
00380 }
00381 }
00382
00383 bool CShip::Damage(int Damage)
00384 {
00385 if(IsDead() == true)
00386 {
00387 return true;
00388 }
00389
00390 if(m_Invulnerable == true)
00391 {
00392 return false;
00393 }
00394
00395 m_CurArmor -= Damage;
00396
00397 if(m_CurArmor <= 0)
00398 {
00399 m_DeadSound.Play();
00400
00401 m_DeadEmiter.Activate(true);
00402 m_DeadTime = sgl::get_clock().GetElapsedTime()*1000;
00403
00404 return true;
00405 }
00406 return false;
00407 }
00408
00409
00410 int CShip::GetProjectilCount() const
00411 {
00412 int Count = 0;
00413
00414 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00415 {
00416 Count += m_Weapons[CurWeapon]->GetProjectilCount();
00417 }
00418
00419 return Count;
00420 }
00421
00422 float CShip::GetProjectilXPosition(int Projectil) const
00423 {
00424 int Add = 0;
00425
00426 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00427 {
00428 if(Add + m_Weapons[CurWeapon]->GetProjectilCount() > Projectil)
00429 {
00430 return m_Weapons[CurWeapon]->GetProjectilX(Projectil - Add);
00431 }
00432
00433 Add += m_Weapons[CurWeapon]->GetProjectilCount();
00434 }
00435
00436 return 0.0f;
00437 }
00438
00439 float CShip::GetProjectilYPosition(int Projectil) const
00440 {
00441 int Add = 0;
00442
00443 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00444 {
00445 if(Add + m_Weapons[CurWeapon]->GetProjectilCount() > Projectil)
00446 {
00447 return m_Weapons[CurWeapon]->GetProjectilY(Projectil - Add);
00448 }
00449
00450 Add += m_Weapons[CurWeapon]->GetProjectilCount();
00451 }
00452
00453 return 0.0f;
00454 }
00455
00456 int CShip::GetProjectilDamage(int Projectil) const
00457 {
00458 int Add = 0;
00459
00460 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00461 {
00462 if(Add + m_Weapons[CurWeapon]->GetProjectilCount() > Projectil)
00463 {
00464 return m_Weapons[CurWeapon]->GetDamage();
00465 }
00466
00467 Add += m_Weapons[CurWeapon]->GetProjectilCount();
00468 }
00469
00470 return 0;
00471 }
00472
00473
00474 float CShip::GetProjectilWidth(int Projectil) const
00475 {
00476 int Add = 0;
00477
00478 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00479 {
00480 if(Add + m_Weapons[CurWeapon]->GetProjectilCount() > Projectil)
00481 {
00482 return m_Weapons[CurWeapon]->GetProjectilWidth(Projectil - Add);
00483 }
00484
00485 Add += m_Weapons[CurWeapon]->GetProjectilCount();
00486 }
00487
00488 return 0.0f;
00489 }
00490
00491
00492 int CShip::GetWeaponDamage(std::size_t Weapon) const
00493 {
00494 if(Weapon > m_Weapons.size())
00495 {
00496 return 0;
00497 }
00498
00499 return m_Weapons[Weapon]->GetDamage();
00500 }
00501
00502 std::string CShip::GetWeaponName(std::size_t Weapon) const
00503 {
00504 if(Weapon > m_Weapons.size())
00505 {
00506 return 0;
00507 }
00508
00509 return m_Weapons[Weapon]->GetName();
00510 }
00511
00512
00513 int CShip::GetWeaponTypeCount() const
00514 {
00515 std::vector<int> UsedTypes;
00516 bool Used;
00517 int Count = 0;
00518
00519 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00520 {
00521 Used = false;
00522 for(std::size_t CurType = 0; CurType < UsedTypes.size(); CurType++)
00523 {
00524 if(UsedTypes[CurType] == m_Weapons[CurWeapon]->GetGroupID())
00525 {
00526 Used = true;
00527 }
00528 }
00529
00530 if(Used == false)
00531 {
00532 Count++;
00533 UsedTypes.push_back(m_Weapons[CurWeapon]->GetGroupID());
00534 }
00535 }
00536
00537 UsedTypes.clear();
00538
00539 return Count;
00540 }
00541
00542 std::string CShip::GetCurWeaponNameOfType(std::size_t GroupID) const
00543 {
00544 const CWeapon* Weapon = GetCurWeaponOfType(GroupID);
00545
00546 if(Weapon != NULL)
00547 {
00548 return Weapon->GetName();
00549 }
00550
00551 return "";
00552 }
00553
00554 const CWeapon* CShip::GetCurWeaponOfType(std::size_t GroupID) const
00555 {
00556 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00557 {
00558 if(m_Weapons[CurWeapon]->GetGroupID() == GroupID && m_Weapons[CurWeapon]->IsEquiped())
00559 {
00560 return m_Weapons[CurWeapon];
00561 }
00562 }
00563
00564 return NULL;
00565 }
00566
00567 int CShip::GetProjectileTarget(int YDistance) const
00568 {
00569 int Count = 0;;
00570 int XSum = 0;
00571
00572 for(std::size_t CurWeapon = 0; CurWeapon < m_Weapons.size(); CurWeapon++)
00573 {
00574 if(m_Weapons[CurWeapon]->IsEquiped())
00575 {
00576 ++Count;
00577 XSum += m_Weapons[CurWeapon]->GetProjectilXRel(YDistance);
00578 }
00579 }
00580
00581 return (Count==0) ? 0 : (XSum / Count);
00582 }
00583
00584
00585 #endif