battle_actors.cpp

Go to the documentation of this file.
00001 
00002 //            Copyright (C) 2004-2007 by The Allacrost Project
00003 //                         All Rights Reserved
00004 //
00005 // This code is licensed under the GNU GPL version 2. It is free software and
00006 // you may modify it and/or redistribute it under the terms of this license.
00007 // See http://www.gnu.org/copyleft/gpl.html for details.
00009 
00018 #include <iostream>
00019 #include <sstream>
00020 
00021 #include "utils.h"
00022 #include "audio.h"
00023 #include "video.h"
00024 #include "input.h"
00025 #include "system.h"
00026 #include "global.h"
00027 #include "script.h"
00028 #include "battle.h"
00029 #include "battle_actors.h"
00030 
00031 using namespace hoa_utils;
00032 using namespace hoa_audio;
00033 using namespace hoa_video;
00034 using namespace hoa_input;
00035 using namespace hoa_system;
00036 using namespace hoa_global;
00037 using namespace hoa_script;
00038 
00039 using namespace hoa_battle::private_battle;
00040 
00041 namespace hoa_battle {
00042 
00043 namespace private_battle {
00044 
00045 // *****************************************************************************
00046 // BattleActor class
00047 // *****************************************************************************
00048 
00049 BattleActor::BattleActor() : _total_time_damaged(0),
00050   _damage_dealt(0),
00051   _is_queued_to_perform(false)
00052 {
00053   //Load time portrait selector
00054   _time_portrait_selected.SetDimensions(45,45);
00055   _time_portrait_selected.SetFilename("img/menus/stamina_icon_selected.png");
00056   VideoManager->LoadImage(_time_portrait_selected);
00057 
00058   // Reset attack timer, TEMP CODE!!!!
00059   _TEMP_attack_animation_timer.Initialize(0);
00060   _TEMP_attack_animation_timer.Run();
00061 }
00062 
00063 BattleActor::~BattleActor()
00064 {
00065   VideoManager->DeleteImage(_time_portrait_selected);
00066 }
00067 
00068 //Copies stats from the GlobalActor handle that is passed in
00069 void BattleActor::InitBattleActorStats(hoa_global::GlobalActor* actor)
00070 {
00071   SetMaxHitPoints(actor->GetMaxHitPoints());
00072   SetMaxSkillPoints(actor->GetMaxSkillPoints());
00073   SetHitPoints(actor->GetHitPoints());
00074   SetSkillPoints(actor->GetSkillPoints());
00075   SetStrength(actor->GetStrength());
00076   SetVigor(actor->GetVigor());
00077   SetFortitude(actor->GetFortitude());
00078   SetProtection(actor->GetProtection());
00079   SetAgility(actor->GetAgility());
00080   SetEvade(actor->GetEvade());
00081 
00082   CalcPhysicalAttack();
00083   CalcMetaPhysicalAttack();
00084   CalcPhysicalDefense();
00085   CalcMetaPhysicalDefense();
00086 }
00087 
00088 // Draws the character's portrait on the time meter
00089 void BattleActor::DrawTimePortrait(bool is_selected) {
00090   if (IsAlive()) {
00091     VideoManager->Move(995, _time_portrait_location);
00092 
00093     VideoManager->DrawImage(_time_meter_portrait);
00094 
00095     if (is_selected)
00096       VideoManager->DrawImage(_time_portrait_selected);
00097   }
00098 }
00099 
00100 //Reset actor wait time
00101 void BattleActor::ResetWaitTime()
00102 {
00103   _wait_time.Reset();
00104   _wait_time.Run();
00105 
00106   //Sets time meter portrait position
00107   _time_portrait_location = 128.f;
00108 }
00109 
00110 
00111 //For when he dies
00112 void BattleActor::OnDeath()
00113 {
00114   GetWaitTime()->Reset();
00115 }
00116 
00117 //For when he is given new life! LIFE!
00118 void BattleActor::OnLife()
00119 {
00120   GetWaitTime()->Run();
00121 }
00122 
00123 // Gives a specific amount of damage for the actor
00124 // Switched from uint to int to allow for nullified attacks
00125 //(i.e. attacks where damage dealt is < defense)
00126 void BattleActor::TakeDamage(int32 damage)
00127 {
00128   _total_time_damaged = 1;
00129 
00130   if (damage <= 0)
00131   {
00132     _damage_dealt = RandomBoundedInteger(1, 5);
00133   }
00134   else
00135   {
00136     _damage_dealt = damage + static_cast<uint32>(RandomBoundedInteger(0, 4));
00137   }
00138 
00139   if (static_cast<uint32>(_damage_dealt) >= GetHitPoints()) // Was it a killing blow?
00140   {
00141     SetHitPoints(0);
00142     OnDeath();
00143     current_battle->RemoveScriptedEventsForActor(this);
00144   }
00145   else {
00146     SetHitPoints(GetHitPoints() - _damage_dealt);
00147   }
00148 }
00149 
00150 void BattleActor::TEMP_ResetAttackTimer()
00151 {
00152   _TEMP_attack_animation_timer.Initialize(1000);
00153   _TEMP_attack_animation_timer.Run();
00154 }
00155 
00156 // Is the actor attacking right now
00157 bool BattleActor::TEMP_IsAttacking() const
00158 {
00159   return !_TEMP_attack_animation_timer.IsFinished();
00160 }
00161 
00162 // *****************************************************************************
00163 // BattleCharacterActor class
00164 // *****************************************************************************
00165 BattleCharacterActor::BattleCharacterActor(GlobalCharacter * character, float x_location, float y_location) :
00166   BattleActor(),
00167   _global_character(character)
00168   /*_x_location(x_location),
00169   _y_location(y_location),
00170   _x_origin(_x_location),
00171   _y_origin(_y_location)*/
00172   //_total_time_damaged(0),
00173   //_damage_dealt(0),
00174   //_is_queued_to_perform(false)
00175 {
00176   //Cannot initalize protected members in init list for some reason
00177   _x_location = x_location;
00178   _y_location = y_location;
00179   _x_origin = _x_location;
00180   _y_origin = _y_location;
00181   //FIX ME
00182   _time_meter_portrait.SetFilename("img/icons/actors/characters/" + character->GetFilename() + ".png");
00183   _time_meter_portrait.SetDimensions(45,45);
00184   VideoManager->LoadImage(_time_meter_portrait);
00185 
00186   //Load time portrait selector
00187   /*_time_portrait_selected.SetDimensions(45,45);
00188   _time_portrait_selected.SetFilename("img/menus/stamina_icon_selected.png");
00189   VideoManager->LoadImage(_time_portrait_selected);*/
00190 
00191   //_time_portrait_location = 128;
00192   //FIX ME Use char stats to determine wait time
00193   //FIX ME #2 Do not initialize here.  Have BattleMode loop through all actors
00194   // and scale wait time based on slowest actor
00195   //_wait_time.SetDuration(5000);
00196   //ResetWaitTime();
00197   //_wait_time.Initialize();
00198   //_action_state = ACTION_IDLE;
00199 
00200   // Load images for the down menu
00201   _status_bar_cover_image.SetFilename("img/menus/bar_cover.png");
00202   VideoManager->LoadImage(_status_bar_cover_image);
00203 
00204   _status_menu_image.SetFilename("img/menus/battle_character_menu.png");
00205   VideoManager->LoadImage(_status_menu_image);
00206 }
00207 
00208 
00209 BattleCharacterActor::~BattleCharacterActor() {
00210   //FIX ME
00211   VideoManager->DeleteImage(_time_meter_portrait);
00212   //VideoManager->DeleteImage(_time_portrait_selected);
00213   VideoManager->DeleteImage(_status_bar_cover_image);
00214   VideoManager->DeleteImage(_status_menu_image);
00215 }
00216 
00217 
00218 /*void BattleCharacterActor::ResetWaitTime()
00219 {
00220   _wait_time.Reset();// = 5000;
00221   _wait_time.Initialize();
00222 
00223   //Sets time meter portrait position
00224   _time_portrait_location = 128.f;
00225 }*/
00226 
00227 // Updates the state of the character. Must be called every frame!
00228 void BattleCharacterActor::Update()
00229 { 
00230   /*if (GetActor()->IsAlive() == false)
00231   {
00232     current_battle->RemoveScriptedEventsForActor(this);
00233   }*/
00234   if (!_wait_time.IsFinished() && IsAlive() && !IsQueuedToPerform() && _wait_time.IsRunning())
00235     _time_portrait_location += SystemManager->GetUpdateTime() * (405.0f / _wait_time.GetDuration());
00236 
00237   GetActor()->RetrieveBattleAnimation("idle")->Update();
00238 
00239   if (TEMP_IsAttacking()) {
00240     if ((_x_location - _x_origin) < 50)
00241       _x_location += 0.8f * static_cast<float>(SystemManager->GetUpdateTime());
00242   }
00243   else
00244     SetXLocation(GetXOrigin()); // Restore original place
00245 
00246   //if (!_wait_time.IsFinished() && GetActor()->IsAlive() && !IsQueuedToPerform())
00247   //  _time_portrait_location += SystemManager->GetUpdateTime() * (405.0f / _wait_time.GetDuration());  
00248 }
00249 
00250 //Calculates the actor's base physical attack damage
00251 void BattleCharacterActor::CalcPhysicalAttack()
00252 {
00253   _physical_attack = _strength;
00254 
00255   if (GetActor()->GetWeaponEquipped())
00256     _physical_attack += GetActor()->GetWeaponEquipped()->GetPhysicalAttack();
00257 }
00258 
00259 //Calculates the actor's base metaphysical attack damage
00260 void BattleCharacterActor::CalcMetaPhysicalAttack()
00261 {
00262   _metaphysical_attack = _vigor;
00263 
00264   if (GetActor()->GetWeaponEquipped())
00265     _metaphysical_attack += GetActor()->GetWeaponEquipped()->GetMetaphysicalAttack();
00266 }
00267 
00268 //Calculates the actor's base physical defense
00269 void BattleCharacterActor::CalcPhysicalDefense(hoa_global::GlobalAttackPoint* attack_point)
00270 {
00271   _physical_defense = _fortitude;
00272   std::vector<GlobalArmor*>* armor = GetActor()->GetArmorEquipped();
00273 
00274   for (uint32 i = 0; i < armor->size(); ++i)
00275   {
00276     _physical_defense += armor->at(i)->GetPhysicalDefense();
00277   }
00278 
00279   if (attack_point)
00280   {
00281     _physical_defense += static_cast<uint32>(_physical_defense * attack_point->GetFortitudeModifier());
00282   }
00283 }
00284 
00285 //Calculates the actor's base metaphysical defense
00286 void BattleCharacterActor::CalcMetaPhysicalDefense(hoa_global::GlobalAttackPoint* attack_point)
00287 {
00288   _metaphysical_defense = _protection;
00289 
00290   std::vector<GlobalArmor*>* armor = GetActor()->GetArmorEquipped();
00291 
00292   for (uint32 i = 0; i < armor->size(); ++i)
00293   {
00294     _metaphysical_defense += armor->at(i)->GetMetaphysicalDefense();
00295   }
00296 
00297   if (attack_point)
00298   {
00299     _metaphysical_defense += static_cast<uint32>(_metaphysical_defense * attack_point->GetProtectionModifier());
00300   }
00301 }
00302 
00303 //Calculates the actor's evade
00304 void BattleCharacterActor::CalcEvade(hoa_global::GlobalAttackPoint* attack_point)
00305 {
00306   _combat_evade = _evade;
00307 
00308   //std::vector<GlobalArmor*> armor = GetActor()->GetArmorEquipped();
00309 
00310   /*for (uint32 i = 0; i < armor.size(); ++i)
00311   {
00312     _metaphysical_defense += armor[i]->GetMetaphysicalDefense();
00313   }*/
00314   if (attack_point)
00315   {
00316     _combat_evade += static_cast<uint32>(_combat_evade * attack_point->GetEvadeModifier());
00317   }
00318 }
00319 
00320 // Draws the character's current sprite animation frame
00321 void BattleCharacterActor::DrawSprite() {
00322   VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00323 
00324   if (IsAlive()) {
00325     // Draw the actor selector image if this character is currently selected
00326     if (this == current_battle->_selected_character && current_battle->_cursor_state != CURSOR_IDLE) {
00327       VideoManager->Move(_x_location - 20.0f, _y_location - 20.0f);
00328       VideoManager->DrawImage(current_battle->_actor_selection_image);
00329     }
00330     // Draw the character sprite
00331     VideoManager->Move(_x_location, _y_location);
00332     GetActor()->RetrieveBattleAnimation("idle")->Draw();
00333 
00334     if (this == current_battle->_selected_target) {
00335       VideoManager->Move(_x_location - 20.0f, _y_location - 20.0f);
00336       VideoManager->DrawImage(current_battle->_actor_selection_image);
00337     }
00338 
00339     // TEMP: determine if character sprite needs red damage numbers drawn next to it
00340     if (_total_time_damaged > 0) {
00341       _total_time_damaged += SystemManager->GetUpdateTime();
00342       VideoManager->SetFont( "battle_dmg" );
00343       VideoManager->SetTextColor(Color::red);
00344       VideoManager->Move(GetXLocation() + 40.0f, GetYLocation() + ( _total_time_damaged / 35.0f ) + 100.0f);
00345       VideoManager->DrawText(NumberToString(_damage_dealt));
00346       VideoManager->SetFont( "battle" );
00347 
00348       if (_total_time_damaged > 3000) { // Show it for three seconds
00349         _total_time_damaged = 0;
00350       }
00351         //current_battle->SetPerformingScript (false);
00352       //}
00353     }
00354   }
00355   else {
00356     // TODO: draw the "incapacitated" character here
00357   }
00358 }
00359 
00360 
00361 // Draws the character's damage-blended face portrait
00362 void BattleCharacterActor::DrawPortrait() {
00363   std::vector<StillImage> & portrait_frames = *(GetActor()->GetBattlePortraits());
00364   VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00365   VideoManager->Move(48, 9);
00366 
00367   float hp_percent =  static_cast<float>(GetHitPoints()) / static_cast<float>(GetMaxHitPoints());
00368 
00369   if (GetActor()->GetHitPoints() == 0) {
00370     VideoManager->DrawImage(portrait_frames[4]);
00371   }
00372   // The blend alpha will range from 1.0 to 0.0 in the following calculations
00373   else if (hp_percent < 0.25f) {
00374     VideoManager->DrawImage(portrait_frames[4]);
00375     float alpha = (hp_percent) * 4;
00376     VideoManager->DrawImage(portrait_frames[3], Color(1.0f, 1.0f, 1.0f, alpha));
00377   }
00378   else if (hp_percent < 0.50f) {
00379     VideoManager->DrawImage(portrait_frames[3]);
00380     float alpha = (hp_percent - 0.25f) * 4;
00381     VideoManager->DrawImage(portrait_frames[2], Color(1.0f, 1.0f, 1.0f, alpha));
00382   }
00383   else if (hp_percent < 0.75f) {
00384     VideoManager->DrawImage(portrait_frames[2]);
00385     float alpha = (hp_percent - 0.50f) * 4;
00386     VideoManager->DrawImage(portrait_frames[1], Color(1.0f, 1.0f, 1.0f, alpha));
00387   }
00388   else if (hp_percent < 1.00f) {
00389     VideoManager->DrawImage(portrait_frames[1]);
00390     float alpha = (hp_percent - 0.75f) * 4;
00391     VideoManager->DrawImage(portrait_frames[0], Color(1.0f, 1.0f, 1.0f, alpha));
00392   }
00393   else { // Character is at full health
00394     VideoManager->DrawImage(portrait_frames[0]);
00395   }
00396 }
00397 
00398 
00399 // Draws the character's portrait on the time meter
00400 /*void BattleCharacterActor::DrawTimePortrait(bool is_selected) {
00401 
00402   if (GetActor()->IsAlive()) {
00403     VideoManager->Move(995, _time_portrait_location);
00404 
00405     VideoManager->DrawImage(_time_meter_portrait);
00406 
00407     if (is_selected)
00408       VideoManager->DrawImage(_time_portrait_selected);
00409   }
00410 }*/
00411 // Draws the character's status information
00412 void BattleCharacterActor::DrawStatus() {
00413   // Used to determine where to draw the character's status
00414   float y_offset = 0.0f;
00415 
00416   // Determine what vertical order the character is in and set the y_offset accordingly
00417   if (current_battle->_character_actors[0] == this) {
00418     y_offset = 0.0f;
00419   } else if (current_battle->_character_actors[1] == this) {
00420     y_offset = -25.0f;
00421   } else if (current_battle->_character_actors[2] == this) {
00422     y_offset = -50.0f;
00423   } else if (current_battle->_character_actors[3] == this) {
00424     y_offset = -75.0f;
00425   }
00426 
00427   // Draw the background of the menu
00428   VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00429   VideoManager->Move(149, 84.0f + y_offset);
00430   VideoManager->DrawImage(_status_menu_image);
00431 
00432   VideoManager->SetTextColor(Color::white);
00433 
00434   // Draw the character's name
00435   VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00436   VideoManager->Move(225.0f, 90.0f + y_offset);
00437   VideoManager->DrawText(GetActor()->GetName());
00438 
00439   // If the swap key is being held down, draw status icons instead of HP and SP bars
00440   if (InputManager->SwapState()) {
00441     // TODO: draw status icons and information
00442 
00443     // Draw all of the character's current status afflictions
00444     // VideoManager->MoveRel(152, 4);
00445     // for (uint8 i = 0; i < _effects.size(); i++) {
00446     //  VideoManager->DrawImage(_effects[i].image);
00447     //  VideoManager->MoveRel(25, 0);
00448     // }
00449   }
00450   else {
00451     // Shrinking bars (HP, SP)
00452     float bar_size;
00453 
00454     // HP, green bar
00455     VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_NO_BLEND, 0);
00456     bar_size = static_cast<float>(83*GetHitPoints())/static_cast<float>(GetMaxHitPoints());
00457     VideoManager->Move(312, 90 + y_offset);
00458 
00459     if (GetHitPoints() > 0)   // Draw color bar (if needed)
00460     {
00461       VideoManager->DrawRectangle(bar_size,6,Color(0.133f,0.455f,0.133f,1.0f));
00462     }
00463     if (GetHitPoints() != GetMaxHitPoints())  // Draw black bar (if needed)
00464     {
00465       VideoManager->MoveRelative(bar_size, 0.0f);
00466       VideoManager->DrawRectangle(83.0f-bar_size,6,Color::black);
00467       VideoManager->Move(312, 90 + y_offset);
00468     }
00469 
00470     VideoManager->SetDrawFlags(VIDEO_BLEND_ADD, 0);
00471     VideoManager->DrawImage(_status_bar_cover_image);
00472 
00473     // SP, blue bar
00474     VideoManager->SetDrawFlags(VIDEO_NO_BLEND, 0);
00475     bar_size = static_cast<float>(84*GetSkillPoints())/static_cast<float>(GetMaxSkillPoints());
00476     VideoManager->Move(412, 90 + y_offset);
00477 
00478     if (GetSkillPoints() > 0) // Draw color bar (if needed)
00479     {
00480       VideoManager->DrawRectangle(bar_size,6,Color(0.129f,0.263f,0.451f,1.0f));
00481     }
00482     if (GetHitPoints() != GetMaxHitPoints())  // Draw black bar (if needed)
00483     {
00484       VideoManager->MoveRelative(bar_size,0.0f);
00485       VideoManager->DrawRectangle(83.0f-bar_size,6,Color::black);
00486       VideoManager->Move(412, 90 + y_offset);
00487     }
00488 
00489     VideoManager->SetDrawFlags(VIDEO_BLEND_ADD, 0);
00490     VideoManager->DrawImage(_status_bar_cover_image);
00491 
00492     // Draw the character's current health on top of the middle of the HP bar
00493     VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00494 
00495     VideoManager->Move(355.0f, 90.0f + y_offset);
00496     VideoManager->DrawText(NumberToString(GetHitPoints()));
00497 
00498     // Draw the character's current skill points on top of the middle of the SP bar
00499     VideoManager->MoveRelative(100, 0);
00500     VideoManager->DrawText(NumberToString(GetSkillPoints()));
00501   }
00502 }
00503 
00504 
00505 // Gives a specific amount of damage for the character
00506 /*void BattleCharacterActor::TakeDamage(uint32 damage)
00507 {
00508   _total_time_damaged = 1;
00509   _damage_dealt = damage;
00510 
00511   if (damage >= GetActor()->GetHitPoints()) // Was it a killing blow?
00512   {
00513     GetActor()->SetHitPoints(0);
00514     current_battle->RemoveScriptedEventsForActor(this);
00515   }
00516   else {
00517     GetActor()->SetHitPoints(GetActor()->GetHitPoints() - damage);
00518   }
00519 }*/
00520 
00521 //For now, only update HP and SP
00522 void BattleCharacterActor::UpdateGlobalActorStats()
00523 {
00524   GetActor()->SetHitPoints(GetHitPoints());
00525   GetActor()->SetSkillPoints(GetSkillPoints());
00526 }
00527 
00529 // EnemyActor class
00531 BattleEnemyActor::BattleEnemyActor(GlobalEnemy enemy, float x_location, float y_location) :
00532   BattleActor(),
00533   _global_enemy(enemy.GetID())
00534   /*_x_location(x_location),
00535   _y_location(y_location),
00536   _x_origin(_x_location),
00537   _y_origin(_y_location)*/
00538   /*_total_time_damaged(0),
00539   _damage_dealt(0),
00540   _is_queued_to_perform(false)*/
00541 {
00542   //Cannot initalize protected members in init list for some reason
00543   _x_location = x_location;
00544   _y_location = y_location;
00545   _x_origin = _x_location;
00546   _y_origin = _y_location;
00547 
00548   //FIX ME
00549   _time_meter_portrait.SetFilename("img/icons/actors/enemies/" + _global_enemy.GetFilename() + ".png");
00550   //_time_meter_portrait.SetFilename("img/menus/stamina_icon.png");
00551   _time_meter_portrait.SetDimensions(45,45);
00552   VideoManager->LoadImage(_time_meter_portrait);
00553 
00554   //Load time portrait selector
00555   /*_time_portrait_selected.SetDimensions(45,45);
00556   _time_portrait_selected.SetFilename("img/menus/stamina_icon.png");
00557   VideoManager->LoadImage(_time_portrait_selected);*/
00558 
00559   //GetWaitTime()->SetDuration(2000);
00560   //ResetWaitTime();
00561 }
00562 
00563 
00564 
00565 BattleEnemyActor::~BattleEnemyActor() {
00566   // FIX ME
00567   VideoManager->DeleteImage(_time_meter_portrait);
00568   //VideoManager->DeleteImage(_time_portrait_selected);
00569 }
00570 
00571 //Calculates the actor's base physical attack damage
00572 void BattleEnemyActor::CalcPhysicalAttack()
00573 {
00574   _physical_attack = _strength;
00575 
00576   if (GetActor()->GetWeaponEquipped())
00577     _physical_attack += GetActor()->GetWeaponEquipped()->GetPhysicalAttack();
00578 }
00579 
00580 //Calculates the actor's base metaphysical attack damage
00581 void BattleEnemyActor::CalcMetaPhysicalAttack()
00582 {
00583   _metaphysical_attack = _vigor;
00584 
00585   if (GetActor()->GetWeaponEquipped())
00586     _metaphysical_attack += GetActor()->GetWeaponEquipped()->GetMetaphysicalAttack();
00587 }
00588 
00589 //Calculates the actor's base physical defense
00590 void BattleEnemyActor::CalcPhysicalDefense(GlobalAttackPoint* attack_point)
00591 {
00592   _physical_defense = _fortitude;
00593 
00594   if (attack_point)
00595   {
00596     _physical_defense += static_cast<uint32>(_physical_defense + attack_point->GetFortitudeModifier());
00597   }
00598 }
00599 
00600 //Calculates the actor's base metaphysical defense
00601 void BattleEnemyActor::CalcMetaPhysicalDefense(GlobalAttackPoint* attack_point)
00602 {
00603   _metaphysical_defense = _protection;
00604 
00605   if (attack_point)
00606   {
00607     _metaphysical_defense += static_cast<uint32>(attack_point->GetProtectionModifier());
00608   }
00609 }
00610 
00611 //Calculates the actor's base evade
00612 void BattleEnemyActor::CalcEvade(hoa_global::GlobalAttackPoint* attack_point)
00613 {
00614   _combat_evade = _evade;
00615 
00616   //std::vector<GlobalArmor*> armor = GetActor()->GetArmorEquipped();
00617 
00618   /*for (uint32 i = 0; i < armor.size(); ++i)
00619   {
00620     _metaphysical_defense += armor[i]->GetMetaphysicalDefense();
00621   }*/
00622   if (attack_point)
00623   {
00624     _combat_evade += static_cast<uint32>(_combat_evade * attack_point->GetEvadeModifier());
00625   }
00626 }
00627 
00628 /*void BattleEnemyActor::ResetWaitTime()
00629 {
00630   _wait_time.Reset();
00631   _wait_time.Initialize();
00632   //Sets time meter portrait position
00633 
00634   _time_portrait_location = 128.f;
00635 }*/
00636 
00637 // Compares the Y-coordinates of the actors, used for sorting the actors up-down when drawing
00638 // BROKEN!!! My bad -CD
00639 bool BattleEnemyActor::operator<(const BattleEnemyActor & other) const
00640 {
00641   //if ((_y_location - ((*GetActor()).GetHeight())) > (other.GetYLocation() - (*(other.GetActor()).GetHeight())))
00642   //  return true;
00643   
00644   return false;
00645 }
00646 
00647 // Updates the action status of the enemy
00648 void BattleEnemyActor::Update() {
00649 
00650   //if (_wait_time)
00651   //  _wait_time -= SystemManager->GetUpdateTime();
00652   if (!_wait_time.IsFinished() && IsAlive() && !IsQueuedToPerform() && _wait_time.IsRunning())
00653     _time_portrait_location += SystemManager->GetUpdateTime() * (405.0f / _wait_time.GetDuration());
00654 
00655   if (IsAlive() && !IsQueuedToPerform() && GetWaitTime()->IsFinished())
00656   {
00657     //if (_wait_time.IsFinished())
00658     //{
00659       //_wait_time = 0;
00660       //FIX ME Needs real AI decisions
00661       //we can perform another attack
00662       //MF: Bad bad bad.  We do not build a queue of targets.  Not anymore.
00663       //All we do is have a handle to either 1 enemy or char to see which
00664       //side we're attacking.  If it's a party skill, then the script just
00665       //loops over them.  Besides, we don't want to send dequeues to the
00666       //Lua stack.
00667 
00668       /*std::deque<BattleActor*> final_targets;
00669       std::deque<BattleCharacterActor*> targets = current_battle->GetCharacters();
00670 
00671       for (uint8 i = 0; i < targets.size(); i++) {
00672         final_targets.push_back(dynamic_cast<BattleActor*>(targets[i]));
00673       }*/
00674 
00675       // okay, we can perform another attack.  set us up as queued to perform.
00676       SetQueuedToPerform(true);
00677       GlobalSkill* skill = (GetActor()->GetSkills()->begin()->second);
00678       //FIX ME Until we have AI, pick Claudius
00679       ScriptEvent *se = new ScriptEvent(this, current_battle->GetPlayerCharacterAt(0), skill);
00680       current_battle->AddScriptEventToQueue(se);
00681 
00682       //current_battle->AddScriptEventToQueue(new ScriptEvent(this, final_targets, "sword_swipe", 3000));
00683       SetXLocation(GetXOrigin()); // Always attack from the starting location
00684     //}
00685     //FIX ME have to use char stats
00686     /*else
00687       _time_portrait_location += SystemManager->GetUpdateTime() * (405.f / _wait_time.GetDuration());//.081f;*/
00688   }
00689 
00690   // If we're attacking, update the offset a little
00691   // FIX ME Let the script event handle this
00692   if (TEMP_IsAttacking()) {
00693     if ((_x_origin - _x_location) < 50)
00694       _x_location -= 0.8f * static_cast<float>(SystemManager->GetUpdateTime());
00695   }
00696   else
00697     SetXLocation(GetXOrigin()); // Restore original place
00698 
00699 }
00700 
00701 
00702 // Draws the damage-blended enemy sprite
00703 void BattleEnemyActor::DrawSprite() {
00704   VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00705 
00706   std::vector<StillImage>& sprite_frames = *(GetActor()->GetBattleSpriteFrames());
00707 
00708   // Draw the sprite's final damage frame in grayscale and return
00709   if (!IsAlive()) {
00710     VideoManager->Move(_x_location, _y_location);
00711     sprite_frames[3].EnableGrayScale();
00712     VideoManager->DrawImage(sprite_frames[3]);
00713     sprite_frames[3].DisableGrayScale();
00714   }
00715   else {
00716     // Draw the actor selector image over the currently selected enemy
00717     if (this == current_battle->_selected_target) {
00718       VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00719       VideoManager->Move(_x_location + GetActor()->GetSpriteWidth() / 2, _y_location - 25);
00720       VideoManager->DrawImage(current_battle->_actor_selection_image);
00721       VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00722     }
00723 
00724     // Draw the enemy's damage-blended sprite frames  
00725     VideoManager->Move(_x_location, _y_location);
00726     float hp_percent = static_cast<float>(GetHitPoints()) / static_cast<float>(GetMaxHitPoints());
00727 
00728     // Alpha will range from 1.0 to 0.0 in the following calculations
00729     if (hp_percent < 0.33f) {
00730       VideoManager->DrawImage(sprite_frames[3]);
00731       float alpha = (hp_percent) * 3;
00732       VideoManager->DrawImage(sprite_frames[2], Color(1.0f, 1.0f, 1.0f, alpha));
00733     }
00734     else if (hp_percent < 0.66f) {
00735       VideoManager->DrawImage(sprite_frames[2]);
00736       float alpha = (hp_percent - 0.33f) * 3;
00737       VideoManager->DrawImage(sprite_frames[1], Color(1.0f, 1.0f, 1.0f, alpha));
00738     }
00739     else if (hp_percent < 1.00f) {
00740       VideoManager->DrawImage(sprite_frames[1]);
00741       float alpha = (hp_percent - 0.66f) * 3;
00742       VideoManager->DrawImage(sprite_frames[0], Color (1.0f, 1.0f, 1.0f, alpha));
00743     }
00744     else { // Enemy is at full health
00745       VideoManager->DrawImage(sprite_frames[0]);
00746     }
00747 
00748     // Draw the attack point indicator if necessary
00749     if (this == current_battle->_selected_target && current_battle->_cursor_state == CURSOR_SELECT_ATTACK_POINT) {
00750       VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_CENTER, 0);
00751       std::vector<GlobalAttackPoint*>& attack_points = *(GetActor()->GetAttackPoints());
00752 
00753       VideoManager->Move(GetXLocation() + attack_points[current_battle->_selected_attack_point]->GetXPosition(),
00754         GetYLocation() + attack_points[current_battle->_selected_attack_point]->GetYPosition());
00755       VideoManager->DrawImage(current_battle->_attack_point_indicator);
00756 
00757       // Reset default X and Y draw orientation
00758       VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, 0);
00759     }
00760   }
00761 
00762   // Determine if enemy needs to have red damage text drawn next to it
00763   if (_total_time_damaged > 0) {
00764     _total_time_damaged += SystemManager->GetUpdateTime();
00765 
00766     VideoManager->SetFont( "battle_dmg" );
00767     VideoManager->SetTextColor(Color::red);
00768     VideoManager->Move(GetXLocation() + 25.0f, GetYLocation() + ( _total_time_damaged / 35.0f ) + 80.0f);
00769     VideoManager->DrawText(NumberToString(_damage_dealt));
00770     VideoManager->SetFont( "battle" );
00771 
00772     if (_total_time_damaged > 3000) {
00773       _total_time_damaged = 0;
00774       //current_battle->SetPerformingScript(false);
00775     }
00776   }
00777 }
00778 
00779 // Draws the enemy's time meter portrait
00780 /*void BattleEnemyActor::DrawTimePortrait(bool is_selected)
00781 {
00782   if (GetActor()->IsAlive()) {
00783     VideoManager->Move(995, _time_portrait_location);
00784 
00785     VideoManager->DrawImage(_time_meter_portrait);
00786 
00787     if (is_selected)
00788       VideoManager->DrawImage(_time_portrait_selected);
00789   }
00790 }*/
00791 
00792 // Draws the enemy's status information
00793 void BattleEnemyActor::DrawStatus() {
00794   // Draw the enemy's name
00795   VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00796   VideoManager->SetTextColor(Color::white);
00797   VideoManager->Move(920, 84);
00798   VideoManager->DrawText(GetActor()->GetName());
00799 
00800   // Draw the name of the enemy's currently selected attack point
00801   if (current_battle->_cursor_state == CURSOR_SELECT_ATTACK_POINT) {
00802     std::vector<GlobalAttackPoint*>& attack_points = *(GetActor()->GetAttackPoints());
00803     VideoManager->MoveRelative(0, -25);
00804     ustring attack_point = MakeUnicodeString("(") + attack_points[current_battle->_selected_attack_point]->GetName() + MakeUnicodeString(")");
00805     VideoManager->DrawText(attack_point);
00806   }
00807 
00808   // TODO Draw the icons for any status afflictions that the enemy has
00809   //VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, VIDEO_BLEND, 0);
00810   //VideoManager->Move(818, 12);
00811 //  for (uint8 i = 0; i < _effects; i++) {
00812 //    VideoManager->DrawImage(_effects[i].image);
00813 //    VideoManager->MoveRel(25, 0);
00814 //  }
00815 }
00816 
00817 
00818 // Gives a specific amount of damage for the enemy
00819 /*void BattleEnemyActor::TakeDamage(uint32 damage)
00820 {
00821   _total_time_damaged = 1;
00822   _damage_dealt = damage;
00823   if (damage >= GetHitPoints()) // Was it a killing blow?
00824   {
00825     SetHitPoints(0);
00826     current_battle->RemoveScriptedEventsForActor(this);
00827   }
00828   else {
00829     SetHitPoints(GetHitPoints() - damage);
00830   }
00831 }*/
00832 
00833 
00834 } // namespace private_battle
00835 
00836 } // namespace hoa_battle

Generated on Fri Jul 6 23:11:10 2007 for Hero of Allacrost by  doxygen 1.5.1