1 /***************************************************************************
2                           map.c  -  description
3                              -------------------
4     begin                : Sat Jan 1 2000
5     copyright            : (C) 2000 by Perdig
6     email                : perdig@linuxbr.com.br
7 
8     $Id: map.c,v 1.8 2000/12/23 15:19:33 perdig Exp $
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19 #include "map.h"
20 #include "score.h"
21 #include "car.h"
22 #include "graphics.h"
23 #include "game.h"
24 #include "config.h"
25 
26 
27 
28 extern int actualFuel;
29 
30 
31 radarStruct radar;
32 
33 extern scoreStruct score;
34 extern levelStruct level;
35 extern int SPRITE_SIZE;
36 extern int TILE_WIDTH;
37 extern int TILE_HEIGHT;
38 
39 // Variable declaration
40 mapStruct *map;
41 
createMap(levelStruct * level,int mapNumber)42 int createMap(levelStruct *level, int mapNumber) {
43 	float facX, facY;
44 
45 
46 	if (mapNumber >= level->number) {
47 		hdbg("There isn't a map number %d in this file", mapNumber);
48 		return -1;
49 	}
50 
51 	map = &level->map[mapNumber];
52 
53 	ldbg("Map size:  %d", sizeof(mapStruct));
54 	ldbg("Data size: %d", sizeof(map->data));
55 
56 
57 	// Radar:
58   // It has a maximum width of 128 and height of 256
59 	// Check the factors
60 
61 	facX = RADAR_WIDTH / (float)toMap(map->width);
62 	facY = RADAR_HEIGHT / (float)toMap(map->height);
63 
64 	// The fuel should be enough to run 2/3 of the map
65 	if (map->startFuel < 0)
66 		map->startFuel = actualFuel = (toMap((map->width)*(map->height)) / STEP * 2) / 3;
67 	else
68 		map->startFuel = actualFuel = map->startFuel;
69 	ldbg("FacX: %f", facX);
70 	ldbg("FacY: %f", facY);
71 
72 	if (facX < facY)
73 		radar.factor = facX;
74 	else
75 		radar.factor = facY;
76 
77 	radar.width = (int)(radar.factor*toMap(1))*map->width;
78 	radar.height = (int)(radar.factor*toMap(1))*map->height;
79 
80 
81 	return 0;
82 
83 }
84 
toTile(int pos)85 int toTile(int pos) {
86 	pos+=(SPRITE_SIZE/2);
87 	pos -= (pos % SPRITE_SIZE);
88 	return (pos / SPRITE_SIZE);
89 }
90 
toMap(int tPos)91 int toMap(int tPos) {
92 	return (tPos * SPRITE_SIZE);
93 }
94 
update_offset(mapStruct * Map,carStruct * Car)95 void update_offset(mapStruct *Map, carStruct *Car) {
96 	int aX, aY;
97 	// Get the up-right corner
98 	aX = Car->x - MIDDLE_X;
99 	aY = Car->y - MIDDLE_Y;
100 	// OffX and Offy
101 	Map->offX = aX % SPRITE_SIZE;
102 	Map->offY = aY % SPRITE_SIZE;
103 	// tX and tY
104 	Map->tX = (aX - Map->offX) / SPRITE_SIZE;
105 	Map->tY = (aY - Map->offY) / SPRITE_SIZE;
106 }
107 
isClean(mapStruct * Map,carStruct * Car,int dir,int lookAhead)108 bool isClean(mapStruct *Map, carStruct *Car, int dir, int lookAhead) {
109 	int x, y;
110 	int tX, tY;
111 	x = Car->x;
112 	y = Car->y;
113 	moveXY(&x, &y, Car->direction, lookAhead);
114 	tX = x / SPRITE_SIZE;
115 	tY = y / SPRITE_SIZE;
116 	switch (dir) {
117 		case UP:
118 			if (y%SPRITE_SIZE != 0)
119 				return true; // Can go one more
120 			else {
121 				if (x%SPRITE_SIZE == 0)
122 					return passable(tX, tY-1);
123 				else
124 					return (passable(tX, tY-1) && passable(tX+1, tY-1));
125 			}
126 			break;
127 		case DOWN:
128 			if (y%SPRITE_SIZE != 0)
129 				return true; // Can go one more
130 			else {
131 				if (x%SPRITE_SIZE == 0)
132 					return passable(tX, tY+1);
133 				else
134 					return (passable(tX, tY+1) && passable(tX+1, tY+1));
135 			}
136 			break;
137 		case LEFT:
138 			if (x%SPRITE_SIZE != 0)
139 				return true; // Can go one more
140 			else {
141 				if (y%SPRITE_SIZE == 0)
142 					return passable(tX-1, tY);
143 				else
144 					return (passable(tX-1, tY) && passable(tX-1, tY+1));
145 			}
146 			break;
147 		case RIGHT:
148 			if (x%SPRITE_SIZE != 0)
149 				return true; // Can go one more
150 			else {
151 				if (y%SPRITE_SIZE == 0)
152 					return passable(tX+1, tY);
153 				else
154 					return (passable(tX+1, tY) && passable(tX+1, tY+1));
155 			}
156 			break;
157 	}
158 	return false;
159 }
160 
passable(int x,int y)161 bool passable(int x, int y) {
162 //	if (map->data[ (ty - 1) * map->width + tx ] == BLOCK || map->data[ (ty - 1) * map->width + tx ] >= 9)
163 	// Check for end of map
164 	if (x >= map->width || x < 0 || y >= map->height || y < 0)
165 		return false;
166 	return !(map->data[y*map->width+x] == BLOCK || map->data[y*map->width+x] >= 9);
167 }
168 	/* OLD isClean STUFF
169 	int tx, ty;
170 	ty = toTile(Car->y);
171 	tx = toTile(Car->x);
172 
173 	// If it is the opposite d, its ok to turn
174 	if (abs(dir - Car->direction) == 2)
175 		return true;
176 
177 	if (lookAhead) {
178 		switch (Car->direction) {
179 			case UP:
180 				ty -= lookAhead;
181 				break;
182 			case DOWN:
183 				ty += lookAhead;
184 				break;
185 			case RIGHT:
186 				tx += lookAhead;
187 				break;
188 			case LEFT:
189 				tx -= lookAhead;
190 				break;
191 		}
192 	}
193 	switch (dir) {
194 		// Custom impassable tiles: value >= 11
195 		case UP:
196 			// Check if end of map
197 			if (Car->y < Car->vel)
198 				return false;
199 			// Check if wall on top
200 			if (map->data[ (ty - 1) * map->width + tx ] == BLOCK || map->data[ (ty - 1) * map->width + tx ] >= 9)
201 				return false;
202 			break;
203 		case RIGHT:
204 			// Check if end of map
205 			if (Car->x > (toMap(map->width) - Car->vel - SPRITE_SIZE))
206 				return false;
207 			// Check if wall at right
208 			if (map->data[ (ty * map->width) + tx + 1 ] == BLOCK || map->data[ (ty * map->width) + tx + 1 ] >= 9)
209 				return false;
210 			break;
211 		case DOWN:
212 			// Check if end of map
213 			if (Car->y > (toMap(map->height) - Car->vel - SPRITE_SIZE))
214 				return false;
215 			// Check if wall at down
216 			if (map->data[ (ty + 1) * map->width + tx ] == BLOCK || map->data[ (ty + 1) * map->width + tx ] >= 9)
217 				return false;
218 			break;
219 		case LEFT:
220  			// Check if end of map
221 			if (Car->x < Car->vel)
222 				return false;
223 			// Check if wall at left
224 			if (map->data[ ty * map->width + tx - 1 ] == BLOCK || map->data[ ty * map->width + tx - 1 ] >= 9)
225 				return false;
226 			break;
227 	}
228 	return true;
229 	*/
230 
getFlag(int x,int y)231 void getFlag(int x, int y) {
232 	int a;
233 	map->data[(y * map->width) + x] = ROAD;
234 	map->flagLeft--;
235 	for (a = 0; a < map->flagNum; a++) {
236 		if (map->flagX[a] == x && map->flagY[a]	== y) {
237 			ldbg("Got flag %d", a);
238 			map->flagX[a] = -1;
239 			map->flagY[a] = -1;
240 		}
241 	}
242 	score.last += FLAG_VALUE;
243 	score.x = toMap(x);
244 	score.y = toMap(y);
245 	score.timer = SCORE_TIMER;
246 	add_score(&score, &level, score.last * score.bonus);
247 }
248 
initMap(mapStruct * map)249 void initMap(mapStruct *map) {
250 	map->width = -1;
251 	map->height = -1;
252 	map->startX = -1;
253 	map->startY = -1;
254 	map->red_startX = NULL;
255 	map->red_startY = NULL;
256 	map->redNum = -1;
257 	map->flagNum = -1;
258 	map->flagX = NULL;
259 	map->flagY = NULL;
260   map->data = NULL;
261 	map->startDir = -1;
262 	map->carVel = STEP;
263 	map->aiVel = STEP2;
264 	map->startFuel = -1;
265 	map->fuelImpact = 1;
266 	map->fuelpts = 5;
267 	map->radarmode = ORIGINAL;
268 	map->radarrange = 480;
269 	map->enemywait = 0;
270 }
271