00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00034
00035
00036
00037
00038
00039 #include <string.h>
00040
00041 #include "stratagus.h"
00042 #include "unit_cache.h"
00043 #include "unit.h"
00044 #include "unittype.h"
00045
00046
00047 CUnitCache UnitCache;
00048
00049
00056 void CUnitCache::Init(int mapWidth, int mapHeight)
00057 {
00058 width = mapWidth;
00059 height = mapHeight;
00060
00061 cache.clear();
00062 cache.resize(width);
00063 for (int i = 0; i < width; ++i) {
00064 cache[i].resize(height);
00065 }
00066 }
00067
00073 void CUnitCache::Insert(CUnit *unit)
00074 {
00075 Assert(!unit->Removed);
00076
00077 for (int i = 0; i < unit->Type->TileWidth; ++i) {
00078 for (int j = 0; j < unit->Type->TileHeight; ++j) {
00079 cache[unit->X + i][unit->Y + j].push_back(unit);
00080 }
00081 }
00082 }
00083
00089 void CUnitCache::Remove(CUnit *unit)
00090 {
00091 Assert(!unit->Removed);
00092
00093 for (int i = 0; i < unit->Type->TileWidth; ++i) {
00094 for (int j = 0; j < unit->Type->TileHeight; ++j) {
00095 for (std::vector<CUnit *>::iterator k = cache[unit->X + i][unit->Y + j].begin();
00096 k != cache[unit->X + i][unit->Y + j].end(); ++k) {
00097 if (*k == unit) {
00098 cache[unit->X + i][unit->Y + j].erase(k);
00099 break;
00100 }
00101 }
00102 }
00103 }
00104 }
00105
00118 int CUnitCache::Select(int x1, int y1, int x2, int y2, CUnit **table, int tablesize)
00119 {
00120 int i;
00121 int j;
00122 int n;
00123 CUnit *unit;
00124 bool unitAdded[UnitMax];
00125
00126
00127 if (x1 >= x2 - 1 && y1 >= y2 - 1) {
00128 return UnitCache.Select(x1, y1, table, tablesize);
00129 }
00130
00131
00132
00133
00134 x1 = std::max(x1, 0);
00135 y1 = std::max(y1, 0);
00136 x2 = std::min(x2, width - 1);
00137 y2 = std::min(y2, height - 1);
00138
00139 memset(unitAdded, 0, sizeof(unitAdded));
00140 n = 0;
00141
00142 for (i = x1; i <= x2 && n < tablesize; ++i) {
00143 for (j = y1; j <= y2 && n < tablesize; ++j) {
00144 for (size_t k = 0, end = cache[i][j].size(); k < end && n < tablesize; ++k) {
00145
00146
00147
00148
00149
00150 unit = cache[i][j][k];
00151 if (!unitAdded[unit->Slot] && !unit->Type->Revealer) {
00152 Assert(!unit->Removed);
00153 unitAdded[unit->Slot] = true;
00154 table[n++] = unit;
00155 }
00156 }
00157 }
00158 }
00159
00160 return n;
00161 }
00162
00173 int CUnitCache::Select(int x, int y, CUnit **table, int tablesize)
00174 {
00175
00176
00177
00178
00179 int n = 0;
00180 std::vector<CUnit *>::iterator i, end;
00181
00182 for (i = cache[x][y].begin(), end = cache[x][y].end(); i != end && n < tablesize; ++i) {
00183 Assert(!(*i)->Removed);
00184 table[n++] = *i;
00185 }
00186
00187 return n;
00188 }
00189