added using separate constants for tiles in EM engine caves and game logic
[rocksndiamonds.git] / src / game_em / convert.c
1 /* 2007-04-04 08:33:37
2  *
3  * convert intermediate cave format to internal cave structure for
4  * use in logic(). initializes entire internal structure.
5  */
6
7 #include "main_em.h"
8
9
10 static const short map[CAVE_TILE_MAX] =
11 {
12   [Cblank]              = Xblank,
13   [Cgrass]              = Xgrass,
14   [Cdirt]               = Xdirt,
15   [Cplant]              = Xplant,
16   [Cwall_1]             = Xwall_1,
17   [Cwall_2]             = Xwall_2,
18   [Cwall_3]             = Xwall_3,
19   [Cwall_4]             = Xwall_4,
20   [Croundwall_1]        = Xroundwall_1,
21   [Croundwall_2]        = Xroundwall_2,
22   [Croundwall_3]        = Xroundwall_3,
23   [Croundwall_4]        = Xroundwall_4,
24   [Csteel_1]            = Xsteel_1,
25   [Csteel_2]            = Xsteel_2,
26   [Csteel_3]            = Xsteel_3,
27   [Csteel_4]            = Xsteel_4,
28   [Candroid]            = Xandroid,
29   [Ceater_n]            = Xeater_n,
30   [Ceater_e]            = Xeater_e,
31   [Ceater_s]            = Xeater_s,
32   [Ceater_w]            = Xeater_w,
33   [Calien]              = Xalien,
34   [Cbug_1_n]            = Xbug_1_n,
35   [Cbug_1_e]            = Xbug_1_e,
36   [Cbug_1_s]            = Xbug_1_s,
37   [Cbug_1_w]            = Xbug_1_w,
38   [Cbug_2_n]            = Xbug_2_n,
39   [Cbug_2_e]            = Xbug_2_e,
40   [Cbug_2_s]            = Xbug_2_s,
41   [Cbug_2_w]            = Xbug_2_w,
42   [Ctank_1_n]           = Xtank_1_n,
43   [Ctank_1_e]           = Xtank_1_e,
44   [Ctank_1_s]           = Xtank_1_s,
45   [Ctank_1_w]           = Xtank_1_w,
46   [Ctank_2_n]           = Xtank_2_n,
47   [Ctank_2_e]           = Xtank_2_e,
48   [Ctank_2_s]           = Xtank_2_s,
49   [Ctank_2_w]           = Xtank_2_w,
50   [Cemerald]            = Xemerald,
51   [Cdiamond]            = Xdiamond,
52   [Cstone]              = Xstone,
53   [Cbomb]               = Xbomb,
54   [Cnut]                = Xnut,
55   [Cspring]             = Xspring,
56   [Cpush_emerald_e]     = Xpush_emerald_e,
57   [Cpush_emerald_w]     = Xpush_emerald_w,
58   [Cpush_diamond_e]     = Xpush_diamond_e,
59   [Cpush_diamond_w]     = Xpush_diamond_w,
60   [Cpush_stone_e]       = Xpush_stone_e,
61   [Cpush_stone_w]       = Xpush_stone_w,
62   [Cpush_bomb_e]        = Xpush_bomb_e,
63   [Cpush_bomb_w]        = Xpush_bomb_w,
64   [Cpush_nut_e]         = Xpush_nut_e,
65   [Cpush_nut_w]         = Xpush_nut_w,
66   [Cpush_spring_e]      = Xpush_spring_e,
67   [Cpush_spring_w]      = Xpush_spring_w,
68   [Cdynamite]           = Xdynamite,
69   [Cdynamite_1]         = Xdynamite_1,
70   [Cdynamite_2]         = Xdynamite_2,
71   [Cdynamite_3]         = Xdynamite_3,
72   [Cdynamite_4]         = Xdynamite_4,
73   [Ckey_1]              = Xkey_1,
74   [Ckey_2]              = Xkey_2,
75   [Ckey_3]              = Xkey_3,
76   [Ckey_4]              = Xkey_4,
77   [Ckey_5]              = Xkey_5,
78   [Ckey_6]              = Xkey_6,
79   [Ckey_7]              = Xkey_7,
80   [Ckey_8]              = Xkey_8,
81   [Cdoor_1]             = Xdoor_1,
82   [Cdoor_2]             = Xdoor_2,
83   [Cdoor_3]             = Xdoor_3,
84   [Cdoor_4]             = Xdoor_4,
85   [Cdoor_5]             = Xdoor_5,
86   [Cdoor_6]             = Xdoor_6,
87   [Cdoor_7]             = Xdoor_7,
88   [Cdoor_8]             = Xdoor_8,
89   [Cfake_door_1]        = Xfake_door_1,
90   [Cfake_door_2]        = Xfake_door_2,
91   [Cfake_door_3]        = Xfake_door_3,
92   [Cfake_door_4]        = Xfake_door_4,
93   [Cfake_door_5]        = Xfake_door_5,
94   [Cfake_door_6]        = Xfake_door_6,
95   [Cfake_door_7]        = Xfake_door_7,
96   [Cfake_door_8]        = Xfake_door_8,
97   [Cballoon]            = Xballoon,
98   [Cball_1]             = Xball_1,
99   [Cball_2]             = Xball_2,
100   [Camoeba_1]           = Xamoeba_1,
101   [Camoeba_2]           = Xamoeba_2,
102   [Camoeba_3]           = Xamoeba_3,
103   [Camoeba_4]           = Xamoeba_4,
104   [Camoeba_5]           = Xamoeba_5,
105   [Camoeba_6]           = Xamoeba_6,
106   [Camoeba_7]           = Xamoeba_7,
107   [Camoeba_8]           = Xamoeba_8,
108   [Cdrip]               = Xdrip,
109   [Cwonderwall]         = Xwonderwall,
110   [Cwheel]              = Xwheel,
111   [Cswitch]             = Xswitch,
112   [Cbumper]             = Xbumper,
113   [Cacid_nw]            = Xacid_nw,
114   [Cacid_ne]            = Xacid_ne,
115   [Cacid_sw]            = Xacid_sw,
116   [Cacid_s]             = Xacid_s,
117   [Cacid_se]            = Xacid_se,
118   [Cacid_1]             = Xacid_1,
119   [Cacid_2]             = Xacid_2,
120   [Cacid_3]             = Xacid_3,
121   [Cacid_4]             = Xacid_4,
122   [Cacid_5]             = Xacid_5,
123   [Cacid_6]             = Xacid_6,
124   [Cacid_7]             = Xacid_7,
125   [Cacid_8]             = Xacid_8,
126   [Cfake_acid_1]        = Xfake_acid_1,
127   [Cfake_acid_2]        = Xfake_acid_2,
128   [Cfake_acid_3]        = Xfake_acid_3,
129   [Cfake_acid_4]        = Xfake_acid_4,
130   [Cfake_acid_5]        = Xfake_acid_5,
131   [Cfake_acid_6]        = Xfake_acid_6,
132   [Cfake_acid_7]        = Xfake_acid_7,
133   [Cfake_acid_8]        = Xfake_acid_8,
134   [Cfake_blank]         = Xfake_blank,
135   [Cfake_grass]         = Xfake_grass,
136   [Cfake_amoeba]        = Xfake_amoeba,
137   [Clenses]             = Xlenses,
138   [Cmagnify]            = Xmagnify,
139   [Csand]               = Xsand,
140   [Csand_stone]         = Xsand_stone,
141   [Cslide_ns]           = Xslide_ns,
142   [Cslide_ew]           = Xslide_ew,
143   [Cwind_n]             = Xwind_n,
144   [Cwind_e]             = Xwind_e,
145   [Cwind_s]             = Xwind_s,
146   [Cwind_w]             = Xwind_w,
147   [Cwind_any]           = Xwind_any,
148   [Cwind_stop]          = Xwind_stop,
149   [Cexit]               = Xexit,
150   [Cexit_1]             = Xexit_1,
151   [Cexit_2]             = Xexit_2,
152   [Cexit_3]             = Xexit_3,
153   [Cpause]              = Xpause,
154   [Cdecor_1]            = Xdecor_1,
155   [Cdecor_2]            = Xdecor_2,
156   [Cdecor_3]            = Xdecor_3,
157   [Cdecor_4]            = Xdecor_4,
158   [Cdecor_5]            = Xdecor_5,
159   [Cdecor_6]            = Xdecor_6,
160   [Cdecor_7]            = Xdecor_7,
161   [Cdecor_8]            = Xdecor_8,
162   [Cdecor_9]            = Xdecor_9,
163   [Cdecor_10]           = Xdecor_10,
164   [Cdecor_11]           = Xdecor_11,
165   [Cdecor_12]           = Xdecor_12,
166   [Calpha_0]            = Xalpha_0,
167   [Calpha_1]            = Xalpha_1,
168   [Calpha_2]            = Xalpha_2,
169   [Calpha_3]            = Xalpha_3,
170   [Calpha_4]            = Xalpha_4,
171   [Calpha_5]            = Xalpha_5,
172   [Calpha_6]            = Xalpha_6,
173   [Calpha_7]            = Xalpha_7,
174   [Calpha_8]            = Xalpha_8,
175   [Calpha_9]            = Xalpha_9,
176   [Calpha_excla]        = Xalpha_excla,
177   [Calpha_apost]        = Xalpha_apost,
178   [Calpha_comma]        = Xalpha_comma,
179   [Calpha_minus]        = Xalpha_minus,
180   [Calpha_perio]        = Xalpha_perio,
181   [Calpha_colon]        = Xalpha_colon,
182   [Calpha_quest]        = Xalpha_quest,
183   [Calpha_a]            = Xalpha_a,
184   [Calpha_b]            = Xalpha_b,
185   [Calpha_c]            = Xalpha_c,
186   [Calpha_d]            = Xalpha_d,
187   [Calpha_e]            = Xalpha_e,
188   [Calpha_f]            = Xalpha_f,
189   [Calpha_g]            = Xalpha_g,
190   [Calpha_h]            = Xalpha_h,
191   [Calpha_i]            = Xalpha_i,
192   [Calpha_j]            = Xalpha_j,
193   [Calpha_k]            = Xalpha_k,
194   [Calpha_l]            = Xalpha_l,
195   [Calpha_m]            = Xalpha_m,
196   [Calpha_n]            = Xalpha_n,
197   [Calpha_o]            = Xalpha_o,
198   [Calpha_p]            = Xalpha_p,
199   [Calpha_q]            = Xalpha_q,
200   [Calpha_r]            = Xalpha_r,
201   [Calpha_s]            = Xalpha_s,
202   [Calpha_t]            = Xalpha_t,
203   [Calpha_u]            = Xalpha_u,
204   [Calpha_v]            = Xalpha_v,
205   [Calpha_w]            = Xalpha_w,
206   [Calpha_x]            = Xalpha_x,
207   [Calpha_y]            = Xalpha_y,
208   [Calpha_z]            = Xalpha_z,
209   [Calpha_arrow_e]      = Xalpha_arrow_e,
210   [Calpha_arrow_w]      = Xalpha_arrow_w,
211   [Calpha_copyr]        = Xalpha_copyr
212 };
213
214 int map_em_element_C_to_X(int element_em_cave)
215 {
216   if (element_em_cave >= 0 && element_em_cave < CAVE_TILE_MAX)
217     return map[element_em_cave];
218
219   Error(ERR_WARN, "invalid EM cave element %d", element_em_cave);
220
221   return Xblank;
222 }
223
224 int map_em_element_X_to_C(int element_em_game)
225 {
226   static unsigned short map_reverse[TILE_MAX];
227   static boolean map_reverse_initialized = FALSE;
228
229   if (!map_reverse_initialized)
230   {
231     int i;
232
233     // return "Cblank" for all undefined elements in mapping array
234     for (i = 0; i < TILE_MAX; i++)
235       map_reverse[i] = Cblank;
236
237     for (i = 0; i < CAVE_TILE_MAX; i++)
238       map_reverse[map[i]] = i;
239
240     map_reverse_initialized = TRUE;
241   }
242
243   if (element_em_game >= 0 && element_em_game < TILE_MAX)
244   {
245     int element_em_cave = map_reverse[element_em_game];
246
247     if (element_em_cave == Cblank && element_em_game != Xblank)
248       Error(ERR_WARN, "unknown EM game element %d", element_em_game);
249
250     return element_em_cave;
251   }
252
253   Error(ERR_WARN, "invalid EM game element %d", element_em_game);
254
255   return Cblank;
256 }
257
258 void prepare_em_level(void)
259 {
260   int i, j, x, y;
261   int players_left;
262   boolean team_mode;
263
264   /* reset all runtime variables to their initial values */
265
266   game_init_cave_buffers();
267
268   lev.width  = cav.width;
269   lev.height = cav.height;
270
271   lev.left = CAVE_BUFFER_XOFFSET;
272   lev.top  = CAVE_BUFFER_YOFFSET;
273   lev.right = lev.left + lev.width;
274   lev.bottom = lev.top + lev.height;
275
276   /* add linked cave buffer columns for wrap-around movement */
277   for (x = 0; x < lev.left; x++)
278   {
279     lev.cavecol[x] = lev.cavecol[lev.width + x];
280     lev.nextcol[x] = lev.nextcol[lev.width + x];
281     lev.drawcol[x] = lev.drawcol[lev.width + x];
282     lev.boomcol[x] = lev.boomcol[lev.width + x];
283
284     lev.cavecol[lev.right + x] = lev.cavecol[lev.left + x];
285     lev.nextcol[lev.right + x] = lev.nextcol[lev.left + x];
286     lev.drawcol[lev.right + x] = lev.drawcol[lev.left + x];
287     lev.boomcol[lev.right + x] = lev.boomcol[lev.left + x];
288   }
289
290   for (x = 0; x < lev.width; x++)
291     for (y = 0; y < lev.height; y++)
292       lev.cave[lev.left + x][lev.top + y] = map[cav.cave[x][y]];
293
294   for (x = lev.left; x < lev.right; x++)
295     for (y = lev.top; y < lev.bottom; y++)
296       lev.next[x][y] = lev.draw[x][y] = lev.cave[x][y];
297
298   lev.time = cav.time_seconds;
299   lev.gems_needed = cav.gems_needed;
300   lev.score = 0;
301
302   lev.eater_score       = cav.eater_score;
303   lev.alien_score       = cav.alien_score;
304   lev.bug_score         = cav.bug_score;
305   lev.tank_score        = cav.tank_score;
306   lev.emerald_score     = cav.emerald_score;
307   lev.diamond_score     = cav.diamond_score;
308   lev.nut_score         = cav.nut_score;
309   lev.slurp_score       = cav.slurp_score;
310   lev.dynamite_score    = cav.dynamite_score;
311   lev.key_score         = cav.key_score;
312   lev.lenses_score      = cav.lenses_score;
313   lev.magnify_score     = cav.magnify_score;
314   lev.exit_score        = cav.exit_score;
315
316   lev.amoeba_time = cav.amoeba_time;
317
318   lev.android_move_time = cav.android_move_time;
319   lev.android_move_cnt  = cav.android_move_time;
320
321   lev.android_clone_time = cav.android_clone_time;
322   lev.android_clone_cnt  = cav.android_clone_time;
323
324   lev.ball_time   = cav.ball_time;
325   lev.ball_cnt    = cav.ball_time;
326   lev.ball_state  = cav.ball_state;
327   lev.ball_random = cav.ball_random;
328   lev.ball_pos    = 0;
329
330   lev.eater_pos = 0;
331   lev.shine_cnt = 0;
332
333   lev.lenses_time = cav.lenses_time;
334   lev.lenses_cnt  = cav.lenses_cnt;
335
336   lev.magnify_time = cav.magnify_time;
337   lev.magnify_cnt  = cav.magnify_cnt;
338
339   lev.wheel_time = cav.wheel_time;
340   lev.wheel_cnt  = cav.wheel_cnt;
341   lev.wheel_x    = cav.wheel_x;
342   lev.wheel_y    = cav.wheel_y;
343
344   lev.wind_time      = cav.wind_time;
345   lev.wind_cnt       = cav.wind_cnt;
346   lev.wind_direction = cav.wind_direction;
347
348   lev.wonderwall_time  = cav.wonderwall_time;
349   lev.wonderwall_state = cav.wonderwall_state;
350
351   lev.killed_out_of_time = FALSE;
352
353   lev.num_ball_arrays = cav.num_ball_arrays;
354
355   for (i = 0; i < 8; i++)
356     for (j = 0; j < 9; j++)
357       lev.eater_array[i][j] = map[cav.eater_array[i][j]];
358
359   for (i = 0; i < 8; i++)
360     for (j = 0; j < 8; j++)
361       lev.ball_array[i][j] = map[cav.ball_array[i][j]];
362
363   for (i = 0; i < TILE_MAX; i++)
364     lev.android_array[i] = map[cav.android_array[i]];
365
366   /* determine number of players in this level */
367   lev.home_initial = 0;
368
369   for (i = 0; i < MAX_PLAYERS; i++)
370   {
371     ply[i].exists = 0;
372     ply[i].alive_initial = FALSE;
373
374     if (cav.player_x[i] != -1 &&
375         cav.player_y[i] != -1)
376     {
377       ply[i].exists = 1;
378
379       lev.home_initial++;
380     }
381   }
382
383   team_mode = getTeamMode_EM();
384
385   if (!team_mode)
386     lev.home_initial = 1;
387
388   lev.home = lev.home_initial;
389   players_left = lev.home_initial;
390
391   for (i = 0; i < MAX_PLAYERS; i++)
392   {
393     if (ply[i].exists)
394     {
395       if (players_left)
396       {
397         ply[i].alive_initial = TRUE;
398         players_left--;
399       }
400       else
401       {
402         int x = cav.player_x[i];
403         int y = cav.player_y[i];
404
405         lev.cave[lev.left + x][lev.top + y] = Xblank;
406         lev.next[lev.left + x][lev.top + y] = Xblank;
407         lev.draw[lev.left + x][lev.top + y] = Xblank;
408       }
409     }
410   }
411
412   for (i = 0; i < MAX_PLAYERS; i++)
413   {
414     ply[i].num = i;
415     ply[i].alive = ply[i].alive_initial;
416     ply[i].dynamite = 0;
417     ply[i].dynamite_cnt = 0;
418     ply[i].keys = 0;
419     ply[i].anim = 0;
420     ply[i].oldx = ply[i].x = cav.player_x[i] + lev.left;
421     ply[i].oldy = ply[i].y = cav.player_y[i] + lev.top;
422     ply[i].last_move_dir = MV_NONE;
423     ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
424     ply[i].joy_snap  = ply[i].joy_drop = 0;
425     ply[i].joy_stick = ply[i].joy_spin = 0;
426   }
427
428   // the following engine variables are initialized to version-specific values
429   // in function InitGameEngine() (src/game.c):
430   //
431   // - game_em.use_single_button (default: TRUE)
432   // - game_em.use_snap_key_bug (default: FALSE)
433   // - game_em.use_old_explosions (default: FALSE)
434
435   game_em.level_solved = FALSE;
436   game_em.game_over = FALSE;
437
438   game_em.any_player_moving = FALSE;
439   game_em.any_player_snapping = FALSE;
440
441   game_em.last_moving_player = 0;       /* default: first player */
442
443   for (i = 0; i < MAX_PLAYERS; i++)
444     game_em.last_player_direction[i] = MV_NONE;
445
446   lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */
447 }