SHOW:
|
|
- or go back to the newest paste.
1 | - | // 02 uncover map |
1 | + | // 03 commands |
2 | ||
3 | - | // hide everything on the map and uncover it as the player roams |
3 | + | // enable commands HJKLYUBN . s idc eqr tz wWTPR D |
4 | - | // makes 3x3 rooms with 1 gold pile and 1 monster each |
4 | + | |
5 | - | // lit rooms light up when player walks in |
5 | + | |
6 | - | // can discover traps |
6 | + | |
7 | ||
8 | class Program | |
9 | { | |
10 | static List<ITEM> items_on_floor; | |
11 | ||
12 | static List<THING> monsters; | |
13 | ||
14 | static THING player = new THING(); | |
15 | ||
16 | static bool player_running = false; | |
17 | ||
18 | static bool found_amulet = false; | |
19 | ||
20 | static Random random = new Random(); | |
21 | ||
22 | static void Main(string[] args) | |
23 | { | |
24 | Console.WindowWidth = Console.BufferWidth = 80; | |
25 | Console.WindowHeight = Console.BufferHeight = 25; | |
26 | Console.Title = "steelgolem rogue - 03 commands"; | |
27 | - | Console.Title = "steelgolem rogue - 02 uncover map"; |
27 | + | |
28 | ITEM item = new ITEM(); | |
29 | item.ch = ')'; | |
30 | item.type = "mace"; | |
31 | player.items.Add(item); | |
32 | ||
33 | item = new ITEM(); | |
34 | item.ch = ')'; | |
35 | item.type = "short bow"; | |
36 | player.items.Add(item); | |
37 | ||
38 | item = new ITEM(); | |
39 | item.ch = ')'; | |
40 | item.type = "arrow"; | |
41 | - | char key_ch = CONSOLE.read_key(); |
41 | + | item.count = 20; |
42 | player.items.Add(item); | |
43 | - | switch (key_ch) |
43 | + | |
44 | item = new ITEM(); | |
45 | - | case '?': show_help(); break; |
45 | + | item.ch = ']'; |
46 | item.type = "ring mail"; | |
47 | - | case 'h': move_player(-1, 0); break; |
47 | + | player.items.Add(item); |
48 | - | case 'j': move_player(0, +1); break; |
48 | + | |
49 | - | case 'k': move_player(0, -1); break; |
49 | + | item = new ITEM(); |
50 | - | case 'l': move_player(+1, 0); break; |
50 | + | item.ch = ':'; |
51 | - | case 'y': move_player(-1, -1); break; |
51 | + | item.type = "food"; |
52 | - | case 'u': move_player(+1, -1); break; |
52 | + | player.items.Add(item); |
53 | - | case 'b': move_player(-1, +1); break; |
53 | + | |
54 | - | case 'n': move_player(+1, +1); break; |
54 | + | |
55 | ||
56 | - | case '>': |
56 | + | |
57 | - | if (dungeon_map[player.x, player.y] == '%') |
57 | + | |
58 | ||
59 | - | if (found_amulet && dungeon_level == 1) |
59 | + | |
60 | - | win_game(); |
60 | + | |
61 | while (true) | |
62 | - | if (found_amulet) dungeon_level--; |
62 | + | |
63 | - | else dungeon_level++; |
63 | + | |
64 | CONSOLE.move_cursor(player.x, player.y); | |
65 | - | new_level(); |
65 | + | |
66 | - | update_status(); |
66 | + | if (!player_running) |
67 | { | |
68 | char key_ch = CONSOLE.read_key(); | |
69 | ||
70 | - | if (found_amulet) set_message("there is no way up"); |
70 | + | switch (key_ch) |
71 | - | else set_message("there is no way down"); |
71 | + | |
72 | case '?': show_help(); break; | |
73 | - | break; |
73 | + | |
74 | case 'h': move_player(-1, 0); break; | |
75 | - | case (char)18: // ^R |
75 | + | case 'j': move_player(0, +1); break; |
76 | - | set_message(last_message); |
76 | + | case 'k': move_player(0, -1); break; |
77 | - | break; |
77 | + | case 'l': move_player(+1, 0); break; |
78 | case 'y': move_player(-1, -1); break; | |
79 | - | case 'Q': |
79 | + | case 'u': move_player(+1, -1); break; |
80 | - | Environment.Exit(0); |
80 | + | case 'b': move_player(-1, +1); break; |
81 | - | break; |
81 | + | case 'n': move_player(+1, +1); break; |
82 | ||
83 | case 'H': start_running(-1, 0); break; | |
84 | case 'J': start_running(0, +1); break; | |
85 | case 'K': start_running(0, -1); break; | |
86 | case 'L': start_running(+1, 0); break; | |
87 | case 'Y': start_running(-1, -1); break; | |
88 | case 'U': start_running(+1, -1); break; | |
89 | case 'B': start_running(-1, +1); break; | |
90 | case 'N': start_running(+1, +1); break; | |
91 | ||
92 | case '.': break; | |
93 | ||
94 | case '>': | |
95 | if (dungeon_map[player.x, player.y] == '%') | |
96 | { | |
97 | if (found_amulet && dungeon_level == 1) | |
98 | win_game(); | |
99 | ||
100 | if (found_amulet) dungeon_level--; | |
101 | else dungeon_level++; | |
102 | ||
103 | new_level(); | |
104 | update_status(); | |
105 | } | |
106 | else | |
107 | { | |
108 | if (found_amulet) set_message("there is no way up"); | |
109 | else set_message("there is no way down"); | |
110 | } | |
111 | break; | |
112 | ||
113 | case 's': search(); break; | |
114 | ||
115 | case 'i': show_inventory(); break; | |
116 | case 'd': drop_item(); break; | |
117 | case 'c': call_item_name(); break; | |
118 | ||
119 | case 'e': eat_food(); break; | |
120 | case 'q': quaff_potion(); break; | |
121 | case 'r': read_scroll(); break; | |
122 | ||
123 | case 't': throw_item(); break; | |
124 | case 'z': zap_stick(); break; | |
125 | ||
126 | case 'w': wield_weapon(); break; | |
127 | case 'W': wear_armor(); break; | |
128 | case 'T': take_off_armor(); break; | |
129 | case 'P': put_on_ring(); break; | |
130 | case 'R': remove_ring(); break; | |
131 | ||
132 | - | dungeon_map[room.x + room.w / 2, room.y + room.h - 1] = '+'; |
132 | + | case 'D': list_discoveries(); break; |
133 | ||
134 | case (char)18: // ^R | |
135 | set_message(last_message); | |
136 | break; | |
137 | ||
138 | case 'Q': | |
139 | Environment.Exit(0); | |
140 | break; | |
141 | ||
142 | default: | |
143 | if (key_ch < 32) | |
144 | set_message("unknown command: ^" + (char)(key_ch + 'A' - 1)); | |
145 | else | |
146 | set_message("unknown command: " + key_ch); | |
147 | break; | |
148 | } | |
149 | } | |
150 | ||
151 | while (player_running) | |
152 | player_running = move_player(run_dir_x, run_dir_y); | |
153 | } | |
154 | } | |
155 | ||
156 | #region dungeon level | |
157 | ||
158 | static int dungeon_level; | |
159 | ||
160 | static char[,] dungeon_map = new char[80, 25]; | |
161 | ||
162 | static ROOM[,] rooms; | |
163 | ||
164 | const int room_max_w = 80 / 3; | |
165 | const int room_max_h = 23 / 3; | |
166 | ||
167 | static List<TRAP> traps; | |
168 | ||
169 | static void new_level() | |
170 | { | |
171 | items_on_floor = new List<ITEM>(); | |
172 | ||
173 | monsters = new List<THING>(); | |
174 | ||
175 | traps = new List<TRAP>(); | |
176 | ||
177 | for (int y = 0; y < 25; y++) | |
178 | for (int x = 0; x < 80; x++) | |
179 | dungeon_map[x, y] = ' '; | |
180 | ||
181 | CONSOLE.clear(); | |
182 | ||
183 | // add 3x3 rooms | |
184 | rooms = new ROOM[3, 3]; | |
185 | for (int ry = 0; ry < 3; ry++) | |
186 | { | |
187 | for (int rx = 0; rx < 3; rx++) | |
188 | { | |
189 | ROOM room = new ROOM(); | |
190 | room.w = 4 + random.Next(room_max_w - 4); | |
191 | room.h = 4 + random.Next(room_max_h - 4); | |
192 | room.x = rx * room_max_w + | |
193 | random.Next(room_max_w - room.w); | |
194 | room.y = 1 + ry * room_max_h + | |
195 | random.Next(room_max_h - room.h); | |
196 | if (random.Next(100) < 50) | |
197 | room.is_lit = true; | |
198 | rooms[rx, ry] = room; | |
199 | ||
200 | room.draw_on_map(); | |
201 | // one door at the bottom | |
202 | char door_ch = '+'; | |
203 | if (random.Next(100) < 50) door_ch = '&'; | |
204 | dungeon_map[room.x + room.w / 2, room.y + room.h - 1] = door_ch; | |
205 | } | |
206 | } | |
207 | ||
208 | // add some random level bits | |
209 | for (int c = 0; c < 80; c++) | |
210 | { | |
211 | int x = random.Next(80); | |
212 | int y = 1 + random.Next(23); | |
213 | char ch = "-|.+#"[random.Next(5)]; | |
214 | dungeon_map[x, y] = ch; | |
215 | } | |
216 | ||
217 | // add some traps | |
218 | for (int t = 0; t < 9; t++) | |
219 | { | |
220 | TRAP trap = new TRAP(); | |
221 | do | |
222 | { | |
223 | ROOM room = get_random_room(); | |
224 | room.set_random_pos(trap); | |
225 | } | |
226 | while (dungeon_map[trap.x, trap.y] != '.'); | |
227 | trap.ch = ">{$}~`"[random.Next(6)]; | |
228 | dungeon_map[trap.x, trap.y] = trap.ch; | |
229 | traps.Add(trap); | |
230 | } | |
231 | ||
232 | // add some gold | |
233 | for (int ry = 0; ry < 3; ry++) | |
234 | { | |
235 | for (int rx = 0; rx < 3; rx++) | |
236 | { | |
237 | ROOM room = rooms[rx, ry]; | |
238 | ITEM item = new ITEM(); | |
239 | do room.set_random_pos(item); | |
240 | while (dungeon_map[item.x, item.y] != '.'); | |
241 | item.ch = '*'; | |
242 | items_on_floor.Add(item); | |
243 | } | |
244 | } | |
245 | ||
246 | // add some items | |
247 | for (int c = 0; c < 9; c++) | |
248 | { | |
249 | ITEM item = new ITEM(); | |
250 | do | |
251 | { | |
252 | ROOM room = get_random_room(); | |
253 | room.set_random_pos(item); | |
254 | } | |
255 | while (dungeon_map[item.x, item.y] != '.'); | |
256 | item.ch = ":!?)]=/"[random.Next(7)]; | |
257 | switch (item.ch) | |
258 | { | |
259 | case ':': item.type = "food"; break; | |
260 | case '!': item.type = "potion"; break; | |
261 | case '?': item.type = "scroll"; break; | |
262 | case ')': item.type = "weapon"; break; | |
263 | case ']': item.type = "armor"; break; | |
264 | case '=': item.type = "ring"; break; | |
265 | case '/': item.type = "stick"; break; | |
266 | } | |
267 | items_on_floor.Add(item); | |
268 | } | |
269 | ||
270 | // add some monsters | |
271 | for (int ry = 0; ry < 3; ry++) | |
272 | { | |
273 | for (int rx = 0; rx < 3; rx++) | |
274 | { | |
275 | ROOM room = rooms[rx, ry]; | |
276 | THING monster = new THING(); | |
277 | do room.set_random_pos(monster); | |
278 | while (dungeon_map[monster.x, monster.y] != '.'); | |
279 | monster.ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[random.Next(26)]; | |
280 | monsters.Add(monster); | |
281 | } | |
282 | } | |
283 | ||
284 | // add the amulet | |
285 | if (dungeon_level >= 26) | |
286 | { | |
287 | ITEM item = new ITEM(); | |
288 | do | |
289 | { | |
290 | ROOM room = get_random_room(); | |
291 | room.set_random_pos(item); | |
292 | } | |
293 | while (dungeon_map[item.x, item.y] != '.'); | |
294 | item.ch = ','; | |
295 | item.type = "the amulet of yendor"; | |
296 | items_on_floor.Add(item); | |
297 | } | |
298 | ||
299 | // add the stairs | |
300 | int stairs_x = -1, stairs_y = -1; | |
301 | do | |
302 | { | |
303 | ROOM room = get_random_room(); | |
304 | room.set_random_pos(ref stairs_x, ref stairs_y); | |
305 | } | |
306 | while (dungeon_map[stairs_x, stairs_y] != '.'); | |
307 | dungeon_map[stairs_x, stairs_y] = '%'; | |
308 | ||
309 | // place the player | |
310 | do | |
311 | { | |
312 | ROOM room = get_random_room(); | |
313 | room.set_random_pos(player); | |
314 | } | |
315 | while (dungeon_map[player.x, player.y] != '.'); | |
316 | draw_what_player_can_see(); | |
317 | } | |
318 | ||
319 | class ROOM | |
320 | { | |
321 | - | CONSOLE.write_string(0, h, help_text[h]); |
321 | + | |
322 | public bool is_lit; | |
323 | ||
324 | public void draw_on_map() | |
325 | { | |
326 | for (int y = 0; y < this.h; y++) | |
327 | for (int x = 0; x < this.w; x++) | |
328 | dungeon_map[this.x + x, this.y + y] = '.'; | |
329 | ||
330 | - | static void move_player(int dx, int dy) |
330 | + | |
331 | { | |
332 | dungeon_map[this.x, this.y + y] = '|'; | |
333 | dungeon_map[this.x + this.w - 1, this.y + y] = '|'; | |
334 | } | |
335 | ||
336 | for (int x = 0; x < this.w; x++) | |
337 | { | |
338 | dungeon_map[this.x + x, this.y] = '-'; | |
339 | dungeon_map[this.x + x, this.y + this.h - 1] = '-'; | |
340 | } | |
341 | } | |
342 | ||
343 | public void set_random_pos(ref int x, ref int y) | |
344 | { | |
345 | x = this.x + 1 + random.Next(this.w - 2); | |
346 | y = this.y + 1 + random.Next(this.h - 2); | |
347 | } | |
348 | ||
349 | public void set_random_pos(ITEM item) | |
350 | { | |
351 | set_random_pos(ref item.x, ref item.y); | |
352 | } | |
353 | ||
354 | public void set_random_pos(THING thing) | |
355 | - | return; |
355 | + | |
356 | set_random_pos(ref thing.x, ref thing.y); | |
357 | } | |
358 | ||
359 | public void set_random_pos(TRAP trap) | |
360 | { | |
361 | set_random_pos(ref trap.x, ref trap.y); | |
362 | } | |
363 | } | |
364 | ||
365 | static ROOM get_random_room() | |
366 | { | |
367 | return rooms[random.Next(3), random.Next(3)]; | |
368 | } | |
369 | ||
370 | static ROOM get_room_at(int x, int y) | |
371 | { | |
372 | for (int ry = 0; ry < 3; ry++) | |
373 | { | |
374 | for (int rx = 0; rx < 3; rx++) | |
375 | { | |
376 | - | return; |
376 | + | |
377 | if (x >= room.x && x < room.x + room.w && | |
378 | y >= room.y && y < room.y + room.h) | |
379 | - | set_message("picked up " + get_name(item.ch)); |
379 | + | |
380 | } | |
381 | } | |
382 | return null; | |
383 | - | player.items.Add(item); |
383 | + | |
384 | ||
385 | - | if (item.ch == ',') |
385 | + | |
386 | - | found_amulet = true; |
386 | + | |
387 | public int x, y; | |
388 | public char ch; | |
389 | public bool found; | |
390 | } | |
391 | ||
392 | static TRAP get_trap_at(int x, int y) | |
393 | { | |
394 | for (int t = 0; t < traps.Count; t++) | |
395 | if (x == traps[t].x && y == traps[t].y) | |
396 | return traps[t]; | |
397 | ||
398 | return null; | |
399 | } | |
400 | ||
401 | #endregion // dungeon level | |
402 | ||
403 | #region commands | |
404 | ||
405 | static void show_help() | |
406 | { | |
407 | string[] help_text = new string[] | |
408 | { | |
409 | "? show help", | |
410 | "h move left", | |
411 | "j move down", | |
412 | "k move up", | |
413 | "l move right", | |
414 | "y move up & left", | |
415 | "u move up & right", | |
416 | "b move down & left", | |
417 | "n move down & right", | |
418 | "H run left", | |
419 | "J run down", | |
420 | "K run up", | |
421 | "L run right", | |
422 | "Y run up & left", | |
423 | "U run up & right", | |
424 | "B run down & left", | |
425 | "N run down & right", | |
426 | ". rest for a turn", | |
427 | "> use stairs", | |
428 | "s search for hidden doors and traps", | |
429 | "i show inventory", | |
430 | "d drop item", | |
431 | "e eat food", | |
432 | "q quaff potion", | |
433 | "r read scroll", | |
434 | "t throw item", | |
435 | "z zap wand or staff", | |
436 | "w wield weapon", | |
437 | "W wear armor", | |
438 | "T take off armor", | |
439 | "P put on ring", | |
440 | "R remove ring", | |
441 | "D list discoveries", | |
442 | "^R repeat last message", | |
443 | "Q quit game", | |
444 | }; | |
445 | ||
446 | CONSOLE.back_up_buffer(); | |
447 | ||
448 | CONSOLE.clear(); | |
449 | ||
450 | int x = 0, y = 0; | |
451 | for (int h = 0; h < help_text.Length; h++) | |
452 | { | |
453 | CONSOLE.write_string(x, y, help_text[h]); | |
454 | y++; | |
455 | ||
456 | if (help_text.Length % 2 == 0) | |
457 | { | |
458 | if (h == help_text.Length / 2 - 1) | |
459 | { | |
460 | x = 40; | |
461 | y = 0; | |
462 | } | |
463 | } | |
464 | else | |
465 | { | |
466 | if (h == help_text.Length / 2) | |
467 | { | |
468 | x = 40; | |
469 | y = 0; | |
470 | } | |
471 | } | |
472 | } | |
473 | ||
474 | CONSOLE.write_string(0, 24, "[press any key]"); | |
475 | ||
476 | CONSOLE.read_key(); | |
477 | ||
478 | CONSOLE.restore_buffer(); | |
479 | } | |
480 | ||
481 | // returns false if player stopped | |
482 | static bool move_player(int dx, int dy) | |
483 | { | |
484 | clear_message(); | |
485 | ||
486 | int dest_x = player.x + dx; | |
487 | int dest_y = player.y + dy; | |
488 | ||
489 | if (dest_x < 1 || dest_x >= 79 || | |
490 | dest_y < 2 || dest_y >= 23) | |
491 | return false; | |
492 | ||
493 | char map_ch = dungeon_map[dest_x, dest_y]; | |
494 | ||
495 | // walls stop movement | |
496 | if (is_wall(map_ch)) | |
497 | return false; | |
498 | ||
499 | // fight monster | |
500 | for (int m = monsters.Count - 1; m >= 0; m--) | |
501 | { | |
502 | THING monster = monsters[m]; | |
503 | ||
504 | if (dest_x == monster.x && dest_y == monster.y) | |
505 | { | |
506 | monsters.Remove(monster); | |
507 | ||
508 | draw_what_player_can_see(); | |
509 | ||
510 | set_message("defeated " + get_name(monster.ch)); | |
511 | ||
512 | return false; | |
513 | } | |
514 | } | |
515 | ||
516 | CONSOLE.cursor_off(); | |
517 | ||
518 | erase_what_player_cant_see(); | |
519 | ||
520 | player.x = dest_x; | |
521 | player.y = dest_y; | |
522 | ||
523 | draw_what_player_can_see(); | |
524 | ||
525 | CONSOLE.cursor_on(); | |
526 | ||
527 | // pick up item | |
528 | for (int i = items_on_floor.Count - 1; i >= 0; i--) | |
529 | { | |
530 | ITEM item = items_on_floor[i]; | |
531 | ||
532 | if (dest_x == item.x && dest_y == item.y) | |
533 | { | |
534 | if (player.items.Count == 23) | |
535 | { | |
536 | set_message("no room in inventory"); | |
537 | return false; | |
538 | } | |
539 | ||
540 | set_message("picked up " + get_item_name(item.ch)); | |
541 | ||
542 | items_on_floor.Remove(item); | |
543 | ||
544 | if(item.ch != '*') | |
545 | player.items.Add(item); | |
546 | ||
547 | if (item.ch == ',') found_amulet = true; | |
548 | ||
549 | return false; | |
550 | } | |
551 | } | |
552 | ||
553 | // get trapped | |
554 | for (int t = 0; t < traps.Count; t++) | |
555 | { | |
556 | TRAP trap = traps[t]; | |
557 | ||
558 | if (dest_x == trap.x && dest_y == trap.y) | |
559 | { | |
560 | trap.found = true; | |
561 | string message = "found "; | |
562 | switch (trap.ch) | |
563 | { | |
564 | case '>': message += "trap door"; break; | |
565 | case '{': message += "arrow trap"; break; | |
566 | case '$': message += "sleep trap"; break; | |
567 | case '}': message += "bear trap"; break; | |
568 | case '~': message += "teleport trap"; break; | |
569 | case '`': message += "dart trap"; break; | |
570 | } | |
571 | set_message(message); | |
572 | return false; | |
573 | } | |
574 | } | |
575 | ||
576 | // stop on stairs and doors | |
577 | if (map_ch == '%' || map_ch == '+') return false; | |
578 | ||
579 | return true; | |
580 | } | |
581 | ||
582 | static void draw_what_player_can_see() | |
583 | { | |
584 | ROOM room = null; | |
585 | ||
586 | - | case '*': return "gold"; |
586 | + | |
587 | // everything in it every time we move | |
588 | - | case ':': return "food"; |
588 | + | |
589 | - | case '!': return "potion"; |
589 | + | |
590 | - | case '?': return "scroll"; |
590 | + | |
591 | - | case ')': return "weapon"; |
591 | + | |
592 | - | case ']': return "armor"; |
592 | + | |
593 | - | case '=': return "ring"; |
593 | + | |
594 | - | case '/': return "stick"; |
594 | + | |
595 | - | case ',': return "the amulet of yendor"; |
595 | + | |
596 | for (int rx = 0; rx < room.w; rx++) | |
597 | { | |
598 | int x = room.x + rx; | |
599 | int y = room.y + ry; | |
600 | if (">{$}~`".Contains(dungeon_map[x, y].ToString())) | |
601 | { | |
602 | TRAP trap = get_trap_at(x, y); | |
603 | if (trap.found) | |
604 | CONSOLE.put_char(x, y, '^'); | |
605 | else | |
606 | CONSOLE.put_char(x, y, '.'); | |
607 | } | |
608 | else if (dungeon_map[] == '&') | |
609 | CONSOLE.put_char(x, y, '-'); | |
610 | else | |
611 | CONSOLE.put_char(x, y, dungeon_map[x, y]); | |
612 | } | |
613 | } | |
614 | ||
615 | for (int i = 0; i < items_on_floor.Count; i++) | |
616 | { | |
617 | ITEM item = items_on_floor[i]; | |
618 | if (get_room_at(item.x, item.y) == room) | |
619 | CONSOLE.put_char(item.x, item.y, item.ch); | |
620 | } | |
621 | ||
622 | for (int m = 0; m < monsters.Count; m++) | |
623 | { | |
624 | THING monster = monsters[m]; | |
625 | if (get_room_at(monster.x, monster.y) == room) | |
626 | CONSOLE.put_char(monster.x, monster.y, monster.ch); | |
627 | } | |
628 | ||
629 | CONSOLE.put_char(player.x, player.y, '@'); | |
630 | } | |
631 | ||
632 | // 3x3 area around player | |
633 | for (int dy = -1; dy <= +1; dy++) | |
634 | { | |
635 | for (int dx = -1; dx <= +1; dx++) | |
636 | { | |
637 | int x = player.x + dx; | |
638 | int y = player.y + dy; | |
639 | ||
640 | if (x < 0 || x >= 80 || y < 0 || y >= 25) continue; | |
641 | ||
642 | CONSOLE.put_char(x, y, dungeon_map[x, y]); | |
643 | ||
644 | if (">{$}~`".Contains(dungeon_map[x, y].ToString())) | |
645 | { | |
646 | TRAP trap = get_trap_at(x, y); | |
647 | if (trap.found) | |
648 | CONSOLE.put_char(x, y, '^'); | |
649 | else | |
650 | CONSOLE.put_char(x, y, '.'); | |
651 | } | |
652 | ||
653 | for (int i = 0; i < items_on_floor.Count; i++) | |
654 | if (x == items_on_floor[i].x && | |
655 | y == items_on_floor[i].y) | |
656 | CONSOLE.put_char(x, y, items_on_floor[i].ch); | |
657 | ||
658 | for (int m = 0; m < monsters.Count; m++) | |
659 | if (x == monsters[m].x && | |
660 | y == monsters[m].y) | |
661 | CONSOLE.put_char(x, y, monsters[m].ch); | |
662 | } | |
663 | } | |
664 | ||
665 | CONSOLE.put_char(player.x, player.y, '@'); | |
666 | } | |
667 | ||
668 | static void erase_what_player_cant_see() | |
669 | { | |
670 | ROOM room = get_room_at(player.x, player.y); | |
671 | ||
672 | if (room != null && room.is_lit) | |
673 | return; | |
674 | ||
675 | // 3x3 area around player | |
676 | for (int dy = -1; dy <= +1; dy++) | |
677 | { | |
678 | for (int dx = -1; dx <= +1; dx++) | |
679 | { | |
680 | int x = player.x + dx; | |
681 | int y = player.y + dy; | |
682 | ||
683 | if (x < 0 || x >= 80 || y < 0 || y >= 25) continue; | |
684 | ||
685 | char ch = CONSOLE.get_char(x, y); | |
686 | ||
687 | if (!"-|+#%^".Contains(ch.ToString())) | |
688 | CONSOLE.put_char(x, y, ' '); | |
689 | } | |
690 | } | |
691 | } | |
692 | ||
693 | static int run_dir_x, run_dir_y; | |
694 | ||
695 | static void start_running(int dx, int dy) | |
696 | { | |
697 | player_running = true; | |
698 | run_dir_x = dx; | |
699 | run_dir_y = dy; | |
700 | } | |
701 | ||
702 | static void search() | |
703 | { | |
704 | for (int dy = -1; dy <= +1; dy++) | |
705 | { | |
706 | for (int dx = -1; dx <= +1; dx++) | |
707 | { | |
708 | int x = player.x + dx; | |
709 | int y = player.y + dy; | |
710 | if (dungeon_map[x, y] == '&') | |
711 | dungeon_map[x, y] = '+'; | |
712 | if (">{$}~`".Contains(dungeon_map[x, y].ToString()) | |
713 | { | |
714 | TRAP trap = get_trap_at(x, y); | |
715 | trap.found = true; | |
716 | } | |
717 | } | |
718 | } | |
719 | show_what_player_can_see(); | |
720 | } | |
721 | ||
722 | static void show_inventory() | |
723 | { | |
724 | CONSOLE.back_up_buffer(); | |
725 | ||
726 | CONSOLE.clear(); | |
727 | ||
728 | for (int i = 0; i < player.items.Count; i++) | |
729 | { | |
730 | string text = (char)('a' + i) + ") "; | |
731 | if (player.items[i].count > 1) | |
732 | text += player.items[i].count + " "; | |
733 | text += player.items[i].ToString(); | |
734 | } | |
735 | ||
736 | CONSOLE.write_string(0, 24, "[press any key]"); | |
737 | CONSOLE.read_key(); | |
738 | ||
739 | CONSOLE.restore_buffer(); | |
740 | } | |
741 | ||
742 | static void drop_item() | |
743 | { | |
744 | throw new NotImplementedException(); | |
745 | } | |
746 | ||
747 | static void call_item_name() | |
748 | { | |
749 | throw new NotImplementedException(); | |
750 | } | |
751 | ||
752 | static void eat_food() | |
753 | { | |
754 | throw new NotImplementedException(); | |
755 | } | |
756 | ||
757 | static void quaff_potion() | |
758 | { | |
759 | throw new NotImplementedException(); | |
760 | } | |
761 | ||
762 | static void read_scroll() | |
763 | { | |
764 | throw new NotImplementedException(); | |
765 | } | |
766 | ||
767 | static void throw_item() | |
768 | { | |
769 | throw new NotImplementedException(); | |
770 | } | |
771 | ||
772 | static void zap_stick() | |
773 | { | |
774 | throw new NotImplementedException(); | |
775 | } | |
776 | ||
777 | static void wield_weapon() | |
778 | { | |
779 | throw new NotImplementedException(); | |
780 | } | |
781 | ||
782 | static void wear_armor() | |
783 | { | |
784 | throw new NotImplementedException(); | |
785 | } | |
786 | ||
787 | static void take_off_armor() | |
788 | { | |
789 | throw new NotImplementedException(); | |
790 | } | |
791 | ||
792 | static void put_on_ring() | |
793 | { | |
794 | throw new NotImplementedException(); | |
795 | } | |
796 | ||
797 | static void remove_ring() | |
798 | { | |
799 | throw new NotImplementedException(); | |
800 | } | |
801 | ||
802 | static void list_discoveries() | |
803 | { | |
804 | throw new NotImplementedException(); | |
805 | } | |
806 | ||
807 | #endregion // commands | |
808 | ||
809 | #region helper functions | |
810 | ||
811 | static bool is_wall(char ch) | |
812 | { | |
813 | return "-|".Contains(ch.ToString()); | |
814 | } | |
815 | ||
816 | static string get_name(char dest_ch) | |
817 | { | |
818 | switch (dest_ch) | |
819 | { | |
820 | case 'A': return "giant ant"; | |
821 | case 'B': return "bat"; | |
822 | case 'C': return "centaur"; | |
823 | case 'D': return "dragon"; | |
824 | case 'E': return "floating eye"; | |
825 | case 'F': return "violet fungi"; | |
826 | case 'G': return "gnome"; | |
827 | case 'H': return "hobgoblin"; | |
828 | case 'I': return "invisible stalker"; | |
829 | case 'J': return "jackal"; | |
830 | case 'K': return "kobold"; | |
831 | case 'L': return "leprechaun"; | |
832 | case 'M': return "mimic"; | |
833 | case 'N': return "nymph"; | |
834 | case 'O': return "orc"; | |
835 | case 'P': return "purple worm"; | |
836 | case 'Q': return "quasit"; | |
837 | case 'R': return "rust monster"; | |
838 | case 'S': return "snake"; | |
839 | case 'T': return "troll"; | |
840 | case 'U': return "umber hulk"; | |
841 | case 'V': return "vampire"; | |
842 | case 'W': return "wraith"; | |
843 | case 'X': return "xorn"; | |
844 | case 'Y': return "yeti"; | |
845 | case 'Z': return "zombie"; | |
846 | ||
847 | default: return null; | |
848 | } | |
849 | } | |
850 | ||
851 | static void update_status() | |
852 | { | |
853 | clear_status(); | |
854 | ||
855 | CONSOLE.write_string(0, 24, "level: " + dungeon_level); | |
856 | } | |
857 | ||
858 | #endregion // helper functions | |
859 | ||
860 | #region messages | |
861 | ||
862 | static string last_message = ""; | |
863 | ||
864 | static void set_message(string text) | |
865 | { | |
866 | CONSOLE.write_string(0, 0, text); | |
867 | last_message = text; | |
868 | } | |
869 | ||
870 | static void clear_message() | |
871 | { | |
872 | CONSOLE.cursor_off(); | |
873 | CONSOLE.write_string(0, 0, "".PadRight(80)); | |
874 | CONSOLE.cursor_on(); | |
875 | } | |
876 | ||
877 | static void clear_status() | |
878 | { | |
879 | CONSOLE.write_string(0, 24, "".PadRight(79)); | |
880 | } | |
881 | ||
882 | #endregion // messages | |
883 | ||
884 | #region game over | |
885 | ||
886 | static void win_game() | |
887 | { | |
888 | CONSOLE.clear(); | |
889 | ||
890 | CONSOLE.write_string("you win"); | |
891 | ||
892 | CONSOLE.read_key(); | |
893 | ||
894 | Environment.Exit(0); | |
895 | } | |
896 | ||
897 | #endregion // game over | |
898 | ||
899 | // THING must be in Program for access to dungeon_map[] | |
900 | class THING | |
901 | { | |
902 | public int x, y; | |
903 | public char ch; | |
904 | public List<ITEM> items = new List<ITEM>(); | |
905 | } | |
906 | } | |
907 | ||
908 | class ITEM | |
909 | { | |
910 | public int x; | |
911 | public int y; | |
912 | public char ch; | |
913 | public string type; | |
914 | ||
915 | public override string ToString() | |
916 | { | |
917 | return type; | |
918 | } | |
919 | } | |
920 | ||
921 | class CONSOLE | |
922 | { | |
923 | static char[,] buffer = new char[80, 25]; | |
924 | ||
925 | static int cursor_x, cursor_y; | |
926 | ||
927 | public static char get_char(int x, int y) | |
928 | { | |
929 | return buffer[x, y]; | |
930 | } | |
931 | ||
932 | public static void put_char(char ch) | |
933 | { | |
934 | buffer[cursor_x, cursor_y] = ch; | |
935 | cursor_x++; | |
936 | if (cursor_x == 80) | |
937 | { | |
938 | cursor_x = 0; | |
939 | cursor_y++; | |
940 | } | |
941 | ||
942 | Console.Write(ch); | |
943 | } | |
944 | ||
945 | public static void put_char(int x, int y, char ch) | |
946 | { | |
947 | move_cursor(x, y); | |
948 | put_char(ch); | |
949 | } | |
950 | ||
951 | public static void move_cursor(int x, int y) | |
952 | { | |
953 | cursor_x = x; | |
954 | cursor_y = y; | |
955 | ||
956 | Console.SetCursorPosition(x, y); | |
957 | } | |
958 | ||
959 | public static char read_key() | |
960 | { | |
961 | return Console.ReadKey(true).KeyChar; | |
962 | } | |
963 | ||
964 | public static void write_string(string text) | |
965 | { | |
966 | for (int c = 0; c < text.Length; c++) | |
967 | put_char(text[c]); | |
968 | } | |
969 | ||
970 | public static void write_string(int x, int y, string text) | |
971 | { | |
972 | move_cursor(x, y); | |
973 | write_string(text); | |
974 | } | |
975 | ||
976 | public static void cursor_on() | |
977 | { | |
978 | Console.CursorVisible = true; | |
979 | } | |
980 | ||
981 | public static void cursor_off() | |
982 | { | |
983 | Console.CursorVisible = false; | |
984 | } | |
985 | ||
986 | public static void clear() | |
987 | { | |
988 | for (int y = 0; y < 25; y++) | |
989 | for (int x = 0; x < 80; x++) | |
990 | buffer[x, y] = ' '; | |
991 | cursor_x = cursor_y = 0; | |
992 | ||
993 | Console.Clear(); | |
994 | } | |
995 | ||
996 | static char[,] old_buffer = new char[80, 25]; | |
997 | ||
998 | public static void back_up_buffer() | |
999 | { | |
1000 | Array.Copy(CONSOLE.buffer, old_buffer, 80 * 25); | |
1001 | } | |
1002 | ||
1003 | public static void restore_buffer() | |
1004 | { | |
1005 | Array.Copy(old_buffer, CONSOLE.buffer, 80 * 25); | |
1006 | ||
1007 | for (int y = 0; y < 25; y++) | |
1008 | for (int x = 0; x < 80; x++) | |
1009 | if (!(x == 79 && y == 24)) | |
1010 | CONSOLE.put_char(x, y, CONSOLE.buffer[x, y]); | |
1011 | } | |
1012 | } | |
1013 |