1 /*
2 Solar Conquest
3 Copyright (C) 2006 Greg Beaman
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 #define MAP_SIZE 1000
21 #define TILE_SIZE 10
22 
23 //Node for object list
24 class CObjectListNode
25 {
26 public:
27 	void* obj;
28 	CObjectListNode* prevNode;
29 	CObjectListNode* nextNode;
30 
31 	CObjectListNode(void* store);
32 	~CObjectListNode();
33 };
34 
CObjectListNode(void * store)35 CObjectListNode::CObjectListNode(void* store) { obj = store; prevNode = NULL; nextNode = NULL; }
~CObjectListNode()36 CObjectListNode::~CObjectListNode() {}
37 
38 //Class to hold a list of objects
39 class CObjectList
40 {
41 public:
42 	CObjectListNode* firstNode;
43 
44 	CObjectList();
45 	~CObjectList();
46 
47 	CObjectListNode* AddNode(void* obj);
48 	CObjectListNode* GetNode(void* obj);
49 	void DeleteNode(CObjectListNode* node);
50 	void ClearAll();
51 };
52 
CObjectList()53 CObjectList::CObjectList() { firstNode = NULL; }
~CObjectList()54 CObjectList::~CObjectList() { ClearAll(); }
55 
AddNode(void * obj)56 CObjectListNode* CObjectList::AddNode(void* obj)
57 {
58 	if (obj == NULL)
59 		return NULL;
60 
61 	CObjectListNode* newNode;
62 	newNode = new CObjectListNode(obj);
63 	if (!newNode)
64 		return NULL;
65 	newNode->nextNode = firstNode;
66 	if (firstNode)
67 		firstNode->prevNode = newNode;
68 	firstNode = newNode;
69 	return newNode;
70 }
71 
GetNode(void * obj)72 CObjectListNode* CObjectList::GetNode(void* obj)
73 {
74 	CObjectListNode* cNode = firstNode;
75 	while (cNode)
76 	{
77 		if (cNode->obj == obj)
78 			return cNode;
79 		cNode = cNode->nextNode;
80 	}
81 	return NULL;
82 }
83 
DeleteNode(CObjectListNode * node)84 void CObjectList::DeleteNode(CObjectListNode* node)
85 {
86 	if (!node)
87 		return;
88 
89 	if (node->prevNode)
90 		node->prevNode->nextNode = node->nextNode;
91 	else
92 		firstNode = node->nextNode;
93 	if (node->nextNode)
94 		node->nextNode->prevNode = node->prevNode;
95 	delete node;
96 }
97 
ClearAll()98 void CObjectList::ClearAll()
99 {
100 	CObjectListNode* cNode = firstNode;
101 	CObjectListNode* tNode;
102 	while (cNode)
103 	{
104 		tNode = cNode->nextNode;
105 		delete cNode;
106 		cNode = tNode;
107 	}
108 	firstNode = NULL;
109 }
110 
111 //Data for tile
112 struct TileData
113 {
114 	CObjectList* list;
115 };
116 
117 class CMap
118 {
119 protected:
120 	TileData Tiles[MAP_SIZE][MAP_SIZE];
121 
122 public:
123 	CMap();
124 	~CMap();
125 
126 	bool ValidTile(int x, int y);
127 
128 	void ResetMap();
129 
130 	void AddObject(float x, float y, int radius, void* obj);
131 	void DeleteObject(float x, float y, int radius, void* obj);
132 
133 	CObjectList* GetObjectList(int x, int y);
134 	CObjectList* GetObjectList(float x, float y);
135 };
136 
CMap()137 CMap::CMap()
138 {
139 	for (int x=0; x < MAP_SIZE; x++)
140 		for (int y=0; y < MAP_SIZE; y++)
141 		{
142 			Tiles[x][y].list = new CObjectList();
143 			if (!Tiles[x][y].list)
144 				DebugMessage(1,"Could not create object list for tile");
145 		}
146 }
147 
~CMap()148 CMap::~CMap()
149 {
150 	for (int x=0; x < MAP_SIZE; x++)
151 		for (int y=0; y < MAP_SIZE; y++)
152 		{
153 			delete Tiles[x][y].list;
154 			Tiles[x][y].list = NULL;
155 		}
156 }
157 
ResetMap()158 void CMap::ResetMap()
159 {
160 	for (int x=0; x < MAP_SIZE; x++)
161 		for (int y=0; y < MAP_SIZE; y++)
162 			if (Tiles[x][y].list)
163 				Tiles[x][y].list->ClearAll();
164 }
165 
ValidTile(int x,int y)166 bool CMap::ValidTile(int x, int y)
167 {
168 	if (x < 0 || x >= MAP_SIZE)
169 		return false;
170 	if (y < 0 || y >= MAP_SIZE)
171 		return false;
172 	return true;
173 }
174 
AddObject(float x,float y,int radius,void * obj)175 void CMap::AddObject(float x, float y, int radius, void* obj)
176 {
177 	int sx,sy;
178 	sx = (int)(x / TILE_SIZE);
179 	sy = (int)(y / TILE_SIZE);
180 
181 	for (int tx = sx-radius; tx <= sx+radius; tx++)
182 	{
183 		for (int ty = sy-radius; ty <= sy+radius; ty++)
184 		{
185 			if (ValidTile(tx,ty))
186 				if (Tiles[tx][ty].list)
187 					Tiles[tx][ty].list->AddNode(obj);
188 		}
189 	}
190 }
191 
DeleteObject(float x,float y,int radius,void * obj)192 void CMap::DeleteObject(float x, float y, int radius, void* obj)
193 {
194 	int sx,sy;
195 	sx = (int)(x / TILE_SIZE);
196 	sy = (int)(y / TILE_SIZE);
197 
198 	for (int tx = sx-radius; tx <= sx+radius; tx++)
199 	{
200 		for (int ty = sy-radius; ty <= sy+radius; ty++)
201 		{
202 			if (ValidTile(tx,ty))
203 				if (Tiles[tx][ty].list)
204 					Tiles[tx][ty].list->DeleteNode(Tiles[tx][ty].list->GetNode(obj));
205 		}
206 	}
207 }
208 
GetObjectList(int x,int y)209 CObjectList* CMap::GetObjectList(int x, int y)
210 {
211 	if (ValidTile(x,y))
212 		return Tiles[x][y].list;
213 	return NULL;
214 }
215 
GetObjectList(float x,float y)216 CObjectList* CMap::GetObjectList(float x, float y)
217 {
218 	int sx,sy;
219 	sx = (int)(x / TILE_SIZE);
220 	sy = (int)(y / TILE_SIZE);
221 
222 	if (ValidTile(sx,sy))
223 		return Tiles[sx][sy].list;
224 	return NULL;
225 }
226 
227 CMap* g_Map = NULL;
228