1 /* Tower Toppler - Nebulus
2 * Copyright (C) 2000-2012 Andreas R�ver
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "elevators.h"
20
21 #include "level.h"
22 #include "decl.h"
23 #include "toppler.h"
24
25 #include <stdlib.h>
26
27 #define MAX_ELE 10
28
29 /* elevators are handled in a quite complicated way: while
30 the toppler is moving on the elevator the platform is invisible
31 and drawn together with the toppler. The stick below the elevator
32 is always drawn in such a way that the last one will appear or disappear
33 below the platform under the toppler */
34
35 static struct {
36 /* the current position of the platform */
37 Uint8 angle;
38 Uint16 vertical;
39
40 /* time until the elevator falls down */
41 Sint8 time;
42
43 /* background value necessary because in between the stations it
44 is impossible to show a platform so we save the actual value
45 there and force a station at the position, when the elevator moves
46 further down we restore the value there */
47 Uint8 bg;
48 } elevators[MAX_ELE];
49
50 static Sint8 active_ele;
51 static Sint8 ele_dir;
52
ele_init(void)53 void ele_init(void) {
54
55 for (Uint8 t = 0; t < MAX_ELE; t++)
56 elevators[t].time = -1;
57
58 active_ele = -1;
59 }
60
ele_select(Uint16 row,Uint8 col)61 void ele_select(Uint16 row, Uint8 col) {
62
63 assert_msg(active_ele == -1, "Select more than one elevator.");
64
65 Uint8 what = 0;
66
67 col /= 8;
68 row /= 4;
69 row--;
70
71 for (int t = 0; t < MAX_ELE; t++) {
72 if ((elevators[t].time == -1) && (what == 0)) {
73 what = 1;
74 active_ele = t;
75 }
76 if ((elevators[t].angle == col) && (elevators[t].vertical == row)) {
77 what = 2;
78 active_ele = t;
79 }
80 }
81
82 elevators[active_ele].angle = col;
83 elevators[active_ele].vertical = row;
84 elevators[active_ele].time = -1;
85
86 }
87
ele_activate(Sint8 dir)88 void ele_activate(Sint8 dir) {
89
90 assert_msg(active_ele != -1, "Work with unselected elevator, activate.");
91
92 lev_platform2stick(elevators[active_ele].vertical, elevators[active_ele].angle);
93 ele_dir = dir;
94 if (dir == -1) ele_move();
95 }
96
ele_move(void)97 void ele_move(void) {
98
99 assert_msg(active_ele != -1, "Work with unselected elevator, move.");
100
101 if (ele_dir == 1) {
102 elevators[active_ele].vertical++;
103
104 lev_empty2stick(elevators[active_ele].vertical, elevators[active_ele].angle);
105 } else {
106 lev_stick2empty(elevators[active_ele].vertical, elevators[active_ele].angle);
107
108 elevators[active_ele].vertical--;
109 }
110 }
111
ele_is_atstop(void)112 bool ele_is_atstop(void) {
113
114 assert_msg(active_ele != -1, "Work with unselected elevator, is_atstop.");
115
116 if (ele_dir == 1)
117 return lev_is_station(elevators[active_ele].vertical + 1, elevators[active_ele].angle);
118 else
119 return lev_is_station(elevators[active_ele].vertical, elevators[active_ele].angle);
120 }
121
ele_deactivate(void)122 void ele_deactivate(void) {
123
124 assert_msg(active_ele != -1, "Deselected an inactive elevator.");
125
126 if (ele_dir == 1) ele_move();
127
128 lev_stick2platform(elevators[active_ele].vertical, elevators[active_ele].angle);
129
130 Uint8 ae = active_ele;
131 active_ele = -1;
132
133 if (!lev_is_station(elevators[ae].vertical, elevators[ae].angle))
134 elevators[ae].bg = lev_putplatform(elevators[ae].vertical, elevators[ae].angle);
135 else
136 if (lev_is_bottom_station(elevators[ae].vertical, elevators[ae].angle))
137 return;
138 else
139 elevators[ae].bg = lev_tower(elevators[ae].vertical, elevators[ae].angle);
140
141 elevators[ae].time = 0x7d;
142 }
143
ele_update(void)144 void ele_update(void) {
145
146 for (Uint8 t = 0; t < MAX_ELE; t++) {
147 if (elevators[t].time == 0) {
148 lev_restore(elevators[t].vertical, elevators[t].angle, elevators[t].bg);
149 lev_platform2empty(elevators[t].vertical, elevators[t].angle);
150 elevators[t].vertical--;
151 lev_stick2platform(elevators[t].vertical, elevators[t].angle);
152 if (lev_is_bottom_station(elevators[t].vertical, elevators[t].angle)) {
153 elevators[t].time = -1;
154 top_sidemove();
155 } else
156 elevators[t].bg = lev_putplatform(elevators[t].vertical, elevators[t].angle);
157 }
158
159 if (elevators[t].time > 0)
160 elevators[t].time--;
161 }
162 }
163
164