fix regression: enemy soldiers fired in wrong direction
[rofl0r-openDOW.git] / enemytag.c
blob19cb3e23f87d6aad3fd190a861935246ad5e3d1a
1 #include "enemy.h"
2 #include "gameobj.h"
3 #include "video.h"
4 #include <unistd.h>
5 static struct enemy_spawn tag_enemy;
6 static int tag_enemy_current_route;
7 static int tag_enemy_current_shot;
8 static int tag_enemy_id;
9 static int tag_enemy_spawnline;
10 static int tag_enemy_y;
11 static int tag_enemy_upscrolled;
13 static void scrollup() {
14 tag_enemy_upscrolled += 10;
15 objs[player_ids[0]].pos.y -= 10*SCALE;
18 #define STRING_ENTRY(x) [x] = #x
19 static const char* enemy_weapon_string_lut[] = {
20 STRING_ENTRY(EW_GUN),
21 STRING_ENTRY(EW_GRENADE),
23 static const char* enemy_shape_string_lut[] = {
24 STRING_ENTRY(ES_SOLDIER1_DOWN),
25 STRING_ENTRY(ES_SOLDIER1_LEFT),
26 STRING_ENTRY(ES_SOLDIER1_RIGHT),
27 STRING_ENTRY(ES_SOLDIER2_DOWN),
28 STRING_ENTRY(ES_SOLDIER2_LEFT),
29 STRING_ENTRY(ES_SOLDIER2_RIGHT),
30 STRING_ENTRY(ES_GUNTURRET_MOVABLE_MAN),
31 STRING_ENTRY(ES_GUNTURRET_MOVABLE_MACHINE),
32 STRING_ENTRY(ES_JEEP),
33 STRING_ENTRY(ES_TANK_SMALL),
34 STRING_ENTRY(ES_TANK_BIG),
35 STRING_ENTRY(ES_TRANSPORTER),
36 STRING_ENTRY(ES_BUNKER_1),
37 STRING_ENTRY(ES_BUNKER_2),
38 STRING_ENTRY(ES_BUNKER_3),
39 STRING_ENTRY(ES_BUNKER_4),
40 STRING_ENTRY(ES_BUNKER_5),
41 STRING_ENTRY(ES_MINE_FLAT),
42 STRING_ENTRY(ES_MINE_CROSS),
43 STRING_ENTRY(ES_FLAMETURRET),
44 STRING_ENTRY(ES_GUNTURRET_FIXED_SOUTH),
45 STRING_ENTRY(ES_GUNTURRET_FIXED_NORTH),
46 STRING_ENTRY(ES_BOSS),
47 STRING_ENTRY(ES_MAX),
49 static const char* dir16_string_lut[] = {
50 STRING_ENTRY(DIR16_N),
51 STRING_ENTRY(DIR16_NNW),
52 STRING_ENTRY(DIR16_NW),
53 STRING_ENTRY(DIR16_WNW),
54 STRING_ENTRY(DIR16_W),
55 STRING_ENTRY(DIR16_WSW),
56 STRING_ENTRY(DIR16_SW),
57 STRING_ENTRY(DIR16_SSW),
58 STRING_ENTRY(DIR16_S),
59 STRING_ENTRY(DIR16_SSO),
60 STRING_ENTRY(DIR16_SO),
61 STRING_ENTRY(DIR16_OSO),
62 STRING_ENTRY(DIR16_O),
63 STRING_ENTRY(DIR16_ONO),
64 STRING_ENTRY(DIR16_NO),
65 STRING_ENTRY(DIR16_NNO),
66 STRING_ENTRY(DIR16_MAX),
68 static void dump_enemy() {
70 .scroll_line = 1,
71 .weapon = EW_GUN,
72 .x = 100,
73 .y = 100,
74 .route = {
75 [3] = {
76 .shape = ES_JEEP,
77 .dir = DIR16_WNW,
78 .start_step = 0,
79 .vel = 2,
81 [4] = {
82 .shape = ES_SOLDIER1_RIGHT,
83 .dir = DIR16_NNW,
84 .start_step = 128,
85 .vel = 2,
90 #define tprintf(tabs, args...) do { int __tabs; for(__tabs = 0; __tabs < tabs; __tabs++) printf("\t"); printf(args); } while(0)
91 printf("XXX screen %d\n", map_spawn_screen_index);
92 tprintf(2, ".scroll_line = %d,\n", tag_enemy_spawnline);
93 tprintf(2, ".weapon = %s,\n", enemy_weapon_string_lut[tag_enemy.weapon]);
94 tprintf(2, ".x = %d,\n", tag_enemy.x);
95 tprintf(2, ".y = %d,\n", tag_enemy_y);
96 tprintf(2, ".route = {\n");
97 int i;
98 for(i = 0; i < ENEMY_MAX_ROUTE && tag_enemy.route[i].shape != ES_INVALID; i++) {
99 tprintf(3, "[%d] = {\n", i);
100 tprintf(4, ".shape = %s,\n", enemy_shape_string_lut[tag_enemy.route[i].shape]);
101 tprintf(4, ".dir = %s,\n", dir16_string_lut[tag_enemy.route[i].dir]);
102 tprintf(4, ".start_step = %d,\n", tag_enemy.route[i].start_step);
103 tprintf(4, ".vel = %d,\n", tag_enemy.route[i].vel);
104 tprintf(3, "},\n");
106 tprintf(2, "},\n");
107 tprintf(2, ".shots = {\n");
108 for(i = 0; i < ENEMY_MAX_SHOT; i++)
109 tprintf(3, "[%d] = %d,\n", i, tag_enemy.shots[i]);
110 tprintf(2, "},\n");
113 static void reset_tag_enemy() {
114 memset(&tag_enemy, 0, sizeof(tag_enemy));
115 tag_enemy.route[0].shape = ES_SOLDIER1_DOWN;
118 static void update_tag_enemy(int doremove) {
119 if(doremove) remove_enemy(tag_enemy_id);
120 tag_enemy.y = tag_enemy_y + tag_enemy_upscrolled;
121 tag_enemy_id = init_enemy(&tag_enemy);
124 static void toggle_shape(int shapedir) {
125 int s = tag_enemy.route[tag_enemy_current_route].shape;
126 s += shapedir;
127 if(s < ES_FIRST) s = ES_MAX - 1;
128 else if(s >= ES_MAX) s = ES_FIRST;
129 tag_enemy.route[tag_enemy_current_route].shape = s;
132 static void toggle_vel(int veldir) {
133 int v = tag_enemy.route[tag_enemy_current_route].vel;
134 v+=veldir;
135 if(v<0) v = 0;
136 else if(v > 255) v = 255;
137 int i;
138 for(i = tag_enemy_current_route; i < ENEMY_MAX_ROUTE; i++)
139 tag_enemy.route[i].vel = v;
140 update_tag_enemy(1);
143 static void toggle_route(int dir) {
144 enum enemy_shape currshape = tag_enemy.route[tag_enemy_current_route].shape;
145 int newroute = tag_enemy_current_route + dir;
146 if(newroute >= ENEMY_MAX_ROUTE) newroute = 0;
147 else if(newroute < 0) newroute = ENEMY_MAX_ROUTE -1;
148 tag_enemy_current_route = newroute;
149 if(tag_enemy.route[tag_enemy_current_route].shape == ES_INVALID)
150 tag_enemy.route[tag_enemy_current_route].shape = currshape;
153 static void toggle_shot(int dir) {
154 int newshot = tag_enemy_current_shot + dir;
155 if(newshot >= ENEMY_MAX_SHOT) newshot = 0;
156 else if(newshot < 0) newshot = ENEMY_MAX_SHOT -1;
157 tag_enemy_current_shot = newshot;
160 static void toggle_gun(void) {
161 if(tag_enemy.weapon == EW_GRENADE) tag_enemy.weapon = EW_GUN;
162 else tag_enemy.weapon = EW_GRENADE;
165 static void insert_steps(void) {
166 tag_enemy.route[tag_enemy_current_route].start_step = objs[tag_enemy_id].objspecific.enemy.curr_step;
169 static void insert_shot(void) {
170 tag_enemy.shots[tag_enemy_current_shot] = objs[tag_enemy_id].objspecific.enemy.curr_step;
173 static int paused;
174 static void tag_update_caption(void) {
175 char buf [128];
176 snprintf(buf, 128, "%s tag mode: x %d, y %d, route: %d, vel: %d, step: %d, shot: %d",
177 paused ? "XXXX PAUSED XXXX" : "",
178 (int) tag_enemy.x, (int) tag_enemy.y,
179 (int) tag_enemy_current_route,
180 (int) tag_enemy.route[tag_enemy_current_route].vel,
181 (int) objs[tag_enemy_id].objspecific.enemy.curr_step,
182 (int) tag_enemy_current_shot
184 SDL_WM_SetCaption(buf, 0);
187 static void print_dirbuf(char* dirbuf) {
188 char buf [128];
189 snprintf(buf, 128, "enter dir16: %s", dirbuf);
190 SDL_WM_SetCaption(buf, 0);
193 static void do_pause() {
194 static int save_vel[ENEMY_MAX_ROUTE];
195 int i;
196 if(!paused) {
197 for(i = 0; i < ENEMY_MAX_ROUTE; i++) save_vel[i] = tag_enemy.route[i].vel;
198 for(i = 0; i < ENEMY_MAX_ROUTE; i++) tag_enemy.route[i].vel = 0;
199 } else {
200 for(i = 0; i < ENEMY_MAX_ROUTE; i++) tag_enemy.route[i].vel = save_vel[i];
202 paused = !paused;
205 static void enter_direction() {
206 char dirbuf[4] = {0};
207 char* p = dirbuf;
208 while(1) {
209 SDL_Event sdl_event;
210 while (SDL_PollEvent(&sdl_event)) {
211 if(sdl_event.type == SDL_KEYUP) switch(sdl_event.key.keysym.sym) {
212 #define check(dir) if(p+dir < dirbuf || p+dir>=dirbuf+4) break;
213 case SDLK_w: check(1); *p++ = 'w'; break;
214 case SDLK_s: check(1); *p++ = 's'; break;
215 case SDLK_o: check(1); *p++ = 'o'; break;
216 case SDLK_n: check(1); *p++ = 'n'; break;
217 case SDLK_BACKSPACE: check(-1); *--p = 0; break;
218 #undef check
219 case SDLK_RETURN: goto end_loop;
220 default: ;
222 print_dirbuf(dirbuf);
224 print_dirbuf(dirbuf);
225 SDL_Delay(5);
227 end_loop:;
228 enum direction16 dir;
229 if(0);
230 else if (!strcmp(dirbuf,"o")) dir= DIR16_O;
231 else if (!strcmp(dirbuf,"ono")) dir= DIR16_ONO;
232 else if (!strcmp(dirbuf,"no")) dir= DIR16_NO;
233 else if (!strcmp(dirbuf,"nno")) dir= DIR16_NNO;
234 else if (!strcmp(dirbuf,"n")) dir= DIR16_N;
235 else if (!strcmp(dirbuf,"nnw")) dir= DIR16_NNW;
236 else if (!strcmp(dirbuf,"nw")) dir= DIR16_NW;
237 else if (!strcmp(dirbuf,"wnw")) dir= DIR16_WNW;
238 else if (!strcmp(dirbuf,"w")) dir= DIR16_W;
239 else if (!strcmp(dirbuf,"wsw")) dir= DIR16_WSW;
240 else if (!strcmp(dirbuf,"sw")) dir= DIR16_SW;
241 else if (!strcmp(dirbuf,"ssw")) dir= DIR16_SSW;
242 else if (!strcmp(dirbuf,"s")) dir= DIR16_S;
243 else if (!strcmp(dirbuf,"sso")) dir= DIR16_SSO;
244 else if (!strcmp(dirbuf,"so")) dir= DIR16_SO;
245 else if (!strcmp(dirbuf,"oso")) dir= DIR16_OSO;
246 else dir = DIR16_INVALID;
247 if(dir != DIR16_INVALID) tag_enemy.route[tag_enemy_current_route].dir = dir;
248 update_tag_enemy(1);
251 static void enemy_tag_loop() {
252 update_caption = tag_update_caption;
253 tag_enemy_current_route = 0;
254 tag_enemy_current_shot = 0;
255 tag_enemy_spawnline = map_spawn_line;
256 tag_enemy_y = 0;
257 tag_enemy_upscrolled = 0;
258 reset_tag_enemy();
259 tag_enemy_id = init_enemy(&tag_enemy);
261 SDL_Event sdl_event;
262 while(1) {
263 if(!obj_slot_used[tag_enemy_id]) update_tag_enemy(0);
264 //tag_enemy_id = init_enemy(&tag_enemy);
265 unsigned need_redraw = 1;
266 while (SDL_PollEvent(&sdl_event)) {
267 need_redraw = 0;
268 int dir = -1;
269 switch (sdl_event.type) {
270 case SDL_KEYUP:
271 switch(sdl_event.key.keysym.sym) {
272 case SDLK_e: dump_enemy(); return;
273 case SDLK_g: toggle_gun(); break;
274 case SDLK_d: enter_direction(); break;
275 case SDLK_i: insert_steps(); break;
276 case SDLK_s: insert_shot(); break;
277 case SDLK_p: do_pause(); break;
278 case SDLK_c: clear_screen(); video_update(); need_redraw = 1; break;
279 case SDLK_SPACE: update_tag_enemy(1); break;
280 case SDLK_PAGEUP: scrollup(); break;
281 case SDLK_KP_PLUS:
282 dir = 1;
283 case SDLK_KP_MINUS:
284 if((sdl_event.key.keysym.mod & KMOD_RSHIFT) ||
285 (sdl_event.key.keysym.mod & KMOD_LSHIFT))
286 toggle_shape(dir);
287 else
288 if((sdl_event.key.keysym.mod & KMOD_RALT) ||
289 (sdl_event.key.keysym.mod & KMOD_LALT))
290 toggle_route(dir);
291 else
292 if((sdl_event.key.keysym.mod & KMOD_RCTRL) ||
293 (sdl_event.key.keysym.mod & KMOD_LCTRL))
294 toggle_shot(dir);
295 else
296 toggle_vel(dir);
297 break;
298 default: break;
300 case SDL_KEYDOWN:
301 switch(sdl_event.key.keysym.sym) {
302 case SDLK_RIGHT: dir = 1;
303 case SDLK_LEFT:
304 if((sdl_event.key.keysym.mod & KMOD_RSHIFT) ||
305 (sdl_event.key.keysym.mod & KMOD_LSHIFT)) dir *= 4;
306 tag_enemy.x += dir;
307 update_tag_enemy(1);
308 break;
309 case SDLK_DOWN:
310 dir = 1;
311 case SDLK_UP:
312 if((sdl_event.key.keysym.mod & KMOD_RSHIFT) ||
313 (sdl_event.key.keysym.mod & KMOD_LSHIFT)) dir *= 4;
314 tag_enemy_y += dir;
315 update_tag_enemy(1);
316 break;
317 default: ;
319 break;
320 default: ;
323 game_tick(need_redraw);