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