changed handling of chain explosions in EM engine
[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 void prepare_em_level(void)
11 {
12   int i, j, x, y;
13   int players_left;
14   boolean team_mode;
15
16   /* reset all runtime variables to their initial values */
17
18   game_init_cave_buffers();
19
20   lev.width  = cav.width;
21   lev.height = cav.height;
22
23   lev.left = CAVE_BUFFER_XOFFSET;
24   lev.top  = CAVE_BUFFER_YOFFSET;
25   lev.right = lev.left + lev.width;
26   lev.bottom = lev.top + lev.height;
27
28   /* add linked cave buffer columns for wrap-around movement */
29   for (x = 0; x < lev.left; x++)
30   {
31     lev.cavecol[x] = lev.cavecol[lev.width + x];
32     lev.nextcol[x] = lev.nextcol[lev.width + x];
33     lev.drawcol[x] = lev.drawcol[lev.width + x];
34     lev.boomcol[x] = lev.boomcol[lev.width + x];
35
36     lev.cavecol[lev.right + x] = lev.cavecol[lev.left + x];
37     lev.nextcol[lev.right + x] = lev.nextcol[lev.left + x];
38     lev.drawcol[lev.right + x] = lev.drawcol[lev.left + x];
39     lev.boomcol[lev.right + x] = lev.boomcol[lev.left + x];
40   }
41
42   for (x = 0; x < lev.width; x++)
43     for (y = 0; y < lev.height; y++)
44       lev.cave[lev.left + x][lev.top + y] = cav.cave[x][y];
45
46   for (x = lev.left; x < lev.right; x++)
47     for (y = lev.top; y < lev.bottom; y++)
48       lev.next[x][y] = lev.draw[x][y] = lev.cave[x][y];
49
50   lev.time = cav.time_seconds;
51   lev.gems_needed = cav.gems_needed;
52   lev.score = 0;
53
54   lev.eater_score       = cav.eater_score;
55   lev.alien_score       = cav.alien_score;
56   lev.bug_score         = cav.bug_score;
57   lev.tank_score        = cav.tank_score;
58   lev.emerald_score     = cav.emerald_score;
59   lev.diamond_score     = cav.diamond_score;
60   lev.nut_score         = cav.nut_score;
61   lev.slurp_score       = cav.slurp_score;
62   lev.dynamite_score    = cav.dynamite_score;
63   lev.key_score         = cav.key_score;
64   lev.lenses_score      = cav.lenses_score;
65   lev.magnify_score     = cav.magnify_score;
66   lev.exit_score        = cav.exit_score;
67
68   lev.amoeba_time = cav.amoeba_time;
69
70   lev.android_move_time = cav.android_move_time;
71   lev.android_move_cnt  = cav.android_move_time;
72
73   lev.android_clone_time = cav.android_clone_time;
74   lev.android_clone_cnt  = cav.android_clone_time;
75
76   lev.ball_time   = cav.ball_time;
77   lev.ball_cnt    = cav.ball_time;
78   lev.ball_state  = cav.ball_state;
79   lev.ball_random = cav.ball_random;
80   lev.ball_pos    = 0;
81
82   lev.eater_pos = 0;
83   lev.shine_cnt = 0;
84
85   lev.lenses_time = cav.lenses_time;
86   lev.lenses_cnt  = cav.lenses_cnt;
87
88   lev.magnify_time = cav.magnify_time;
89   lev.magnify_cnt  = cav.magnify_cnt;
90
91   lev.wheel_time = cav.wheel_time;
92   lev.wheel_cnt  = cav.wheel_cnt;
93   lev.wheel_x    = cav.wheel_x;
94   lev.wheel_y    = cav.wheel_y;
95
96   lev.wind_time      = cav.wind_time;
97   lev.wind_cnt       = cav.wind_cnt;
98   lev.wind_direction = cav.wind_direction;
99
100   lev.wonderwall_time  = cav.wonderwall_time;
101   lev.wonderwall_state = cav.wonderwall_state;
102
103   lev.killed_out_of_time = FALSE;
104
105   lev.num_ball_arrays = cav.num_ball_arrays;
106
107   for (i = 0; i < 8; i++)
108     for (j = 0; j < 9; j++)
109       lev.eater_array[i][j] = cav.eater_array[i][j];
110
111   for (i = 0; i < 8; i++)
112     for (j = 0; j < 8; j++)
113       lev.ball_array[i][j] = cav.ball_array[i][j];
114
115   for (i = 0; i < TILE_MAX; i++)
116     lev.android_array[i] = cav.android_array[i];
117
118   /* determine number of players in this level */
119   lev.home_initial = 0;
120
121   for (i = 0; i < MAX_PLAYERS; i++)
122   {
123     ply[i].exists = 0;
124     ply[i].alive_initial = FALSE;
125
126     if (cav.player_x[i] != -1 &&
127         cav.player_y[i] != -1)
128     {
129       ply[i].exists = 1;
130
131       lev.home_initial++;
132     }
133   }
134
135   team_mode = getTeamMode_EM();
136
137   if (!team_mode)
138     lev.home_initial = 1;
139
140   lev.home = lev.home_initial;
141   players_left = lev.home_initial;
142
143   for (i = 0; i < MAX_PLAYERS; i++)
144   {
145     if (ply[i].exists)
146     {
147       if (players_left)
148       {
149         ply[i].alive_initial = TRUE;
150         players_left--;
151       }
152       else
153       {
154         int x = cav.player_x[i];
155         int y = cav.player_y[i];
156
157         lev.cave[lev.left + x][lev.top + y] = Xblank;
158         lev.next[lev.left + x][lev.top + y] = Xblank;
159         lev.draw[lev.left + x][lev.top + y] = Xblank;
160       }
161     }
162   }
163
164   for (i = 0; i < MAX_PLAYERS; i++)
165   {
166     ply[i].num = i;
167     ply[i].alive = ply[i].alive_initial;
168     ply[i].dynamite = 0;
169     ply[i].dynamite_cnt = 0;
170     ply[i].keys = 0;
171     ply[i].anim = 0;
172     ply[i].oldx = ply[i].x = cav.player_x[i] + lev.left;
173     ply[i].oldy = ply[i].y = cav.player_y[i] + lev.top;
174     ply[i].last_move_dir = MV_NONE;
175     ply[i].joy_n = ply[i].joy_e = ply[i].joy_s = ply[i].joy_w = 0;
176     ply[i].joy_snap  = ply[i].joy_drop = 0;
177     ply[i].joy_stick = ply[i].joy_spin = 0;
178   }
179
180   // the following engine variables are initialized to version-specific values
181   // in function InitGameEngine() (src/game.c):
182   //
183   // - game_em.use_single_button (default: TRUE)
184   // - game_em.use_snap_key_bug (default: FALSE)
185   // - game_em.use_old_explosions (default: FALSE)
186
187   game_em.level_solved = FALSE;
188   game_em.game_over = FALSE;
189
190   game_em.any_player_moving = FALSE;
191   game_em.any_player_snapping = FALSE;
192
193   game_em.last_moving_player = 0;       /* default: first player */
194
195   for (i = 0; i < MAX_PLAYERS; i++)
196     game_em.last_player_direction[i] = MV_NONE;
197
198   lev.exit_x = lev.exit_y = -1; /* kludge for playing player exit sound */
199 }