1 #include "char.h"
2 #include "map.h"
3 #include "game.h"
4 #include "gfx.h"
5
6 CHAR list[MAX_CHARS];
7 int char_num = 1;
8
9 /* Moving:
10
11 main loop -> player_process(), monster_process()
12 | |
13 char_move()
14 |
15 / \
16 step dx || dy
17 | |
18 when step gets 0 | |
19 change_position() leave(), encounter()
20
21 */
22
23 /* C64: data
24 455 dataa,dire wolf,31,a,rogue,42
25 456 dataan,ogre,27,a,barbarian,41,a,hobgoblin,27,an,elvin ranger,41,a,werebear,27
26 457 dataa,dwarven guard,43,a,gargoyle,28,a,mercenary,41,a,troll,27,a,swordsman,41
27 458 dataa,wyvern,30,a,monk,41,a,dimension spider,29,a,dark warrior,41,a,shadow dragon,30
28 459 dataan,assassin,40,a,fyre drake,30,a,war lord,41
29 */
30
31 char const *char_names[CHAR_NUM] = {
32 "you",
33 "Rogue",
34 "Barbarian",
35 "Elvin Ranger",
36 "Dwarven Guard",
37 "Mercenary",
38 "Swordsman",
39 "Monk",
40 "Dark Warrior",
41 "Assassin",
42 "War Lord",
43 "Dire Wolf",
44 "Ogre",
45 "Hobgoblin",
46 "Werebear",
47 "Gargoyle",
48 "Troll",
49 "Wyvern",
50 "Dimension Spider",
51 "Shadow Dragon",
52 "Fyre Drake"
53 };
54
55 char const *char_prefixes[CHAR_NUM][3] = {
56 {"", "", ""},
57 {"a", "an inferior", "an experienced"},
58 {"a", "an inferior", "an experienced"},
59 {"an", "an inferior", "an experienced"},
60 {"a", "an inferior", "an experienced"},
61 {"a", "an inferior", "an experienced"},
62 {"a", "an inferior", "an experienced"},
63 {"a", "an inferior", "an experienced"},
64 {"a", "an inferior", "an experienced"},
65 {"an", "an inferior", "an experienced"},
66 {"a", "an inferior", "an experienced"},
67 {"a", "a weak", "a powerful"},
68 {"an", "a weak", "a powerful"},
69 {"a", "a weak", "a powerful"},
70 {"a", "a weak", "a powerful"},
71 {"a", "a weak", "a powerful"},
72 {"a", "a weak", "a powerful"},
73 {"a", "a weak", "a powerful"},
74 {"a", "a weak", "a powerful"},
75 {"a", "a weak", "a powerful"},
76 {"a", "a weak", "a powerful"}
77 };
78
79 void
chars_init(void)80 chars_init (void)
81 {
82
83 }
84
85 int
char_create(int x,int y)86 char_create (int x, int y)
87 {
88 int id;
89
90 if (char_num == MAX_CHARS)
91 return 0;
92
93 for (id = 1; id < char_num; id++)
94 {
95 if (!list[id].alive)
96 break;
97 }
98 if (id == MAX_CHARS)
99 return 0;
100 if (id == char_num)
101 char_num++;
102
103 memset (&list[id], 0, sizeof list[id]);
104
105 list[id].x = x;
106 list[id].y = y;
107 list[id].alive = 1;
108
109 return id;
110 }
111
112 /**
113 * Called by char_move when a character encounters another one.
114 */
115 static int
encounter(int id,int who)116 encounter (int id, int who)
117 {
118 if (who == 1 && map_get_spot (list[who].x, list[who].y) != SPOT_TEMPLE &&
119 map_get_spot (list[who].x, list[who].y) != SPOT_BEACON/* &&
120 !list[who].step*/)
121 {
122 if (!list[who].fighting && list[who].alive)
123 {
124 list[id].fighting = who;
125 list[who].fighting = id;
126 list[who].attacked = 1;
127 message (FPS * 2, attack, "Attacked by %s %s!",
128 char_prefixes[list[id].type][list[id].subtype],
129 char_names[list[id].type]);
130 return 1;
131 }
132 }
133 if (id == 1)
134 {
135 if (!list[id].fighting)
136 {
137 list[id].fighting = who;
138 list[who].fighting = id;
139 list[who].attacked = 1;
140 message (FPS * 2, fight, "%c%s %s!",
141 toupper (char_prefixes[list[who].type][list[who].subtype][0]),
142 char_prefixes[list[who].type][list[who].subtype] + 1,
143 char_names[list[who].type]);
144 return 1;
145 }
146 }
147 return 0;
148 }
149
150 /**
151 * Called by char_move whenever a character leaves his current position.
152 */
153 static void
leave(int id)154 leave (int id)
155 {
156 if (id == 1)
157 {
158 player_leave (id);
159 }
160 }
161
162 /**
163 * Called by char_move whenever a character changes to a new position.
164 */
165 static void
change_position(int id)166 change_position (int id)
167 {
168 if (id == 1)
169 player_change_position (id);
170 else
171 monster_change_position (id);
172 }
173
174 /**
175 * Returns 0 if the character may not enter the given map position.
176 */
177 static int
may_walk(int id,int x,int y)178 may_walk (int id, int x, int y)
179 {
180 if (id == 1 && !list[id].attacked && map_get_spot (x, y) != SPOT_WALL)
181 return 1;
182 if (id > 1 && map_get_spot (x, y) != SPOT_WALL)
183 return 1;
184 return 0;
185 }
186
187 /**
188 * Processes movement of a character. If its is still moving, dx and dy are
189 * ignored. Else, the character tries to move in the given direction.
190 *
191 * Returns 1 if a move is initiated
192 **/
193 int
char_move(int id,int dx,int dy)194 char_move (int id, int dx, int dy)
195 {
196 int x = list[id].x;
197 int y = list[id].y;
198
199 if (!list[id].alive)
200 return 0;
201
202 if (list[id].step)
203 {
204 int overlap;
205
206 overlap = (sprite_h + th - 1) / th - 1;
207 list[id].step--;
208
209 DR_add (x - 1 - 1, y - overlap - 1, x + 1 + 1, y + 1);
210
211 if (!list[id].step)
212 change_position (id);
213 }
214 else if (dx || dy)
215 {
216 int ok = 0;
217 int ox, oy;
218
219 ox = x;
220 oy = y;
221
222 if (may_walk (id, x + dx, y + dy))
223 ok = 1;
224 else if (dx && dy)
225 {
226 if (may_walk (id, x, y + dy))
227 {
228 ok = 1;
229 dx = 0;
230 }
231 else if (may_walk (id, x + dx, y))
232 {
233 ok = 1;
234 dy = 0;
235 }
236 }
237
238 if (ok)
239 {
240 int e = map_get_char (x + dx, y + dy);
241 int go = 0;
242 if (e == 0)
243 {
244 e=list[id].fighting;
245 cancel_fighting (id);
246 if(!e)
247 go = 1;
248 else
249 go = 2;
250 }
251 else
252 {
253 if (extensions_overlapfight)
254 {
255 encounter (id, e);
256 return 0;
257 }
258 else
259 {
260 int player_involved = (id == 1 || (e == 1 && !list[e].fighting));
261 if (player_involved)
262 {
263 cancel_fighting (id);
264 if (encounter (id, e))
265 go = 1;
266 }
267 }
268 }
269
270 if (go)
271 {
272 if(go==2 && !extensions_overlapfight)
273 map_put_char (x, y, e);
274 else
275 map_put_char (x, y, 0);
276
277 leave (id);
278
279 x += dx;
280 y += dy;
281
282 list[id].dx = dx;
283 list[id].dy = dy;
284 list[id].step = get_steptime();
285 list[id].x = x;
286 list[id].y = y;
287
288 map_put_char (x, y, id);
289 }
290 }
291 else
292 {
293 return 0;
294 }
295
296 return 1;
297 }
298 return 0;
299 }
300
301 void
char_transfer_to(int id,int x,int y)302 char_transfer_to (int id, int x, int y)
303 {
304 list[id].step = 0;
305
306 map_put_char (list[id].x, list[id].y, 0);
307 cancel_fighting (id);
308
309 leave (id);
310
311 list[id].x = x;
312 list[id].y = y;
313 map_put_char (x, y, id);
314
315 change_position (id);
316 }
317
318 int
char_teleport(int id)319 char_teleport (int id)
320 {
321 int x = list[id].beaconx;
322 int y = list[id].beacony;
323
324 if ((!x || !y) || list[1].trapped)
325 do
326 {
327 x = rnd (1, MAP_W - 2);
328 y = rnd (1, MAP_H - 2);
329 }
330 while (map_get_spot (x, y) != SPOT_FLOOR || map_get_char (x, y));
331
332 char_transfer_to (id, x, y);
333 return 1;
334 }
335