map_zones.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
00006 // and 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 
00016 #include "system.h"
00017 
00018 #include "map_zones.h"
00019 #include "map_objects.h"
00020 #include "map_sprites.h"
00021 
00022 extern bool MAP_DEBUG;
00023 
00024 using namespace std;
00025 
00026 using namespace hoa_utils;
00027 
00028 namespace hoa_map {
00029 
00030 namespace private_map {
00031 
00032 // *****************************************************************************
00033 // ************************* MapZone Class Functions ***************************
00034 // *****************************************************************************
00035 
00036 void MapZone::AddSection(ZoneSection* section) {
00037   _sections.push_back(*section);
00038   delete section;
00039 }
00040 
00041 
00042 
00043 bool MapZone::IsInsideZone(uint16 pos_x, uint16 pos_y) {
00044   // Verify each section of the zone to make sure the position is in bounds.
00045   for (std::vector<ZoneSection>::const_iterator i = _sections.begin(); i != _sections.end(); ++i) {
00046     if (pos_x >= i->start_col && pos_x <= i->end_col &&
00047       pos_y >= i->start_row && pos_y <= i->end_row )
00048     {
00049       return true;
00050     }
00051   }
00052   return false;
00053 }
00054 
00055 
00056 
00057 void MapZone::_RandomPosition(uint16& x, uint16& y) {
00058   // Select a ZoneSection randomly
00059   uint16 i = RandomBoundedInteger(0, _sections.size() - 1);
00060 
00061   // Select a position inside that section
00062   x = RandomBoundedInteger(_sections[i].start_col, _sections[i].end_col);
00063   y = RandomBoundedInteger(_sections[i].start_row, _sections[i].end_row);
00064 }
00065 
00066 // *****************************************************************************
00067 // *********************** EnemyZone Class Functions *************************
00068 // *****************************************************************************
00069 
00070 EnemyZone::EnemyZone(uint32 regen_time, bool restrained) :
00071   _regen_time(regen_time),
00072   _spawn_timer(0),
00073   _active_enemies(0),
00074   _restrained(restrained)
00075 {}
00076 
00077 
00078 
00079 void EnemyZone::AddEnemy(EnemySprite* enemy, MapMode* map, uint8 count) {
00080   if (count == 0) {
00081     // NOTE: The EnemySprite pointer passed in is not deleted in this case
00082     if (MAP_DEBUG)
00083       cerr << "MAP WARNING: EnemyZone::AddEnemy called with a zero count for the enemy" << endl;
00084     return;
00085   }
00086 
00087   // Prepare the first enemy
00088   enemy->SetZone(this);
00089   map->_AddGroundObject(enemy);
00090   _enemies.push_back(enemy);
00091 
00092   // Create any additional copies of the enemy and add them as well
00093   uint8 remaining = count - 1;
00094   while (remaining > 0) {
00095     EnemySprite* copy = new EnemySprite(*enemy);
00096     copy->SetObjectID(map->_GetGeneratedObjectID() );
00097     //Add a 10% random margin of error to make enemies look less sync'ed
00098     copy->SetTimeToChange( (uint32)(copy->GetTimeToChange() * ( 1 + RandomFloat()*10 ) ) );
00099     copy->Reset();
00100     map->_AddGroundObject(copy);
00101     _enemies.push_back(copy);
00102     remaining--;
00103   }
00104 }
00105 
00106 
00107 
00108 void EnemyZone::EnemyDead() {
00109   --_active_enemies;
00110 }
00111 
00112 
00113 
00114 void EnemyZone::Update() {
00115   // Spawn new enemies only if there is at least one enemy that is not active
00116   if (_active_enemies == _enemies.size()) {
00117     return;
00118   }
00119 
00120   // Return if the regenenration time has not been reached, return
00121   _spawn_timer += hoa_system::SystemManager->GetUpdateTime();
00122   if (_spawn_timer < _regen_time) {
00123     return;
00124   }
00125 
00126   // Otherwise, select a DEAD enemy to spawn
00127   uint32 index = 0;
00128   for (uint32 i = 0; i < _enemies.size(); i++) {
00129     if (_enemies[i]->IsDead() == true) {
00130       index = i;
00131       break;
00132     }
00133   }
00134 
00135   // Used to retain random position coordinates in the zone
00136   uint16 x, y;
00137   // Number of times to try to place the enemy in the zone (arbitrarly set to 5 tries)
00138   int8 retries = 5;
00139   // Holds the result of a collision detection check
00140   bool collision;
00141 
00142   // Select a random position inside the zone to place the spawning enemy, and make sure that there is no collision
00143   _enemies[index]->no_collision = false;
00144   do {
00145     _RandomPosition(x, y);
00146     _enemies[index]->SetXPosition(x, 0.0f);
00147     _enemies[index]->SetYPosition(y, 0.0f);
00148     collision = MapMode::_current_map->_DetectCollision(_enemies[index]);
00149   } while (collision && --retries > 0);
00150 
00151   // If there is still a collision, reset the collision info on the enemy and retry on the next frame update
00152   if (collision) {
00153     _enemies[index]->no_collision = true;
00154     return;
00155   }
00156 
00157   // Otherwise, spawn the enemy and reset the spawn timer
00158   _spawn_timer = 0;
00159   _enemies[index]->ChangeStateSpawning();
00160   _active_enemies++;
00161 } // void EnemyZone::Update()
00162 
00163 } // namespace private_map
00164 
00165 } // namespace hoa_map

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