1 2(********************************************************************) 3(* *) 4(* castle.sd7 Castle Adventure *) 5(* Copyright (C) 2004, 2005 Thomas Mertes *) 6(* *) 7(* This program is free software; you can redistribute it and/or *) 8(* modify it under the terms of the GNU General Public License as *) 9(* published by the Free Software Foundation; either version 2 of *) 10(* the License, or (at your option) any later version. *) 11(* *) 12(* This program is distributed in the hope that it will be useful, *) 13(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 14(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 15(* GNU General Public License for more details. *) 16(* *) 17(* You should have received a copy of the GNU General Public *) 18(* License along with this program; if not, write to the *) 19(* Free Software Foundation, Inc., 51 Franklin Street, *) 20(* Fifth Floor, Boston, MA 02110-1301, USA. *) 21(* *) 22(********************************************************************) 23 24 25$ include "seed7_05.s7i"; 26 include "osfiles.s7i"; 27 include "float.s7i"; 28 include "draw.s7i"; 29 include "keybd.s7i"; 30 include "dialog.s7i"; 31 include "pic32.s7i"; 32 include "time.s7i"; 33 include "duration.s7i"; 34 35 36const integer: ROOM_LINES is 18; 37const integer: ROOM_COLUMNS is 24; 38 39const integer: INVENTORY_LINE is 16; 40 41const integer: MAX_STRENGTH is 200; 42 43const integer: MAX_INVENTORY is 6; 44const integer: PIXMAP_SIZE is 32; 45const integer: STEP_SIZE is 16; 46const integer: BORDER_DIST is 20; 47const integer: LEGEND_XPOS is 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE + 16; 48const integer: LEGEND_YPOS_MIN is 8; 49const integer: LEGEND_COLUMN is (LEGEND_XPOS + PIXMAP_SIZE) div 6 + 3; 50const integer: BUTTONS_1_XPOS is LEGEND_XPOS - 3 * 96; 51const integer: BUTTONS_2_XPOS is LEGEND_XPOS - 2 * 96; 52const integer: BUTTONS_3_XPOS is LEGEND_XPOS - 96; 53const integer: BUTTONS_1_COLUMN is (BUTTONS_1_XPOS + PIXMAP_SIZE) div 6 + 3; 54const integer: BUTTONS_2_COLUMN is (BUTTONS_2_XPOS + PIXMAP_SIZE) div 6 + 3; 55const integer: BUTTONS_3_COLUMN is (BUTTONS_3_XPOS + PIXMAP_SIZE) div 6 + 3; 56const integer: BUTTON_YPOS_MIN is 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE + 16; 57const integer: BUTTON_TEXT_LINE1 is BUTTON_YPOS_MIN div 16 + 2; 58 59const type: directionType is new enum 60 NORTH, SOUTH, EAST, WEST, UP, DOWN 61 end enum; 62 63const func string: str (in directionType: direction) is 64 return str(ord(direction)); 65 66const func directionType: (attr directionType) parse (in string: stri) is 67 return directionType conv (integer(stri)); 68 69enable_io(directionType); 70 71 72const type: itemType is new enum 73 NO_ITEM, BOOK, CRYSTAL_BALL, GLASSES, HELMET, 74 KEY, LAMP, MAGIC_WAND, SWORD, WINE_FLASK, 75 CROWN, DIAMOND, FANCY_GOBLET, GOLDBAR, HARP, 76 HOLY_CROSS, HOURGLASS, JADE_FIGURINE, LARGE_GEM, 77 NECKLACE, RUBYS, SCEPTER, SILVER_BARS 78 end enum; 79 80const itemType: MIN_ITEM is succ(itemType.first); 81const itemType: MAX_ITEM is itemType.last; 82 83 84const type: monsterType is new enum 85 NO_MONSTER, ANGRY_DEMON1, ANGRY_DEMON2, 86 UGLY_OGRE1, UGLY_OGRE2, BIG_SPIDER, 87 SMALL_SPIDER, SNAKE, BAT, VAMPIRE, 88 FAIRY1, FAIRY2, DOOR1, DOOR2, DOOR3, DOOR4 89 end enum; 90 91const monsterType: MIN_MONSTER is succ(monsterType.first); 92const monsterType: MAX_MONSTER is monsterType.last; 93 94 95(* Rooms *) 96const integer: NO_ROOM is 0; 97const integer: COURTYARD is 1; 98const integer: WEST_BALLROOM is 4; 99const integer: WEST_DINING_ROOM is 8; 100const integer: KITCHEN is 9; 101const integer: CHEFS_QUARTERS is 10; 102const integer: STORAGE_ROOM is 11; 103const integer: MUSEUM is 12; 104const integer: THRONE_ROOM is 14; 105const integer: GARDEN_NORTH is 17; 106const integer: GARDEN_SOUTH is 18; 107const integer: UPPER_HALL_CENTER is 19; 108const integer: UPPER_HALL_WEST is 20; 109const integer: UPPER_HALL_EAST is 21; 110const integer: GUARDS_HALL is 22; 111const integer: KNIGHTS_HALL is 24; 112const integer: LOWER_BATTLEMENT is 26; 113const integer: CORRIDOR28 is 28; 114const integer: GUEST_ROOM is 29; 115const integer: BALCONY is 33; 116const integer: RED_ROOM is 37; 117const integer: YELLOW_ROOM is 40; 118const integer: CORRIDOR52 is 52; 119const integer: CORRIDOR54 is 54; 120const integer: KINGS_STUDY is 56; 121const integer: EMPTY_ROOM is 57; 122const integer: LIBRARY_WEST_END is 58; 123const integer: LIBRARY_EAST_END is 59; 124const integer: CASTLE_WALL is 60; 125const integer: WEST_TOWER_MIDDLE is 62; 126const integer: EAST_TOWER_TOP is 65; 127const integer: LABORATORY is 66; 128const integer: SORCERERS_QUARTERS is 67; 129const integer: WINE_CELLAR is 68; 130const integer: MAZE70 is 70; 131const integer: MAZE73 is 73; 132const integer: MAZE74 is 74; 133const integer: WINDING_PASSAGE1 is 76; 134const integer: WINDING_PASSAGE2 is 77; 135const integer: WINDING_PASSAGE3 is 78; 136const integer: TORTURE_ROOM is 79; 137const integer: DUNGEON_ENTRANCE is 82; 138const integer: SECRET_ROOM is 83; 139const integer: ESCAPED is 84; 140const integer: CASTLE is 85; 141const integer: MAX_ROOM is 85; 142 143 144const type: itemSet is set of itemType; 145 146const func string: str (in itemSet: aSet) is 147 return str(bitset conv aSet); 148 149const func itemSet: (attr itemSet) parse (in string: stri) is 150 return itemSet conv (bitset(stri)); 151 152enable_io(itemSet); 153 154 155const type: graphObj is new struct 156 var string: name is ""; 157 var string: adjective is ""; 158 var array string: picture is 0 times ""; 159 var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value; 160 var integer: xPos is 0; 161 var integer: yPos is 0; 162 var PRIMITIVE_WINDOW: saved_pixmap is PRIMITIVE_WINDOW.value; 163 var integer: saved_xPos is 0; 164 var integer: saved_yPos is 0; 165 end struct; 166 167const type: itemObj is sub graphObj struct 168 var itemType: ident is NO_ITEM; 169 var integer: room_num is 0; 170 end struct; 171 172const type: monsterObj is sub graphObj struct 173 var monsterType: ident is NO_MONSTER; 174 var integer: attack is 0; 175 var integer: strength is 0; 176 var integer: room_num is 0; 177 var directionType: direction is NORTH; 178 var boolean: living is FALSE; 179 end struct; 180 181const type: playerObj is sub graphObj struct 182 var integer: room is 0; 183 var directionType: direction is NORTH; 184 var itemSet: inventory is itemSet.EMPTY_SET; 185 var integer: strength is 0; 186 var boolean: living is TRUE; 187 end struct; 188 189const type: roomType is new struct 190 var array string: data is ROOM_LINES times ""; 191 var array string: description is 5 times ""; 192 var array [directionType] integer: exits is directionType times 0; 193 end struct; 194 195const type: scoreType is new struct 196 var string: name is ""; 197 var integer: points is 0; 198 end struct; 199 200 201var text: screen is STD_NULL; 202var array [itemType] itemObj: item is itemType times itemObj.value; 203var array [monsterType] monsterObj: monster is monsterType times monsterObj.value; 204var playerObj: player is playerObj.value; 205var array roomType: room is MAX_ROOM times roomType.value; 206var scoreType: highScore is scoreType.value; 207var graphObj: stair_up is graphObj.value; 208var graphObj: stair_down is graphObj.value; 209 210var array string: message is 0 times ""; 211var boolean: flaskFilled is FALSE; 212var boolean: exitGame is FALSE; 213 214var PRIMITIVE_WINDOW: query_pixmap is PRIMITIVE_WINDOW.value; 215var PRIMITIVE_WINDOW: wall_pixmap is PRIMITIVE_WINDOW.value; 216var PRIMITIVE_WINDOW: colored_wall1_pixmap is PRIMITIVE_WINDOW.value; 217var PRIMITIVE_WINDOW: colored_wall2_pixmap is PRIMITIVE_WINDOW.value; 218var PRIMITIVE_WINDOW: vertical_pixmap is PRIMITIVE_WINDOW.value; 219var PRIMITIVE_WINDOW: horizontal_pixmap is PRIMITIVE_WINDOW.value; 220var PRIMITIVE_WINDOW: left_upper_pixmap is PRIMITIVE_WINDOW.value; 221var PRIMITIVE_WINDOW: right_upper_pixmap is PRIMITIVE_WINDOW.value; 222var PRIMITIVE_WINDOW: left_lower_pixmap is PRIMITIVE_WINDOW.value; 223var PRIMITIVE_WINDOW: right_lower_pixmap is PRIMITIVE_WINDOW.value; 224var PRIMITIVE_WINDOW: railing_pixmap is PRIMITIVE_WINDOW.value; 225var PRIMITIVE_WINDOW: gate_pixmap is PRIMITIVE_WINDOW.value; 226var PRIMITIVE_WINDOW: small_bush_pixmap is PRIMITIVE_WINDOW.value; 227var PRIMITIVE_WINDOW: big_bush_pixmap is PRIMITIVE_WINDOW.value; 228var PRIMITIVE_WINDOW: statue_pixmap is PRIMITIVE_WINDOW.value; 229var PRIMITIVE_WINDOW: fountain_pixmap is PRIMITIVE_WINDOW.value; 230var PRIMITIVE_WINDOW: wood_pixmap is PRIMITIVE_WINDOW.value; 231var PRIMITIVE_WINDOW: stone_pixmap is PRIMITIVE_WINDOW.value; 232var PRIMITIVE_WINDOW: gray_pixmap is PRIMITIVE_WINDOW.value; 233var PRIMITIVE_WINDOW: water_pixmap is PRIMITIVE_WINDOW.value; 234var PRIMITIVE_WINDOW: bed_left_pixmap is PRIMITIVE_WINDOW.value; 235var PRIMITIVE_WINDOW: bed_right_pixmap is PRIMITIVE_WINDOW.value; 236var PRIMITIVE_WINDOW: bed_top_pixmap is PRIMITIVE_WINDOW.value; 237var PRIMITIVE_WINDOW: bed_bottom_pixmap is PRIMITIVE_WINDOW.value; 238var PRIMITIVE_WINDOW: bed_white_middle_pixmap is PRIMITIVE_WINDOW.value; 239var PRIMITIVE_WINDOW: bed_red_middle_pixmap is PRIMITIVE_WINDOW.value; 240var PRIMITIVE_WINDOW: bed_blue_middle_pixmap is PRIMITIVE_WINDOW.value; 241var PRIMITIVE_WINDOW: bed_purple_middle_pixmap is PRIMITIVE_WINDOW.value; 242var PRIMITIVE_WINDOW: bed_yellow_middle_pixmap is PRIMITIVE_WINDOW.value; 243var PRIMITIVE_WINDOW: chain_pixmap is PRIMITIVE_WINDOW.value; 244var PRIMITIVE_WINDOW: k_pixmap is PRIMITIVE_WINDOW.value; 245var PRIMITIVE_WINDOW: b_pixmap is PRIMITIVE_WINDOW.value; 246var PRIMITIVE_WINDOW: floor_pixmap is PRIMITIVE_WINDOW.value; 247var PRIMITIVE_WINDOW: eye_pixmap is PRIMITIVE_WINDOW.value; 248var PRIMITIVE_WINDOW: hand_pixmap is PRIMITIVE_WINDOW.value; 249var PRIMITIVE_WINDOW: take_pixmap is PRIMITIVE_WINDOW.value; 250var PRIMITIVE_WINDOW: drop_pixmap is PRIMITIVE_WINDOW.value; 251var PRIMITIVE_WINDOW: load_pixmap is PRIMITIVE_WINDOW.value; 252var PRIMITIVE_WINDOW: save_pixmap is PRIMITIVE_WINDOW.value; 253var PRIMITIVE_WINDOW: exit_pixmap is PRIMITIVE_WINDOW.value; 254 255 256const array string: query_pic is []( 257 " WWWW ", 258 " W W ", 259 " W W ", 260 " WW ", 261 " WW ", 262 " WW ", 263 " ", 264 " WW "); 265 266 267const array string: wall_pic is []( 268 "WBBBBBBBWBBBBBBB", 269 "WBBBBBBBWBBBBBBB", 270 "WBBBBBBBWBBBBBBB", 271 "WWWWWWWWWWWWWWWW", 272 "RRRRWRRRRRRRWRRR", 273 "RRRRWRRRRRRRWRRR", 274 "RRRRWRRRRRRRWRRR", 275 "WWWWWWWWWWWWWWWW", 276 "WBBBBBBBWBBBBBBB", 277 "WBBBBBBBWBBBBBBB", 278 "WBBBBBBBWBBBBBBB", 279 "WWWWWWWWWWWWWWWW", 280 "RRRRWRRRRRRRWRRR", 281 "RRRRWRRRRRRRWRRR", 282 "RRRRWRRRRRRRWRRR", 283 "WWWWWWWWWWWWWWWW"); 284 285 286const array string: colored_wall1_pic is []( 287 "WGGGGGGGWMMMMMMM", 288 "WGGGGGGGWMMMMMMM", 289 "WGGGGGGGWMMMMMMM", 290 "WWWWWWWWWWWWWWWW", 291 "RRRRWmmmmmmmWBBB", 292 "RRRRWmmmmmmmWBBB", 293 "RRRRWmmmmmmmWBBB", 294 "WWWWWWWWWWWWWWWW", 295 "WgggggggWOOOOOOO", 296 "WgggggggWOOOOOOO", 297 "WgggggggWOOOOOOO", 298 "WWWWWWWWWWWWWWWW", 299 "YYYYWbbbbbbbWBBB", 300 "YYYYWbbbbbbbWBBB", 301 "YYYYWbbbbbbbWBBB", 302 "WWWWWWWWWWWWWWWW"); 303 304 305const array string: colored_wall2_pic is []( 306 "WgggggggWOOOOOOO", 307 "WgggggggWOOOOOOO", 308 "WgggggggWOOOOOOO", 309 "WWWWWWWWWWWWWWWW", 310 "BBBBWbbbbbbbWRRR", 311 "BBBBWbbbbbbbWRRR", 312 "BBBBWbbbbbbbWRRR", 313 "WWWWWWWWWWWWWWWW", 314 "WGGGGGGGWMMMMMMM", 315 "WGGGGGGGWMMMMMMM", 316 "WGGGGGGGWMMMMMMM", 317 "WWWWWWWWWWWWWWWW", 318 "BBBBWrrrrrrrWYYY", 319 "BBBBWrrrrrrrWYYY", 320 "BBBBWrrrrrrrWYYY", 321 "WWWWWWWWWWWWWWWW"); 322 323 324const array string: vertical_pic is []( 325 " WW ", 326 " WW ", 327 " WW ", 328 " WW ", 329 " WW ", 330 " WW ", 331 " WW ", 332 " WW ", 333 " WW ", 334 " WW ", 335 " WW ", 336 " WW ", 337 " WW ", 338 " WW ", 339 " WW ", 340 " WW "); 341 342 343const array string: horizontal_pic is []( 344 " ", 345 " ", 346 " ", 347 " ", 348 " ", 349 " ", 350 " ", 351 "WWWWWWWWWWWWWWWW", 352 "WWWWWWWWWWWWWWWW", 353 " ", 354 " ", 355 " ", 356 " ", 357 " ", 358 " ", 359 " "); 360 361 362const array string: left_upper_pic is []( 363 " ", 364 " ", 365 " ", 366 " ", 367 " ", 368 " ", 369 " ", 370 " WWWWWWWWW", 371 " WWWWWWWWW", 372 " WW ", 373 " WW ", 374 " WW ", 375 " WW ", 376 " WW ", 377 " WW ", 378 " WW "); 379 380 381const array string: right_upper_pic is []( 382 " ", 383 " ", 384 " ", 385 " ", 386 " ", 387 " ", 388 " ", 389 "WWWWWWWWW ", 390 "WWWWWWWWW ", 391 " WW ", 392 " WW ", 393 " WW ", 394 " WW ", 395 " WW ", 396 " WW ", 397 " WW "); 398 399 400const array string: left_lower_pic is []( 401 " WW ", 402 " WW ", 403 " WW ", 404 " WW ", 405 " WW ", 406 " WW ", 407 " WW ", 408 " WWWWWWWWW", 409 " WWWWWWWWW", 410 " ", 411 " ", 412 " ", 413 " ", 414 " ", 415 " ", 416 " "); 417 418 419const array string: right_lower_pic is []( 420 " WW ", 421 " WW ", 422 " WW ", 423 " WW ", 424 " WW ", 425 " WW ", 426 " WW ", 427 "WWWWWWWWW ", 428 "WWWWWWWWW ", 429 " ", 430 " ", 431 " ", 432 " ", 433 " ", 434 " ", 435 " "); 436 437 438const array string: railing_pic is []( 439 " WW ", 440 " WW ", 441 " WW ", 442 " WW ", 443 " WW ", 444 " WW ", 445 " WW ", 446 " WWWWWWWWW", 447 " WWWWWWWWW", 448 " WW ", 449 " WW ", 450 " WW ", 451 " WW ", 452 " WW ", 453 " WW ", 454 " WW "); 455 456 457const array string: gate_pic is []( 458 " ", 459 " ", 460 " ", 461 " ", 462 " ", 463 " bbbbbbbbbbbbbb ", 464 "bbbbbrrrrrbbbrrr", 465 "brrrrbbbbbrrrbbb", 466 "bbbbbbrrrbbbbbbb", 467 "rrrrrrbbbrrrrrbb", 468 " bbbbbbbbbbbbbb ", 469 " ", 470 " ", 471 " ", 472 " ", 473 " "); 474 475 476const array string: small_bush_pic is []( 477 " G GG ", 478 " G GG GG G ", 479 " G G G G G ", 480 " GGGG GG G GGG ", 481 " GG GGG ", 482 " GGG G G GG ", 483 " GGG GG GG GGG", 484 " G G GG G G ", 485 " G GG G GG G G", 486 "GG GG Gg g GG ", 487 " G g g g G ", 488 "GGG g ggGG GGGG", 489 " g gg g ", 490 " g g gGG ", 491 " g g g ", 492 " ggg "); 493 494 495const array string: big_bush_pic is []( 496 " G G GG GG ", 497 " GG GG gG GG ", 498 " G g gGg G gG ", 499 " GGgg gg g ggGG", 500 "GG gg ggg ", 501 " GgGG Gg gG GgG", 502 " ggG gg gg ggG", 503 "GG g gg g g ", 504 "GgG gg gG gg G G", 505 "Gg gg gb bG gG ", 506 " g b b b g ", 507 "GggG b bbgG ggGG", 508 " b bb b ", 509 " GGb b bgGG ", 510 " b b b ", 511 " bbb "); 512 513 514const array string: wood_pic is []( 515 "bbbbbbbbbbbbbbrr", 516 "rrbbbbbrrrrbbbbb", 517 "bbrrrrrbbbbrrrbb", 518 "bbbbbbbbbbbbbbbb", 519 "rrrbbbbbbbbbbbbb", 520 "bbbrrbbbbrrrrrrb", 521 "bbbbbrrrrrbbbbbb", 522 "bbbbbbbbbbbbrrrr", 523 "rrrrbbbbbrrrbbbb", 524 "bbbbrrrrrbbbbbbb", 525 "bbbbbbbbbbbbbrrr", 526 "rrbbbbbbrrrrrbbb", 527 "bbbbbbbbbbbbbbbb", 528 "bbbrrrrbbbbbrrrb", 529 "rrrbbbbrrrrrbbbb", 530 "bbbbbbbbbbbbbbbb"); 531 532 533const array string: stone_pic is []( 534 "xxxxxxxxxWxxxxxx", 535 "xxxxxxxxxWxxxxxx", 536 "xxxxxxxxxWxxxxxx", 537 "xxxxxxxxxWxxxxxx", 538 "WWWWWWWWWWWWWWWW", 539 "xxxWxxxxxxxxxxxx", 540 "xxxWxxxxxxxxxxxx", 541 "xxxWxxxxxxxxxxxx", 542 "xxxWxxxxxxxxxxxx", 543 "xxxWxxxxxxxxxxxx", 544 "WWWWWWWWWWWWWWWW", 545 "xxxxxxxxxxxxWxxx", 546 "xxxxxxxxxxxxWxxx", 547 "xxxxxxxxxxxxWxxx", 548 "xxxxxxxxxxxxWxxx", 549 "WWWWWWWWWWWWWWWW"); 550 551 552const array string: gray_pic is []( 553 "xxxxxxxxxxxxxxxx", 554 "xxxxxxxxxxxxxxxx", 555 "xxxxxxxxxxxxxxxx", 556 "xxxxxxxxxxxxxxxx", 557 "xxxxxxxxxxxxxxxx", 558 "xxxxxxxxxxxxxxxx", 559 "xxxxxxxxxxxxxxxx", 560 "xxxxxxxxxxxxxxxx", 561 "xxxxxxxxxxxxxxxx", 562 "xxxxxxxxxxxxxxxx", 563 "xxxxxxxxxxxxxxxx", 564 "xxxxxxxxxxxxxxxx", 565 "xxxxxxxxxxxxxxxx", 566 "xxxxxxxxxxxxxxxx", 567 "xxxxxxxxxxxxxxxx", 568 "xxxxxxxxxxxxxxxx"); 569 570 571const array string: water_pic is []( 572 "BBBBBBBBBBBBBBBB", 573 "BBBBBBBBBBBBBBBB", 574 "BBBBBBBBBBBBBBBB", 575 "BBBBBBBBBBBBBBBB", 576 "BBBBBBBBBBBBBBBB", 577 "BBBBBBBBBBBBBBBB", 578 "BBBBBBBBBBBBBBBB", 579 "BBBBBBBBBBBBBBBB", 580 "BBBBBBBBBBBBBBBB", 581 "BBBBBBBBBBBBBBBB", 582 "BBBBBBBBBBBBBBBB", 583 "BBBBBBBBBBBBBBBB", 584 "BBBBBBBBBBBBBBBB", 585 "BBBBBBBBBBBBBBBB", 586 "BBBBBBBBBBBBBBBB", 587 "BBBBBBBBBBBBBBBB"); 588 589 590const array string: bed_left_pic is []( 591 " bbbb", 592 " bbbb", 593 " bbbb", 594 " bbbb", 595 " bb ", 596 " bb ", 597 " bb ", 598 " bb ", 599 " bb ", 600 " bb ", 601 " bb ", 602 " bb ", 603 " bbbb", 604 " bbbb", 605 " bbbb", 606 " bbbb"); 607 608 609const array string: bed_right_pic is []( 610 "bbbb ", 611 "bbbb ", 612 "bbbb ", 613 "bbbb ", 614 " bb ", 615 " bb ", 616 " bb ", 617 " bb ", 618 " bb ", 619 " bb ", 620 " bb ", 621 " bb ", 622 "bbbb ", 623 "bbbb ", 624 "bbbb ", 625 "bbbb "); 626 627 628const array string: bed_top_pic is []( 629 " ", 630 " ", 631 " ", 632 " ", 633 " ", 634 " ", 635 " ", 636 " ", 637 " ", 638 " ", 639 " ", 640 " ", 641 "bbbb bbbb", 642 "bbbbbbbbbbbbbbbb", 643 "bbbbbbbbbbbbbbbb", 644 "bbbb bbbb"); 645 646 647const array string: bed_bottom_pic is []( 648 "bbbb bbbb", 649 "bbbbbbbbbbbbbbbb", 650 "bbbbbbbbbbbbbbbb", 651 "bbbb bbbb", 652 " ", 653 " ", 654 " ", 655 " ", 656 " ", 657 " ", 658 " ", 659 " ", 660 " ", 661 " ", 662 " ", 663 " "); 664 665 666const array string: bed_white_middle_pic is []( 667 "WWWWWWWWWWWWWWWW", 668 "WWWWWWWWWWWWWWWW", 669 "WWWWWWWWWWWWWWWW", 670 "WWWWWWWWWWWWWWWW", 671 "WWWWWWWWWWWWWWWW", 672 "WWWWWWWWWWWWWWWW", 673 "WWWWWWWWWWWWWWWW", 674 "WWWWWWWWWWWWWWWW", 675 "WWWWWWWWWWWWWWWW", 676 "WWWWWWWWWWWWWWWW", 677 "WWWWWWWWWWWWWWWW", 678 "WWWWWWWWWWWWWWWW", 679 "WWWWWWWWWWWWWWWW", 680 "WWWWWWWWWWWWWWWW", 681 "WWWWWWWWWWWWWWWW", 682 "WWWWWWWWWWWWWWWW"); 683 684 685const array string: bed_red_middle_pic is []( 686 "RRRRRRRRRRRRRRRR", 687 "RRRRRRRRRRRRRRRR", 688 "RRRRRRRRRRRRRRRR", 689 "RRRRRRRRRRRRRRRR", 690 "RRRRRRRRRRRRRRRR", 691 "RRRRRRRRRRRRRRRR", 692 "RRRRRRRRRRRRRRRR", 693 "RRRRRRRRRRRRRRRR", 694 "RRRRRRRRRRRRRRRR", 695 "RRRRRRRRRRRRRRRR", 696 "RRRRRRRRRRRRRRRR", 697 "RRRRRRRRRRRRRRRR", 698 "RRRRRRRRRRRRRRRR", 699 "RRRRRRRRRRRRRRRR", 700 "RRRRRRRRRRRRRRRR", 701 "RRRRRRRRRRRRRRRR"); 702 703 704const array string: bed_blue_middle_pic is []( 705 "BBBBBBBBBBBBBBBB", 706 "BBBBBBBBBBBBBBBB", 707 "BBBBBBBBBBBBBBBB", 708 "BBBBBBBBBBBBBBBB", 709 "BBBBBBBBBBBBBBBB", 710 "BBBBBBBBBBBBBBBB", 711 "BBBBBBBBBBBBBBBB", 712 "BBBBBBBBBBBBBBBB", 713 "BBBBBBBBBBBBBBBB", 714 "BBBBBBBBBBBBBBBB", 715 "BBBBBBBBBBBBBBBB", 716 "BBBBBBBBBBBBBBBB", 717 "BBBBBBBBBBBBBBBB", 718 "BBBBBBBBBBBBBBBB", 719 "BBBBBBBBBBBBBBBB", 720 "BBBBBBBBBBBBBBBB"); 721 722 723const array string: bed_purple_middle_pic is []( 724 "mmmmmmmmmmmmmmmm", 725 "mmmmmmmmmmmmmmmm", 726 "mmmmmmmmmmmmmmmm", 727 "mmmmmmmmmmmmmmmm", 728 "mmmmmmmmmmmmmmmm", 729 "mmmmmmmmmmmmmmmm", 730 "mmmmmmmmmmmmmmmm", 731 "mmmmmmmmmmmmmmmm", 732 "mmmmmmmmmmmmmmmm", 733 "mmmmmmmmmmmmmmmm", 734 "mmmmmmmmmmmmmmmm", 735 "mmmmmmmmmmmmmmmm", 736 "mmmmmmmmmmmmmmmm", 737 "mmmmmmmmmmmmmmmm", 738 "mmmmmmmmmmmmmmmm", 739 "mmmmmmmmmmmmmmmm"); 740 741 742const array string: bed_yellow_middle_pic is []( 743 "YYYYYYYYYYYYYYYY", 744 "YYYYYYYYYYYYYYYY", 745 "YYYYYYYYYYYYYYYY", 746 "YYYYYYYYYYYYYYYY", 747 "YYYYYYYYYYYYYYYY", 748 "YYYYYYYYYYYYYYYY", 749 "YYYYYYYYYYYYYYYY", 750 "YYYYYYYYYYYYYYYY", 751 "YYYYYYYYYYYYYYYY", 752 "YYYYYYYYYYYYYYYY", 753 "YYYYYYYYYYYYYYYY", 754 "YYYYYYYYYYYYYYYY", 755 "YYYYYYYYYYYYYYYY", 756 "YYYYYYYYYYYYYYYY", 757 "YYYYYYYYYYYYYYYY", 758 "YYYYYYYYYYYYYYYY"); 759 760 761const array string: chain_pic is []( 762 " BBB BB", 763 " B B B ", 764 " B BBBBB ", 765 " BB B B ", 766 " BBBB BB", 767 " BB ", 768 " BBB ", 769 " B B B ", 770 " B B ", 771 " B B B ", 772 " BBB ", 773 " BBBBB BB", 774 " BB B B ", 775 " B BBBBB ", 776 " B B B ", 777 " BBB BB"); 778 779 780const array string: k_pic is []( 781 " WW ", 782 " W ", 783 " W ", 784 " W WW ", 785 " W WW ", 786 " WWW ", 787 " W WW ", 788 " WW WW "); 789 790 791const array string: b_pic is []( 792 " WW ", 793 " W ", 794 " W ", 795 " WWWW ", 796 " W W ", 797 " W W ", 798 " W W ", 799 " W WWW "); 800 801 802const array string: up_pic is []( 803 " WddW ", 804 " WdddW ", 805 " WddddW ", 806 " WWWWWWWdddddW ", 807 " WW WdddddW ", 808 " WdW WdddddW ", 809 " WddW WdddddW ", 810 " WdddW WdddddWWWW", 811 " WddddW WddddW ", 812 " WWWWWWWdddddW WdddW ", 813 " WW WdddddW WddW ", 814 " WdW WdddddW WdW ", 815 " WddW WdddddW WW ", 816 " WdddW WdddddWWWWWWW ", 817 " WddddW WddddW ", 818 "WWWWWWWdddddW WdddW W", 819 "WW WdddddW WddW W ", 820 "WdW WdddddW WdW W ", 821 "WddW WdddddW WW W ", 822 "WdddW WdddddWWWWWWW W ", 823 "WddddW WddddW W ", 824 "WdddddW WdddW W ", 825 " WdddddW WddW W ", 826 " WdddddW WdW W ", 827 " WdddddW WW W ", 828 " WdddddWWWWWWW W ", 829 " WddddW W ", 830 " WdddW W ", 831 " WddW W ", 832 " WdW W ", 833 " WW W ", 834 " WWWWWW "); 835 836 837const array string: down_pic is []( 838 " WWWWWWWWWWWWWWWWWWWWW", 839 " WW ", 840 " WdW ", 841 " WddW ", 842 " WdddW W ", 843 " WddddW W ", 844 " WdddddWWWWWWW W ", 845 " WdddddW WW W W ", 846 " WdddddW WdW W W ", 847 " WdddddW WddW W W ", 848 " WdddddW WdddW WW ", 849 "WdddddW WddddW WWWWW ", 850 "WddddW WdddddWWWWWWW ", 851 "WdddW WdddddW WW ", 852 "WddW WdddddW WdW ", 853 "WdW WdddddW WddW ", 854 "WW WdddddW WdddW ", 855 "WWWWWWWdddddW WddddW ", 856 " WddddW WdddddWWWWWWW ", 857 " WdddW WdddddW WW ", 858 " WddW WdddddW WdW ", 859 " WdW WdddddW WddW ", 860 " WW WdddddW WdddW ", 861 " WWWWWWWdddddW WddddW ", 862 " WddddW WdddddWWW", 863 " WdddW WdddddW ", 864 " WddW WdddddW ", 865 " WdW WdddddW ", 866 " WW WdddddW ", 867 " WWWWWWWdddddW ", 868 " WddddW ", 869 " WdddW "); 870 871 872const array string: big_spider_pic is []( 873 " B B ", 874 " B B ", 875 " B B ", 876 " B B ", 877 " B B ", 878 "BBB B B BBB", 879 " BBBWWWWBBB ", 880 " WWWWWW ", 881 " WWWWWW ", 882 " BBBWWWWBBB ", 883 "BBB B B BBB", 884 " B B ", 885 " B B ", 886 " B B ", 887 " B B ", 888 " B B "); 889 890 891const array string: small_spider_pic is []( 892 " ", 893 " B B ", 894 " B B ", 895 " B B ", 896 " B B ", 897 " BBB B B BBB ", 898 " BBBWWBBB ", 899 " WWWW ", 900 " BBBWWBBB ", 901 " BBB B B BBB ", 902 " B B ", 903 " B B ", 904 " B B ", 905 " B B ", 906 " ", 907 " "); 908 909 910const array string: fairy_pic is []( 911 " xxxx YYYYY xxxx ", 912 " xxccxx YYYYYYY xxccxx", 913 " xccccxx YYWWWWWYY xxccccx", 914 " xcccccxx YYWBWBWYY xxcccccx", 915 " xxcccccxx YYWWWWWYY xxcccccxx", 916 " xccccccxx YYWOWOWYY xxccccccx ", 917 " xxccBcBccxx XWWOWWX xxcccccccxx", 918 " xcccccccccxxXXWWWXXxxcccccccccx", 919 " xccBcWcBcccWWWWWWWWWccccccccccx", 920 " xxcccRccccWWRRWWWRRWWccccccccxx", 921 " xccBRBccWWRRRRWRRRRWWcccccccx ", 922 " xxcccRccWWWRRRRWRRRRWWWccccccxx", 923 " xccccRcWWWcxRRWWWRRxcWWWccccccx", 924 " xccccRWWWcxxXWWWWWXxxcWWWWccccx", 925 " xxccWWWWcxx XWWYWWX xxcWWWWccxx", 926 " xccWWWcxx XWWWWWWWX xxcWWWccx ", 927 " xxcccccxx XRRRRRRRRRX xxcccccxx", 928 " xcccccxx XWWRRRRRWWX xxcccccx", 929 " xccccxx XWWWRRRWWWX xxccccx", 930 " xxccxx XWWWWRWWWWX xxccxx", 931 " xxxx XWWWXWWWX xxxx ", 932 " XWWWXWWWX ", 933 " XWWWXWWWX ", 934 " XWWWXWWWX ", 935 " XWWXWWX ", 936 " XWWXWWX ", 937 " XWWXWWX ", 938 " XWWXWWX ", 939 " XWWXWWX ", 940 " XWWXWWX ", 941 " XWWXWWX ", 942 " XWWWXWWWX "); 943 944 945const array string: large_gem_pic is []( 946 " ", 947 " RRRR RRRR ", 948 " RrrrrR RrrrrR ", 949 "RrrrrrrRRrrrrrrR", 950 "RrrrrrrrrrrrrrrR", 951 "RrrrrrrrrrrrrrrR", 952 "RrrrrrrrrrrrrrrR", 953 "RrrrrrrrrrrrrrrR", 954 " RrrrrrrrrrrrrR ", 955 " RrrrrrrrrrrR ", 956 " RrrrrrrrrR ", 957 " RrrrrrrR ", 958 " RrrrrR ", 959 " RrrR ", 960 " RR ", 961 " "); 962 963 964const array string: floor_pic is []( 965 " ", 966 " ", 967 " ", 968 " ", 969 " ", 970 " ", 971 " ", 972 " "); 973 974 975const array string: player_pic is []( 976 " bbbb ", 977 " bbbbbb ", 978 " bBOOBb ", 979 " OOOOOO ", 980 " OWWWWO ", 981 " OOOO ", 982 " xbbbbbbbbx ", 983 " xxbbbbbbbbxx ", 984 " xx bbbbbbbb xx ", 985 "Ox bbbbbbbb xO", 986 "OO bbbbbbbb OO", 987 " YY YY ", 988 " YY YY ", 989 " YY YY ", 990 " YY YY ", 991 " rrrr rrrr "); 992 993 994const func PRIMITIVE_WINDOW: createPixmap (in array string: pattern) is 995 return createPixmap(pattern, PIXMAP_SIZE div length(pattern), black); 996 997 998const proc: initRoomData is func 999 local 1000 var file: dat_file is STD_NULL; 1001 var integer: number is 0; 1002 var integer: line is 0; 1003 var directionType: direction is NORTH; 1004 begin 1005 dat_file := open(dir(PROGRAM) & "/castle.dat", "r"); 1006 for number range 1 to MAX_ROOM do 1007 for line range 1 to ROOM_LINES do 1008 room[number].data[line] := getln(dat_file); 1009 end for; 1010 for line range 1 to 5 do 1011 room[number].description[line] := getln(dat_file); 1012 end for; 1013 for direction range NORTH to DOWN do 1014 read(dat_file, room[number].exits[direction]); 1015 end for; 1016 end for; 1017 close(dat_file); 1018 end func; 1019 1020 1021const proc: initMonster ( 1022 in monsterType: monster_ident, 1023 in string: monster_adjective, 1024 in string: monster_name, 1025 in array string: monster_pic, 1026 in integer: monster_line, 1027 in integer: monster_column, 1028 in integer: monster_attack, 1029 in integer: monster_strength, 1030 in integer: monster_room_num) is func 1031 begin 1032 monster[monster_ident].ident := monster_ident; 1033 monster[monster_ident].adjective := monster_adjective; 1034 monster[monster_ident].name := monster_name; 1035 monster[monster_ident].picture := monster_pic; 1036 monster[monster_ident].pixmap := PRIMITIVE_WINDOW.value; 1037 monster[monster_ident].yPos := pred(monster_line) * PIXMAP_SIZE; 1038 monster[monster_ident].xPos := pred(monster_column) * PIXMAP_SIZE; 1039 monster[monster_ident].attack := monster_attack; 1040 monster[monster_ident].strength := monster_strength; 1041 monster[monster_ident].room_num := monster_room_num; 1042 monster[monster_ident].direction := NORTH; 1043 monster[monster_ident].living := TRUE; 1044 end func; 1045 1046 1047const proc: initMonsterData is func 1048 begin 1049 initMonster(ANGRY_DEMON1, "Angry", "Demon", demon_pic, 7, 13, 5, 160, THRONE_ROOM); 1050 initMonster(ANGRY_DEMON2, "Angry", "Demon", demon_pic, 10, 6, 5, 160, KNIGHTS_HALL); 1051 initMonster(UGLY_OGRE1, "Ugly", "Ogre", ogre_pic, 9, 13, 4, 80, WEST_BALLROOM); 1052 initMonster(UGLY_OGRE2, "Ugly", "Ogre", ogre_pic, 12, 12, 4, 80, UPPER_HALL_EAST); 1053 initMonster(BIG_SPIDER, "Big", "Spider", big_spider_pic, 14, 18, 3, 80, MAZE73); 1054 initMonster(SMALL_SPIDER, "Small", "Spider", small_spider_pic, 5, 17, 1, 60, MAZE70); 1055 initMonster(SNAKE, "", "Snake", snake_pic, 14, 17, 3, 60, GARDEN_NORTH); 1056 initMonster(BAT, "", "Bat", bat_pic, 7, 18, 2, 40, WINE_CELLAR); 1057 initMonster(VAMPIRE, "", "Vampire", vampire_pic, 10, 24, 0, 0, CORRIDOR28); 1058 initMonster(FAIRY1, "", "Fairy", fairy_pic, 10, 1, 0, 0, CORRIDOR52); 1059 initMonster(FAIRY2, "", "Fairy", fairy_pic, 1, 12, 0, 0, CORRIDOR54); 1060 initMonster(DOOR1, "", "Door", grating_pic, 15, 9, 0, 0, WINE_CELLAR); 1061 initMonster(DOOR2, "", "", grating_pic, 15, 10, 0, 0, WINE_CELLAR); 1062 initMonster(DOOR3, "", "Door", grating_pic, 9, 14, 0, 0, DUNGEON_ENTRANCE); 1063 initMonster(DOOR4, "", "", grating_pic, 10, 14, 0, 0, DUNGEON_ENTRANCE); 1064 end func; 1065 1066 1067const func itemType: (attr itemType) conv (in char: ch) is func 1068 result 1069 var itemType: item_ident is NO_ITEM; 1070 local 1071 var integer: number is 0; 1072 begin 1073 number := succ(ord(ch) - ord('a')); 1074 if number >= ord(MIN_ITEM) and number <= ord(MAX_ITEM) then 1075 item_ident := itemType conv number; 1076 end if; 1077 end func; 1078 1079 1080const func char: (attr char) conv (in itemType: anItem) is 1081 return chr(pred(ord('a') + ord(anItem))); 1082 1083 1084const proc: initItem ( 1085 in itemType: item_ident, 1086 in string: item_name, 1087 in array string: item_pic, 1088 in integer: item_line, 1089 in integer: item_column, 1090 in integer: item_room_num) is func 1091 begin 1092 item[item_ident].ident := item_ident; 1093 item[item_ident].name := item_name; 1094 item[item_ident].picture := item_pic; 1095 item[item_ident].pixmap := PRIMITIVE_WINDOW.value; 1096 item[item_ident].yPos := pred(item_line) * PIXMAP_SIZE; 1097 item[item_ident].xPos := pred(item_column) * PIXMAP_SIZE; 1098 item[item_ident].room_num := item_room_num; 1099 if item_room_num <> NO_ROOM then 1100 room[item_room_num].data[item_line] @:= [item_column] char conv item_ident; 1101 end if; 1102 end func; 1103 1104 1105const proc: initItemData is func 1106 begin 1107 initItem(BOOK, "Book", book_pic, 11, 11, NO_ROOM); # LIBRARY_WEST_END 1108 initItem(CRYSTAL_BALL, "Crystal Ball", crystal_ball_pic, 13, 10, LABORATORY); 1109 initItem(GLASSES, "Eye Glasses", glasses_pic, 12, 18, NO_ROOM); # YELLOW_ROOM 1110 initItem(HELMET, "Helmet", helmet_pic, 5, 12, GUARDS_HALL); 1111 initItem(KEY, "Key", key_pic, 7, 12, NO_ROOM); # KINGS_STUDY 1112 initItem(LAMP, "Lamp", lamp_pic, 14, 19, GARDEN_NORTH); 1113 initItem(MAGIC_WAND, "Magic Wand", magic_wand_pic, 9, 4, KNIGHTS_HALL); 1114 initItem(SWORD, "Sword", sword_pic, 5, 11, MUSEUM); 1115 initItem(WINE_FLASK, "Wine Flask", flask_pic, 11, 8, NO_ROOM); # CHEFS_QUARTERS 1116 initItem(CROWN, "Crown", crown_pic, 5, 9, THRONE_ROOM); 1117 initItem(DIAMOND, "Diamond", diamond_pic, 10, 13, EMPTY_ROOM); 1118 initItem(FANCY_GOBLET, "Fancy Goblet", goblet_pic, 14, 6, WEST_DINING_ROOM); 1119 initItem(GOLDBAR, "Goldbar", goldbar_pic, 14, 23, MAZE74); 1120 initItem(HARP, "Harp", harp_pic, 8, 16, EAST_TOWER_TOP); 1121 initItem(HOLY_CROSS, "Holy Cross", holy_cross_pic, 13, 15, RED_ROOM); 1122 initItem(HOURGLASS, "Hourglass", hourglass_pic, 14, 6, UPPER_HALL_WEST); 1123 initItem(JADE_FIGURINE, "Jade Figurine", jade_figurine_pic, 10, 13, GUEST_ROOM); 1124 initItem(LARGE_GEM, "Large Gem", large_gem_pic, 10, 12, NO_ROOM); # GARDEN_SOUTH 1125 initItem(NECKLACE, "Necklace", necklace_pic, 9, 12, NO_ROOM); # UPPER_HALL_CENTER 1126 initItem(RUBYS, "Ruby", ruby_pic, 16, 4, CASTLE_WALL); 1127 initItem(SCEPTER, "Scepter", scepter_pic, 10, 12, SECRET_ROOM); 1128 initItem(SILVER_BARS, "Silver Bars", silver_bars_pic, 8, 7, LOWER_BATTLEMENT); 1129 end func; 1130 1131 1132const proc: initPlayerData is func 1133 begin 1134 player.pixmap := createPixmap(player_pic); 1135 player.xPos := 13 * PIXMAP_SIZE; 1136 player.yPos := 14 * PIXMAP_SIZE; 1137 player.saved_pixmap := PRIMITIVE_WINDOW.value; 1138 player.saved_xPos := 0; 1139 player.saved_yPos := 0; 1140 player.room := COURTYARD; 1141 player.direction := SOUTH; 1142 player.inventory := itemSet.EMPTY_SET; 1143 player.strength := MAX_STRENGTH; 1144 player.living := TRUE; 1145 end func; 1146 1147 1148const proc: loadHighScore is func 1149 local 1150 var file: aFile is STD_NULL; 1151 begin 1152 aFile := open("castle.scr", "r"); 1153 if aFile <> STD_NULL then 1154 read(aFile, highScore.points); 1155 read(aFile, highScore.name); 1156 close(aFile); 1157 else 1158 highScore.name := ""; 1159 highScore.points := 0; 1160 end if; 1161 end func; 1162 1163 1164const proc: saveHighScore is func 1165 local 1166 var file: aFile is STD_NULL; 1167 begin 1168 aFile := open("castle.scr", "w"); 1169 if aFile <> STD_NULL then 1170 write(aFile, highScore.points); 1171 write(aFile, " "); 1172 writeln(aFile, highScore.name); 1173 close(aFile); 1174 end if; 1175 end func; 1176 1177 1178const proc: initGame is func 1179 begin 1180 query_pixmap := createPixmap(query_pic); 1181 wall_pixmap := createPixmap(wall_pic); 1182 colored_wall1_pixmap := createPixmap(colored_wall1_pic); 1183 colored_wall2_pixmap := createPixmap(colored_wall2_pic); 1184 vertical_pixmap := createPixmap(vertical_pic); 1185 horizontal_pixmap := createPixmap(horizontal_pic); 1186 left_upper_pixmap := createPixmap(left_upper_pic); 1187 right_upper_pixmap := createPixmap(right_upper_pic); 1188 left_lower_pixmap := createPixmap(left_lower_pic); 1189 right_lower_pixmap := createPixmap(right_lower_pic); 1190 railing_pixmap := createPixmap(railing_pic); 1191 gate_pixmap := createPixmap(gate_pic); 1192 small_bush_pixmap := createPixmap(small_bush_pic); 1193 big_bush_pixmap := createPixmap(big_bush_pic); 1194 statue_pixmap := createPixmap(statue_pic); 1195 fountain_pixmap := createPixmap(fountain_pic); 1196 wood_pixmap := createPixmap(wood_pic); 1197 stone_pixmap := createPixmap(stone_pic); 1198 gray_pixmap := createPixmap(gray_pic); 1199 water_pixmap := createPixmap(water_pic); 1200 bed_left_pixmap := createPixmap(bed_left_pic); 1201 bed_right_pixmap := createPixmap(bed_right_pic); 1202 bed_top_pixmap := createPixmap(bed_top_pic); 1203 bed_bottom_pixmap := createPixmap(bed_bottom_pic); 1204 bed_white_middle_pixmap := createPixmap(bed_white_middle_pic); 1205 bed_red_middle_pixmap := createPixmap(bed_red_middle_pic); 1206 bed_blue_middle_pixmap := createPixmap(bed_blue_middle_pic); 1207 bed_purple_middle_pixmap := createPixmap(bed_purple_middle_pic); 1208 bed_yellow_middle_pixmap := createPixmap(bed_yellow_middle_pic); 1209 chain_pixmap := createPixmap(chain_pic); 1210 k_pixmap := createPixmap(k_pic); 1211 b_pixmap := createPixmap(b_pic); 1212 floor_pixmap := createPixmap(floor_pic); 1213 eye_pixmap := createPixmap(eye_pic); 1214 hand_pixmap := createPixmap(hand_pic); 1215 take_pixmap := createPixmap(take_pic); 1216 drop_pixmap := createPixmap(drop_pic); 1217 load_pixmap := createPixmap(load_pic); 1218 save_pixmap := createPixmap(save_pic); 1219 exit_pixmap := createPixmap(exit_pic); 1220 1221 stair_up.pixmap := createPixmap(up_pic); 1222 stair_up.name := "Stairs up"; 1223 stair_down.pixmap := createPixmap(down_pic); 1224 stair_down.name := "Stairs down"; 1225 1226 message := 0 times ""; 1227 exitGame := FALSE; 1228 flaskFilled := FALSE; 1229 1230 initRoomData; 1231 initMonsterData; 1232 initItemData; 1233 initPlayerData; 1234 loadHighScore; 1235 end func; 1236 1237 1238const proc: displayBox (in color: boxColor) is func 1239 local 1240 const integer: width is 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE; 1241 const integer: height is 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE; 1242 begin 1243 hline(1, 0, width - 2, boxColor); 1244 vline(0, 1, height - 2, boxColor); 1245 hline(1, height - 1, width - 2, boxColor); 1246 vline(width - 1, 1, height - 2, boxColor); 1247 point(1, 1, boxColor); 1248 point(width - 2, 1, boxColor); 1249 point(width - 2, height - 2, boxColor); 1250 point(1, height - 2, boxColor); 1251 end func; 1252 1253 1254const func PRIMITIVE_WINDOW: getPixmap (inout graphObj: currObject) is func 1255 result 1256 var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value; 1257 begin 1258 if currObject.pixmap = PRIMITIVE_WINDOW.value then 1259 currObject.pixmap := createPixmap(currObject.picture, 1260 PIXMAP_SIZE div length(currObject.picture), black); 1261 end if; 1262 pixmap := currObject.pixmap; 1263 end func; 1264 1265 1266const proc: displayRoom (in roomType: current_room) is func 1267 local 1268 var integer: line is 0; 1269 var integer: column is 0; 1270 var char: ch is ' '; 1271 var PRIMITIVE_WINDOW: field_pixmap is PRIMITIVE_WINDOW.value; 1272 var itemType: item_ident is NO_ITEM; 1273 var integer: number is 0; 1274 begin 1275 for line range 1 to ROOM_LINES do 1276 for column range 1 to length(current_room.data[line]) do 1277 ch := current_room.data[line][column]; 1278 if ch <> ' ' then 1279 case ch of 1280 when {'#'}: field_pixmap := wall_pixmap; 1281 when {':'}: field_pixmap := colored_wall1_pixmap; 1282 when {';'}: field_pixmap := colored_wall2_pixmap; 1283 when {'|'}: field_pixmap := vertical_pixmap; 1284 when {'-'}: field_pixmap := horizontal_pixmap; 1285 when {','}: field_pixmap := left_upper_pixmap; 1286 when {'.'}: field_pixmap := right_upper_pixmap; 1287 when {'`'}: field_pixmap := left_lower_pixmap; 1288 when {'''}: field_pixmap := right_lower_pixmap; 1289 when {'>'}: field_pixmap := railing_pixmap; 1290 when {'='}: field_pixmap := gate_pixmap; 1291 when {'+'}: field_pixmap := small_bush_pixmap; 1292 when {'*'}: field_pixmap := big_bush_pixmap; 1293 when {'$'}: field_pixmap := statue_pixmap; 1294 when {'?'}: field_pixmap := fountain_pixmap; 1295 when {'@'}: field_pixmap := wood_pixmap; 1296 when {'&'}: field_pixmap := stone_pixmap; 1297 when {'%'}: field_pixmap := gray_pixmap; 1298 when {'~'}: field_pixmap := water_pixmap; 1299 when {']'}: field_pixmap := bed_left_pixmap; 1300 when {'['}: field_pixmap := bed_right_pixmap; 1301 when {'_'}: field_pixmap := bed_top_pixmap; 1302 when {'^'}: field_pixmap := bed_bottom_pixmap; 1303 when {'W'}: field_pixmap := bed_white_middle_pixmap; 1304 when {'R'}: field_pixmap := bed_red_middle_pixmap; 1305 when {'N'}: field_pixmap := bed_blue_middle_pixmap; 1306 when {'P'}: field_pixmap := bed_purple_middle_pixmap; 1307 when {'Y'}: field_pixmap := bed_yellow_middle_pixmap; 1308 when {'{'}: field_pixmap := chain_pixmap; 1309 when {'K'}: field_pixmap := k_pixmap; 1310 when {'B'}: field_pixmap := b_pixmap; 1311 when {'U'}: field_pixmap := stair_up.pixmap; 1312 when {'D'}: field_pixmap := stair_down.pixmap; 1313 when {' '}: field_pixmap := floor_pixmap; 1314 when {'a' .. 'z'}: 1315 item_ident := itemType conv ch; 1316 if item_ident <> NO_ITEM then 1317 field_pixmap := getPixmap(item[item_ident]); 1318 else 1319 field_pixmap := query_pixmap; 1320 end if; 1321 otherwise: 1322 field_pixmap := query_pixmap; 1323 write("undefined char no "); 1324 writeln(ord(ch)); 1325 end case; 1326 put(curr_win, BORDER_DIST + pred(column) * PIXMAP_SIZE, 1327 BORDER_DIST + pred(line) * PIXMAP_SIZE, field_pixmap); 1328 end if; 1329 end for; 1330 end for; 1331 rect(8, BUTTON_YPOS_MIN, 300, 50, black); 1332 color(white, black); 1333 for number range 1 to length(current_room.description) do 1334 setPos(screen, pred(BUTTON_TEXT_LINE1 + number), 2); 1335 write(screen, current_room.description[number]); 1336 end for; 1337 end func; 1338 1339 1340const proc: displayObj (inout graphObj: currObject) is func 1341 begin 1342 put(curr_win, BORDER_DIST + currObject.saved_xPos, 1343 BORDER_DIST + currObject.saved_yPos, currObject.saved_pixmap); 1344 currObject.saved_pixmap := getPixmap(BORDER_DIST + currObject.xPos, 1345 BORDER_DIST + currObject.yPos, PIXMAP_SIZE, PIXMAP_SIZE); 1346 put(curr_win, BORDER_DIST + currObject.xPos, 1347 BORDER_DIST + currObject.yPos, getPixmap(currObject)); 1348 currObject.saved_xPos := currObject.xPos; 1349 currObject.saved_yPos := currObject.yPos; 1350 end func; 1351 1352 1353const proc: displayMonster is func 1354 local 1355 var monsterType: monster_ident is NO_MONSTER; 1356 begin 1357 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1358 if monster[monster_ident].room_num = player.room then 1359 displayObj(monster[monster_ident]); 1360 end if; 1361 end for; 1362 end func; 1363 1364 1365const proc: objectLegend (inout graphObj: currObject, in integer: line) is func 1366 begin 1367 put(curr_win, LEGEND_XPOS, LEGEND_YPOS_MIN + pred(line) * PIXMAP_SIZE, getPixmap(currObject)); 1368 color(white, black); 1369 setPos(screen, 2 * line, LEGEND_COLUMN); 1370 if currObject.adjective <> "" then 1371 write(screen, currObject.adjective & " " & currObject.name); 1372 else 1373 write(screen, currObject.name); 1374 end if; 1375 end func; 1376 1377 1378const proc: displayLegend is func 1379 local 1380 var monsterType: monster_ident is NO_MONSTER; 1381 var itemType: item_ident is NO_ITEM; 1382 var integer: line is 1; 1383 begin 1384 rect(LEGEND_XPOS, LEGEND_YPOS_MIN, 200, 576, black); 1385 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1386 if monster[monster_ident].room_num = player.room and 1387 monster[monster_ident].name <> "" then 1388 objectLegend(monster[monster_ident], line); 1389 incr(line); 1390 end if; 1391 end for; 1392 for item_ident range MIN_ITEM to MAX_ITEM do 1393 if item[item_ident].room_num = player.room and 1394 not item_ident in player.inventory then 1395 objectLegend(item[item_ident], line); 1396 incr(line); 1397 end if; 1398 end for; 1399 if room[player.room].exits[UP] <> 0 then 1400 objectLegend(stair_up, line); 1401 incr(line); 1402 end if; 1403 if room[player.room].exits[DOWN] <> 0 then 1404 objectLegend(stair_down, line); 1405 incr(line); 1406 end if; 1407 end func; 1408 1409 1410const func integer: sizeOfLegend is func 1411 result 1412 var integer: line is 0; 1413 local 1414 var monsterType: monster_ident is NO_MONSTER; 1415 var itemType: item_ident is NO_ITEM; 1416 begin 1417 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1418 if monster[monster_ident].room_num = player.room and 1419 monster[monster_ident].name <> "" then 1420 incr(line); 1421 end if; 1422 end for; 1423 for item_ident range MIN_ITEM to MAX_ITEM do 1424 if item[item_ident].room_num = player.room and 1425 not item_ident in player.inventory then 1426 incr(line); 1427 end if; 1428 end for; 1429 if room[player.room].exits[UP] <> 0 then 1430 incr(line); 1431 end if; 1432 if room[player.room].exits[DOWN] <> 0 then 1433 incr(line); 1434 end if; 1435 end func; 1436 1437 1438const proc: collectedTreasures is func 1439 local 1440 var itemType: item_ident is NO_ITEM; 1441 var integer: line is 1; 1442 begin 1443 rect(LEGEND_XPOS, 0, width(curr_win) - LEGEND_XPOS, 1444 BORDER_DIST + PIXMAP_SIZE * 14, black); 1445 color(white, black); 1446 setPos(screen, 2 * line - 1, LEGEND_COLUMN); 1447 write(screen, "You have collected"); 1448 setPos(screen, 2 * line, LEGEND_COLUMN); 1449 write(screen, "these Treasures"); 1450 incr(line); 1451 for item_ident range CROWN to MAX_ITEM do 1452 if item_ident in player.inventory or 1453 item[item_ident].room_num = COURTYARD then 1454 objectLegend(item[item_ident], line); 1455 incr(line); 1456 end if; 1457 end for; 1458 if line = 2 then 1459 color(white, black); 1460 setPos(screen, 2 * line, LEGEND_COLUMN); 1461 write(screen, "NONE"); 1462 end if; 1463 end func; 1464 1465 1466const proc: killedMonsters is func 1467 local 1468 var monsterType: monster_ident is NO_MONSTER; 1469 var integer: line is 16; 1470 begin 1471 rect(LEGEND_XPOS, 15 * PIXMAP_SIZE, width(curr_win) - LEGEND_XPOS, 1472 BORDER_DIST + PIXMAP_SIZE * 7, black); 1473 color(white, black); 1474 setPos(screen, 2 * line - 1, LEGEND_COLUMN); 1475 write(screen, "You have killed"); 1476 setPos(screen, 2 * line, LEGEND_COLUMN); 1477 write(screen, "these Monsters"); 1478 incr(line); 1479 if not monster[ANGRY_DEMON1].living or not monster[ANGRY_DEMON2].living then 1480 objectLegend(monster[ANGRY_DEMON1], line); 1481 if not monster[ANGRY_DEMON1].living and not monster[ANGRY_DEMON2].living then 1482 setPos(screen, 2 * line, LEGEND_COLUMN + 15); 1483 write(screen, "two times"); 1484 end if; 1485 incr(line); 1486 end if; 1487 if not monster[UGLY_OGRE1].living or not monster[UGLY_OGRE2].living then 1488 objectLegend(monster[UGLY_OGRE1], line); 1489 if not monster[UGLY_OGRE1].living and not monster[UGLY_OGRE2].living then 1490 setPos(screen, 2 * line, LEGEND_COLUMN + 15); 1491 write(screen, "two times"); 1492 end if; 1493 incr(line); 1494 end if; 1495 for monster_ident range BIG_SPIDER to BAT do 1496 if not monster[monster_ident].living and 1497 monster[monster_ident].name <> "" then 1498 objectLegend(monster[monster_ident], line); 1499 incr(line); 1500 end if; 1501 end for; 1502 if line = 17 then 1503 color(white, black); 1504 setPos(screen, 2 * line, LEGEND_COLUMN); 1505 write(screen, "NONE"); 1506 end if; 1507 end func; 1508 1509 1510const func integer: getInventoryStartLine is func 1511 result 1512 var integer: startLine is 0; 1513 begin 1514 startLine := succ(sizeOfLegend); 1515 if startLine < INVENTORY_LINE then 1516 startLine := INVENTORY_LINE; 1517 end if; 1518 end func; 1519 1520 1521const proc: displayInventoryItem (in integer: item_num) is func 1522 local 1523 var integer: item_line is 1; 1524 var itemType: item_ident is NO_ITEM; 1525 begin 1526 for item_ident range MIN_ITEM to MAX_ITEM do 1527 if item_ident in player.inventory then 1528 if item_line = item_num then 1529 objectLegend(item[item_ident], getInventoryStartLine + item_line); 1530 end if; 1531 incr(item_line); 1532 end if; 1533 end for; 1534 end func; 1535 1536 1537const proc: displayInventoryList is func 1538 local 1539 var integer: line is 0; 1540 var itemType: item_ident is NO_ITEM; 1541 begin 1542 line := succ(getInventoryStartLine); 1543 if player.inventory = itemSet.EMPTY_SET then 1544 color(white, black); 1545 setPos(screen, 2 * line, LEGEND_COLUMN); 1546 write(screen, "Nothing"); 1547 incr(line); 1548 else 1549 for item_ident range MIN_ITEM to MAX_ITEM do 1550 if item_ident in player.inventory then 1551 objectLegend(item[item_ident], line); 1552 incr(line); 1553 end if; 1554 end for; 1555 end if; 1556 end func; 1557 1558 1559const proc: displayInventory is func 1560 local 1561 var integer: startLine is 0; 1562 begin 1563 startLine := getInventoryStartLine; 1564 rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1565 182, PIXMAP_SIZE * (card(player.inventory) + 2), black); 1566 color(white, black); 1567 setPos(screen, 2 * startLine, LEGEND_COLUMN); 1568 write(screen, "Inventory"); 1569 displayInventoryList; 1570 end func; 1571 1572 1573const proc: displayMessage is func 1574 local 1575 var integer: number is 0; 1576 begin 1577 rect(186, BUTTON_YPOS_MIN, 346, 70, black); 1578 color(screen, white, black); 1579 for number range 1 to length(message) do 1580 setPos(screen, BUTTON_TEXT_LINE1 + pred(number), 32); 1581 write(screen, message[number]); 1582 end for; 1583 end func; 1584 1585 1586const proc: displayCommands (in PRIMITIVE_WINDOW: bmp) is func 1587 begin 1588 put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN, load_pixmap); 1589 setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_1_COLUMN); 1590 write(screen, "Load"); 1591 put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN + 32, save_pixmap); 1592 setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_1_COLUMN); 1593 write(screen, "Save"); 1594 put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN + 64, exit_pixmap); 1595 setPos(screen, BUTTON_TEXT_LINE1 + 4, BUTTONS_1_COLUMN); 1596 write(screen, "Exit"); 1597 put(curr_win, BUTTONS_2_XPOS, BUTTON_YPOS_MIN, take_pixmap); 1598 setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_2_COLUMN); 1599 write(screen, "Take"); 1600 put(curr_win, BUTTONS_2_XPOS, BUTTON_YPOS_MIN + 32, drop_pixmap); 1601 setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_2_COLUMN); 1602 write(screen, "Drop"); 1603 put(curr_win, BUTTONS_3_XPOS, BUTTON_YPOS_MIN, eye_pixmap); 1604 setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_3_COLUMN); 1605 write(screen, "Look"); 1606 put(curr_win, BUTTONS_3_XPOS, BUTTON_YPOS_MIN + 32, hand_pixmap); 1607 setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_3_COLUMN); 1608 write(screen, "Use"); 1609 end func; 1610 1611 1612const proc: displayAll is func 1613 begin 1614 clear(curr_win, black); 1615 displayRoom(room[player.room]); 1616 displayMessage; 1617 displayMonster; 1618 displayObj(player); 1619 displayLegend; 1620 displayInventory; 1621 displayCommands(curr_win); 1622 displayBox(white); 1623 end func; 1624 1625 1626const proc: floodTrap is func 1627 local 1628 var string: s1 is ""; 1629 var string: s2 is ""; 1630 var integer: number is 0; 1631 begin 1632 s1 := room[WINDING_PASSAGE3].data[9]; 1633 s2 := room[WINDING_PASSAGE3].data[10]; 1634 1635 s1 @:= [12] '#'; 1636 s1 @:= [24] '#'; 1637 s2 @:= [12] '#'; 1638 s2 @:= [24] '#'; 1639 1640 room[WINDING_PASSAGE3].data[9] := s1; 1641 room[WINDING_PASSAGE3].data[10] := s2; 1642 for number range 13 to 23 do 1643 s1 @:= [number] '~'; 1644 s2 @:= [number] '~'; 1645 1646 room[WINDING_PASSAGE3].data[9] := s1; 1647 room[WINDING_PASSAGE3].data[10] := s2; 1648 displayAll; 1649 end for; 1650 end func; 1651 1652 1653const proc: checkRoom is func 1654 begin 1655 case player.room of 1656 when {WINDING_PASSAGE1}: 1657 room[WINDING_PASSAGE2].data[18] := " #################### "; 1658 when {WINDING_PASSAGE3}: 1659 room[WINDING_PASSAGE2].data[18] := " #################### "; 1660 if player.xPos = 544 and not NECKLACE in player.inventory then 1661 message := [] ("You have sprung a Trap!!"); 1662 displayAll; 1663 floodTrap; 1664 message &:= [] ("The room has filled with water and you drowned!"); 1665 1666 displayAll; 1667 1668 player.living := FALSE; 1669 end if; 1670 when {SECRET_ROOM}: 1671 room[WINDING_PASSAGE2].data[18] := " ######## ########## "; 1672 when {WINDING_PASSAGE2}: 1673 if room[WINDING_PASSAGE2].data[18][12] = '#' and player.yPos > 512 then 1674 room[WINDING_PASSAGE2].data[18] := " ######## ########## "; 1675 end if; 1676 when {WEST_TOWER_MIDDLE}: 1677 room[SORCERERS_QUARTERS].data[8] := "###### |# "; 1678 room[SORCERERS_QUARTERS].data[9] := " |# "; 1679 room[SORCERERS_QUARTERS].data[10] := " |# "; 1680 room[SORCERERS_QUARTERS].data[11] := "###### |# "; 1681 when {LABORATORY}: 1682 room[SORCERERS_QUARTERS].data[8] := "###### #####"; 1683 room[SORCERERS_QUARTERS].data[9] := " "; 1684 room[SORCERERS_QUARTERS].data[10] := " "; 1685 room[SORCERERS_QUARTERS].data[11] := "###### #####"; 1686 when {SORCERERS_QUARTERS}: 1687 if room[SORCERERS_QUARTERS].data[10][20] = '#' and player.xPos > 544 then 1688 room[SORCERERS_QUARTERS].data[8] := "###### #####"; 1689 room[SORCERERS_QUARTERS].data[9] := " "; 1690 room[SORCERERS_QUARTERS].data[10] := " "; 1691 room[SORCERERS_QUARTERS].data[11] := "###### #####"; 1692 end if; 1693 end case; 1694 end func; 1695 1696 1697const proc: hideItem (in itemObj: anItem) is func 1698 local 1699 var integer: line is 0; 1700 var integer: column is 0; 1701 begin 1702 if anItem.room_num <> NO_ROOM then 1703 line := succ(anItem.yPos div PIXMAP_SIZE); 1704 column := succ(anItem.xPos div PIXMAP_SIZE); 1705 room[anItem.room_num].data[line] @:= [column] ' '; 1706 end if; 1707 end func; 1708 1709 1710const proc: showItem (in itemObj: anItem) is func 1711 local 1712 var integer: line is 0; 1713 var integer: column is 0; 1714 begin 1715 if anItem.room_num <> NO_ROOM then 1716 line := succ(anItem.yPos div PIXMAP_SIZE); 1717 column := succ(anItem.xPos div PIXMAP_SIZE); 1718 room[anItem.room_num].data[line] @:= [column] char conv (anItem.ident); 1719 end if; 1720 end func; 1721 1722 1723const proc: loadGame is func 1724 local 1725 var file: load_file is STD_NULL; 1726 var monsterType: monster_ident is NO_MONSTER; 1727 var itemType: item_ident is NO_ITEM; 1728 begin 1729 if fileType("castle.sav") = FILE_REGULAR then 1730 if isOkay([]("Do you want to load a saved game.", "This will end the current game?")) then 1731 load_file := open("castle.sav", "r"); 1732 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1733 readln(load_file, monster[monster_ident].adjective); 1734 readln(load_file, monster[monster_ident].xPos); 1735 readln(load_file, monster[monster_ident].yPos); 1736 readln(load_file, monster[monster_ident].strength); 1737 readln(load_file, monster[monster_ident].direction); 1738 readln(load_file, monster[monster_ident].living); 1739 end for; 1740 for item_ident range MIN_ITEM to MAX_ITEM do 1741 hideItem(item[item_ident]); 1742 readln(load_file, item[item_ident].xPos); 1743 readln(load_file, item[item_ident].yPos); 1744 readln(load_file, item[item_ident].room_num); 1745 end for; 1746 readln(load_file, player.xPos); 1747 readln(load_file, player.yPos); 1748 readln(load_file, player.room); 1749 readln(load_file, player.direction); 1750 readln(load_file, player.inventory); 1751 readln(load_file, player.strength); 1752 close(load_file); 1753 1754 message := [] ("Game Loaded Successful!"); 1755 for item_ident range MIN_ITEM to MAX_ITEM do 1756 if item_ident not in player.inventory then 1757 showItem(item[item_ident]); 1758 end if; 1759 end for; 1760 player.saved_pixmap := PRIMITIVE_WINDOW.value; 1761 checkRoom; 1762 displayAll; 1763 end if; 1764 else 1765 message := [] ("There Is No Saved Game To Load!"); 1766 displayMessage; 1767 end if; 1768 end func; 1769 1770 1771const proc: saveGame is func 1772 local 1773 var file: save_file is STD_NULL; 1774 var monsterType: monster_ident is NO_MONSTER; 1775 var itemType: item_ident is NO_ITEM; 1776 begin 1777 if fileType("castle.sav") = FILE_REGULAR then 1778 if isOkay([]("Do you want to overwrite the", "game currently saved?")) then 1779 removeFile("castle.sav"); 1780 end if; 1781 end if; 1782 if fileType("castle.sav") = FILE_ABSENT then 1783 save_file := open("castle.sav", "w"); 1784 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1785 writeln(save_file, monster[monster_ident].adjective); 1786 writeln(save_file, monster[monster_ident].xPos); 1787 writeln(save_file, monster[monster_ident].yPos); 1788 writeln(save_file, monster[monster_ident].strength); 1789 writeln(save_file, monster[monster_ident].direction); 1790 writeln(save_file, monster[monster_ident].living); 1791 end for; 1792 for item_ident range MIN_ITEM to MAX_ITEM do 1793 writeln(save_file, item[item_ident].xPos); 1794 writeln(save_file, item[item_ident].yPos); 1795 writeln(save_file, item[item_ident].room_num); 1796 end for; 1797 writeln(save_file, player.xPos); 1798 writeln(save_file, player.yPos); 1799 writeln(save_file, player.room); 1800 writeln(save_file, player.direction); 1801 writeln(save_file, player.inventory); 1802 writeln(save_file, player.strength); 1803 close(save_file); 1804 1805 message := [] ("Game Saved Successful!"); 1806 displayMessage; 1807 end if; 1808 end func; 1809 1810 1811const func monsterType: searchMonster (in integer: xPos, in integer: yPos) is func 1812 result 1813 var monsterType: monsterFound is NO_MONSTER; 1814 local 1815 var monsterType: monster_ident is NO_MONSTER; 1816 begin 1817 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1818 if monster[monster_ident].room_num = player.room and 1819 xPos >= monster[monster_ident].xPos and 1820 xPos < monster[monster_ident].xPos + PIXMAP_SIZE and 1821 yPos >= monster[monster_ident].yPos and 1822 yPos < monster[monster_ident].yPos + PIXMAP_SIZE then 1823 monsterFound := monster_ident; 1824 end if; 1825 end for; 1826 end func; 1827 1828 1829const func monsterType: hitMonster (in integer: xPos, in integer: yPos) is func 1830 result 1831 var monsterType: monsterMet is NO_MONSTER; 1832 local 1833 var monsterType: monster_ident is NO_MONSTER; 1834 begin 1835 for monster_ident range MIN_MONSTER to MAX_MONSTER do 1836 if monster[monster_ident].room_num = player.room and monster[monster_ident].living then 1837 if abs(xPos - monster[monster_ident].xPos) < PIXMAP_SIZE and 1838 abs(yPos - monster[monster_ident].yPos) < PIXMAP_SIZE then 1839 monsterMet := monster_ident; 1840 end if; 1841 end if; 1842 end for; 1843 end func; 1844 1845 1846const func itemType: selectItem (in PRIMITIVE_WINDOW: symbol, in string: name, in integer: invSize) is func 1847 result 1848 var itemType: itemSelected is NO_ITEM; 1849 local 1850 var char: command is ' '; 1851 var integer: startLine is 0; 1852 var integer: position is 0; 1853 var itemType: item_ident is NO_ITEM; 1854 var integer: count is 0; 1855 var boolean: getCommand is FALSE; 1856 var integer: xPos is 0; 1857 var integer: yPos is 0; 1858 begin 1859 if card(player.inventory) >= invSize then 1860 startLine := getInventoryStartLine; 1861 rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1862 PIXMAP_SIZE, PIXMAP_SIZE, black); 1863 box(LEGEND_XPOS - 3, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE - 3, 1864 187, succ(card(player.inventory)) * PIXMAP_SIZE + 6, light_red); 1865 rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1866 150, PIXMAP_SIZE, light_gray); 1867 put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1868 symbol); 1869 color(white, black); 1870 setPos(screen, 2 * startLine, LEGEND_COLUMN + 5); 1871 write(screen, name); 1872 displayInventoryList; 1873 position := 0; 1874 command := getc(KEYBOARD); 1875 while command not in {' ', KEY_NL, KEY_ESC} do 1876 getCommand := TRUE; 1877 rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE, 1878 150, PIXMAP_SIZE, black); 1879 if position >= 1 then 1880 displayInventoryItem(position); 1881 else 1882 put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1883 symbol); 1884 color(white, black); 1885 setPos(screen, 2 * startLine, LEGEND_COLUMN + 5); 1886 write(screen, name); 1887 end if; 1888 if command = KEY_UP and position > 1 then 1889 decr(position); 1890 elsif command = KEY_DOWN and position < card(player.inventory) then 1891 incr(position); 1892 elsif command = KEY_MOUSE1 then 1893 xPos := getxpos(KEYBOARD); 1894 yPos := getypos(KEYBOARD); 1895 if xPos >= LEGEND_XPOS and xPos < LEGEND_XPOS + 128 and 1896 yPos >= LEGEND_YPOS_MIN + startLine * PIXMAP_SIZE and 1897 yPos <= LEGEND_YPOS_MIN + (startLine + card(player.inventory)) * PIXMAP_SIZE then 1898 position := (yPos - LEGEND_YPOS_MIN - startLine * PIXMAP_SIZE) div 32 + 1; 1899 else 1900 position := 0; 1901 end if; 1902 command := ' '; 1903 getCommand := FALSE; 1904 end if; 1905 rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE, 1906 150, PIXMAP_SIZE, light_gray); 1907 if position >= 1 then 1908 displayInventoryItem(position); 1909 else 1910 put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1911 symbol); 1912 color(white, black); 1913 setPos(screen, 2 * startLine, LEGEND_COLUMN + 5); 1914 write(screen, name); 1915 end if; 1916 if getCommand then 1917 command := getc(KEYBOARD); 1918 end if; 1919 end while; 1920 rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE, 1921 150, PIXMAP_SIZE, black); 1922 displayInventoryItem(position); 1923 if position >= 1 and command in {' ', KEY_NL} then 1924 count := 0; 1925 for item_ident range MIN_ITEM to MAX_ITEM do 1926 if item_ident in player.inventory then 1927 incr(count); 1928 if count = position then 1929 itemSelected := item_ident; 1930 end if; 1931 end if; 1932 end for; 1933 end if; 1934 rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE, 1935 182, PIXMAP_SIZE, black); 1936 setPos(screen, 2 * startLine, LEGEND_COLUMN); 1937 color(white, black); 1938 write(screen, "Inventory"); 1939 box(LEGEND_XPOS - 3, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE - 3, 1940 187, succ(card(player.inventory)) * PIXMAP_SIZE + 6, black); 1941 end if; 1942 end func; 1943 1944 1945const proc: dropItem (in itemType: item_ident) is func 1946 local 1947 var directionType: direction is NORTH; 1948 var integer: column is 0; 1949 var integer: line is 0; 1950 1951 begin 1952 direction := player.direction; 1953 repeat 1954 if direction = NORTH then 1955 line := player.yPos div PIXMAP_SIZE; 1956 column := player.xPos div PIXMAP_SIZE + 1; 1957 incr(direction); 1958 elsif direction = SOUTH then 1959 line := (player.yPos + STEP_SIZE) div PIXMAP_SIZE + 2; 1960 column := player.xPos div PIXMAP_SIZE + 1; 1961 incr(direction); 1962 elsif direction = EAST then 1963 line := player.yPos div PIXMAP_SIZE + 1; 1964 column := (player.xPos + STEP_SIZE) div PIXMAP_SIZE + 2; 1965 incr(direction); 1966 elsif direction = WEST then 1967 line := player.yPos div PIXMAP_SIZE + 1; 1968 column := player.xPos div PIXMAP_SIZE; 1969 direction := NORTH; 1970 end if; 1971 until line >= 1 and line <= ROOM_LINES and 1972 column >= 1 and column <= ROOM_COLUMNS and 1973 room[player.room].data[line][column] = ' ' and 1974 hitMonster(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE) = NO_MONSTER or 1975 direction = player.direction; 1976 if room[player.room].data[line][column] = ' ' then 1977 item[item_ident].xPos := pred(column) * PIXMAP_SIZE; 1978 item[item_ident].yPos := pred(line) * PIXMAP_SIZE; 1979 item[item_ident].room_num := player.room; 1980 showItem(item[item_ident]); 1981 excl(player.inventory, item_ident); 1982 put(curr_win, BORDER_DIST + item[item_ident].xPos, 1983 BORDER_DIST + item[item_ident].yPos, getPixmap(item[item_ident])); 1984 displayLegend; 1985 displayInventory; 1986 else 1987 displayInventory; 1988 message := [] ("Something is in the way!"); 1989 displayMessage; 1990 end if; 1991 end func; 1992 1993 1994const proc: dropItem is func 1995 local 1996 var itemType: item_ident is NO_ITEM; 1997 begin 1998 item_ident := selectItem(drop_pixmap, "Drop", 1); 1999 if item_ident <> NO_ITEM then 2000 dropItem(item_ident); 2001 end if; 2002 end func; 2003 2004 2005const proc: useItem (in itemType: item_ident) is func 2006 local 2007 var boolean: done is FALSE; 2008 begin 2009 case item_ident of 2010 when {BOOK}: 2011 if GLASSES in player.inventory then 2012 message := [] ("The book reads:", 2013 " Wave Scepter"); 2014 else 2015 message := [] ("You can't see well enough.", 2016 "It's all Blurry."); 2017 end if; 2018 done := TRUE; 2019 when {CRYSTAL_BALL}: 2020 message := [] ("In the Crystal Ball....", 2021 " You see a man in a winding passage, waving a Wand."); 2022 done := TRUE; 2023 when {HELMET}: 2024 message := [] ("Ok. I'm wearing it."); 2025 done := TRUE; 2026 when {MAGIC_WAND}: 2027 if player.room = WINDING_PASSAGE2 then 2028 message := [] ("As you wave the WAND....", 2029 " There is a *Puff* of smoke Revealing a Secret passage!"); 2030 room[WINDING_PASSAGE2].data[18] := " ######## ########## "; 2031 elsif player.room = SORCERERS_QUARTERS then 2032 message := [] ("As you wave the WAND....", 2033 " There is a *Puff* of smoke Revealing a Secret passage!"); 2034 room[SORCERERS_QUARTERS].data[8] := "###### #####"; 2035 room[SORCERERS_QUARTERS].data[9] := " "; 2036 room[SORCERERS_QUARTERS].data[10] := " "; 2037 room[SORCERERS_QUARTERS].data[11] := "###### #####"; 2038 else 2039 message := [] ("As you wave the WAND....", 2040 " Nothing Happens!"); 2041 end if; 2042 done := TRUE; 2043 when {WINE_FLASK}: 2044 if flaskFilled then 2045 message := [] ("That was good!", 2046 "I feel much better now!"); 2047 player.strength := MAX_STRENGTH; 2048 else 2049 message := [] ("You don't have any WATER!"); 2050 end if; 2051 done := TRUE; 2052 when {HARP}: 2053 message := [] ("The Harp makes Beautiful Music!"); 2054 if player.room = CORRIDOR52 or player.room = CORRIDOR54 then 2055 monster[FAIRY1].room_num := -1; 2056 monster[FAIRY1].living := FALSE; 2057 monster[FAIRY2].room_num := -1; 2058 monster[FAIRY2].living := FALSE; 2059 message := [] ("The fairy likes the music and leaves!"); 2060 end if; 2061 done := TRUE; 2062 when {HOLY_CROSS}: 2063 if player.room = CORRIDOR28 then 2064 monster[VAMPIRE].room_num := -1; 2065 message := [] ("The vampire sees the holy cross and disappears!"); 2066 done := TRUE; 2067 end if; 2068 when {SCEPTER}: 2069 if player.room = COURTYARD then 2070 message := [] ("As you wave the scepter...", 2071 "The Gate opens by itself!"); 2072 room[COURTYARD].data[18] := "########## ##########"; 2073 else 2074 message := [] ("As you wave the SCEPTER....", 2075 " Nothing Happens!"); 2076 end if; 2077 done := TRUE; 2078 end case; 2079 2080 if not done then 2081 message := [] ("You look awful Silly waving that " & item[item_ident].name); 2082 end if; 2083 displayAll; 2084 end func; 2085 2086 2087const proc: useItem is func 2088 local 2089 var itemType: item_ident is NO_ITEM; 2090 begin 2091 item_ident := selectItem(hand_pixmap, "Use", 1); 2092 if item_ident <> NO_ITEM then 2093 useItem(item_ident); 2094 end if; 2095 end func; 2096 2097 2098const func array string: getMonsterMessage (in monsterType: monster_ident) is func 2099 result 2100 var array string: message is 0 times ""; 2101 begin 2102 case monster_ident of 2103 when {ANGRY_DEMON1, ANGRY_DEMON2, UGLY_OGRE1, UGLY_OGRE2, 2104 BIG_SPIDER, SMALL_SPIDER, SNAKE, BAT, VAMPIRE}: 2105 if monster[monster_ident].living then 2106 message := [] ("look " & monster[monster_ident].name & ":", 2107 "The " & monster[monster_ident].name & " looks Mean!"); 2108 else 2109 message := [] ("look " & monster[monster_ident].name & ":", 2110 "The " & monster[monster_ident].name & " looks Dead!"); 2111 end if; 2112 when {FAIRY1, FAIRY2}: 2113 message := [] ("look " & monster[monster_ident].name & ":", 2114 "The " & monster[monster_ident].name & " looks pretty but unhappy."); 2115 when {DOOR1, DOOR2, DOOR3, DOOR4}: 2116 message := [] ("look door:", 2117 "It looks very Strong."); 2118 end case; 2119 end func; 2120 2121 2122const func array string: getItemMessage (in itemType: item_ident) is func 2123 result 2124 var array string: message is 0 times ""; 2125 begin 2126 case item_ident of 2127 when {BOOK}: 2128 message := [] ("It is titled", 2129 " 'The Gate'"); 2130 when {CRYSTAL_BALL}: 2131 message := [] ("In the Crystal Ball....", 2132 " You see a man in a winding passage, waving a Wand."); 2133 when {GLASSES}: 2134 message := [] ("They're Bifocals"); 2135 when {HELMET}: 2136 message := [] ("It looks Tough!"); 2137 when {KEY}: 2138 message := [] ("It looks Old!"); 2139 when {LAMP}: 2140 message := [] ("It's lit Magically"); 2141 when {MAGIC_WAND}: 2142 message := [] ("It looks Magical!"); 2143 when {SWORD}: 2144 message := [] ("It looks Sharp!"); 2145 when {WINE_FLASK}: 2146 if flaskFilled then 2147 message := [] ("It's filled with water."); 2148 else 2149 message := [] ("It's empty."); 2150 end if; 2151 when {CROWN}: 2152 message := [] ("It's made of Gold!"); 2153 when {DIAMOND}: 2154 message := [] ("It looks Expensive!"); 2155 when {FANCY_GOBLET}: 2156 message := [] ("It's made of Gold!"); 2157 when {GOLDBAR}: 2158 message := [] ("It looks Expensive!"); 2159 when {HARP}: 2160 message := [] ("It's made of Gold!"); 2161 when {HOLY_CROSS}: 2162 message := [] ("It's made of Gold!"); 2163 when {HOURGLASS}: 2164 message := [] ("It's made of Gold!"); 2165 when {JADE_FIGURINE}: 2166 message := [] ("It looks Expensive!"); 2167 when {LARGE_GEM}: 2168 message := [] ("It looks Expensive!"); 2169 when {NECKLACE}: 2170 message := [] ("On the back it says:", 2171 "Protection from Traps."); 2172 when {RUBYS}: 2173 message := [] ("They look Expensive!"); 2174 when {SCEPTER}: 2175 message := [] ("It looks Expensive!"); 2176 when {SILVER_BARS}: 2177 message := [] ("They look Expensive!"); 2178 end case; 2179 end func; 2180 2181 2182const func integer: getScore is func 2183 result 2184 var integer: score is 0; 2185 local 2186 var monsterType: monster_ident is NO_MONSTER; 2187 var itemType: item_ident is NO_ITEM; 2188 begin 2189 for monster_ident range MIN_MONSTER to BAT do 2190 if not monster[monster_ident].living then 2191 score +:= 100; 2192 end if; 2193 end for; 2194 for item_ident range CROWN to MAX_ITEM do 2195 if item_ident in player.inventory or 2196 item[item_ident].room_num = COURTYARD then 2197 score +:= 50; 2198 end if; 2199 end for; 2200 if player.room = ESCAPED then 2201 score +:= 100; 2202 end if; 2203 2204 if score > highScore.points then 2205 highScore.points := score; 2206 highScore.name := player.name; 2207 end if; 2208 end func; 2209 2210 2211const proc: showStatus is func 2212 local 2213 var char: command is ' '; 2214 begin 2215 rect(BUTTONS_1_XPOS, BUTTON_YPOS_MIN, 272, 128, black); 2216 box(BUTTONS_1_XPOS, BUTTON_YPOS_MIN, 272, 128, light_red); 2217 color(screen, white, black); 2218 if player.room = ESCAPED then 2219 setPos(screen, BUTTON_TEXT_LINE1, 100); 2220 write(screen, "You've Escaped the Castle!"); 2221 elsif player.living then 2222 setPos(screen, BUTTON_TEXT_LINE1, 100); 2223 write(screen, " Your current status:"); 2224 else 2225 setPos(screen, BUTTON_TEXT_LINE1, 100); 2226 write(screen, "You have failed to Escape!"); 2227 end if; 2228 rect(LEGEND_XPOS, 0, width(curr_win) - LEGEND_XPOS, height(curr_win), black); 2229 collectedTreasures; 2230 killedMonsters; 2231 setPos(screen, BUTTON_TEXT_LINE1 + 2, 105); 2232 write(screen, "Your Score: " <& getScore); 2233 setPos(screen, BUTTON_TEXT_LINE1 + 3, 104); 2234 write(screen, "(1550 is perfect)"); 2235 saveHighScore; 2236 setPos(screen, BUTTON_TEXT_LINE1 + 5, 104); 2237 write(screen, "- Press any key -"); 2238 repeat 2239 command := upper(getc(KEYBOARD)); 2240 if command in {'Y', 'N'} then 2241 setPos(screen, BUTTON_TEXT_LINE1 + 6, 105); 2242 write(screen, "(Except Y or N)"); 2243 end if; 2244 until command not in {'Y', 'N'}; 2245 end func; 2246 2247 2248const proc: lookItemInRoom is func 2249 local 2250 var integer: xPos is 0; 2251 var integer: yPos is 0; 2252 var integer: line is 0; 2253 var integer: column is 0; 2254 var itemType: item_ident is NO_ITEM; 2255 var monsterType: monster_ident is NO_MONSTER; 2256 begin 2257 xPos := getxpos(KEYBOARD); 2258 yPos := getypos(KEYBOARD); 2259 xPos -:= BORDER_DIST; 2260 yPos -:= BORDER_DIST; 2261 line := succ(yPos div PIXMAP_SIZE); 2262 column := succ(xPos div PIXMAP_SIZE); 2263 if line >= 1 and line <= ROOM_LINES and 2264 column >= 1 and column <= ROOM_COLUMNS then 2265 (* writeln(xPos <& " " <& column); 2266 writeln(yPos <& " " <& line); 2267 writeln(" " <& room[player.room].data[line][column] <& 2268 " " <& ord(room[player.room].data[line][column])); *) 2269 case room[player.room].data[line][column] of 2270 when {'#', '&'}: 2271 if player.room = COURTYARD then 2272 if highScore.name = "" then 2273 message := [] ("look wall:", 2274 "Writing on the wall says...", 2275 "Highscore: " & str(highScore.points)); 2276 else 2277 message := [] ("look wall:", 2278 "Writing on the wall says...", 2279 "Highscore: " & str(highScore.points) & 2280 " by " & highScore.name); 2281 end if; 2282 displayMessage; 2283 showStatus; 2284 displayCommands(curr_win); 2285 displayAll; 2286 message := 0 times ""; 2287 elsif player.room = MAZE74 then 2288 message := [] ("look wall:", 2289 "The Wall Says:", 2290 "Kevin Bales was here!"); 2291 else 2292 message := [] ("look wall:", 2293 "The WALLS are made of Gray Stone."); 2294 end if; 2295 when {':', ';'}: 2296 message := [] ("look wall:", 2297 "The walls are many colors!"); 2298 when {'K', 'B'}: 2299 message := [] ("look wall:", 2300 "The Wall Says:", 2301 "Kevin Bales was here!"); 2302 when {'W'}: 2303 message := [] ("look bed:", 2304 "It's Old."); 2305 when {'R'}: 2306 message := [] ("look bed:", 2307 "It's Red."); 2308 when {'N'}: 2309 message := [] ("look bed:", 2310 "It's Blue."); 2311 when {'P'}: 2312 message := [] ("look bed:", 2313 "It's Purple."); 2314 when {'Y'}: 2315 message := [] ("look bed:", 2316 "It's Yellow."); 2317 when {'U'}: 2318 message := [] ("look staircase:", 2319 "The Staircase leads up."); 2320 when {'D'}: 2321 message := [] ("look staircase:", 2322 "The Staircase leads down."); 2323 when {'='}: 2324 message := [] ("look gate:", 2325 "It looks very Strong."); 2326 when {'>'}: 2327 message := [] ("look balcony:", 2328 "The balcony is made of stone."); 2329 when {'?'}: 2330 if player.room = GARDEN_SOUTH then 2331 message := [] ("look fountain:", 2332 "The fountain is filled with water.", 2333 "But you can't see In it."); 2334 elsif player.room = BALCONY then 2335 if item[LARGE_GEM].room_num = NO_ROOM and not LARGE_GEM in player.inventory then 2336 message := [] ("look fountain:", 2337 "There is a BIG Gem in the Garden Fountain!"); 2338 else 2339 message := [] ("look fountain:", 2340 "The Garden Has A Fountain in the middle."); 2341 end if; 2342 end if; 2343 when {'{'}: 2344 message := [] ("look chains:", 2345 "They look Magical!"); 2346 when {'$'}: 2347 if item[NECKLACE].room_num = NO_ROOM and not NECKLACE in player.inventory then 2348 message := [] ("look statue:", 2349 "The statue is wearing a Necklace"); 2350 else 2351 message := [] ("look statue:", 2352 "The statue looks like The King!"); 2353 end if; 2354 when {'%'}: 2355 if player.room = KITCHEN then 2356 message := [] ("look table:", 2357 "It's made of Stone."); 2358 elsif player.room = THRONE_ROOM then 2359 message := [] ("look throne:", 2360 "The throne is made of Stone."); 2361 end if; 2362 when {'@'}: 2363 if player.room = CHEFS_QUARTERS then 2364 if item[WINE_FLASK].room_num = NO_ROOM and not WINE_FLASK in player.inventory then 2365 put(curr_win, BORDER_DIST + item[WINE_FLASK].xPos, 2366 BORDER_DIST + item[WINE_FLASK].yPos, getPixmap(item[WINE_FLASK])); 2367 message := [] ("look desk:", 2368 "There is a Wine Flask on top."); 2369 else 2370 message := [] ("look desk:", 2371 "It's made of Wood."); 2372 end if; 2373 elsif player.room = YELLOW_ROOM then 2374 if item[GLASSES].room_num = NO_ROOM and not GLASSES in player.inventory then 2375 put(curr_win, BORDER_DIST + item[GLASSES].xPos, 2376 BORDER_DIST + item[GLASSES].yPos, getPixmap(item[GLASSES])); 2377 message := [] ("look desk:", 2378 "There is a Pair of Eye Glasses on Top."); 2379 else 2380 message := [] ("look desk:", 2381 "It's made of Wood."); 2382 end if; 2383 elsif player.room = KINGS_STUDY then 2384 if item[KEY].room_num = NO_ROOM and not KEY in player.inventory then 2385 put(curr_win, BORDER_DIST + item[KEY].xPos, 2386 BORDER_DIST + item[KEY].yPos, getPixmap(item[KEY])); 2387 message := [] ("look desk:", 2388 "There is a Key on top."); 2389 else 2390 message := [] ("look desk:", 2391 "It's made of Wood."); 2392 end if; 2393 elsif player.room = LIBRARY_WEST_END then 2394 if item[BOOK].room_num = NO_ROOM and not BOOK in player.inventory then 2395 put(curr_win, BORDER_DIST + item[BOOK].xPos, 2396 BORDER_DIST + item[BOOK].yPos, getPixmap(item[BOOK])); 2397 message := [] ("look shelves:", 2398 "There's a book on one."); 2399 else 2400 message := [] ("look shelves:", 2401 "They're made of wood."); 2402 end if; 2403 elsif player.room = LIBRARY_EAST_END then 2404 message := [] ("look shelves:", 2405 "They're made of wood."); 2406 elsif player.room = STORAGE_ROOM then 2407 message := [] ("look shelves:", 2408 "They're made of wood."); 2409 elsif player.room = WINE_CELLAR then 2410 message := [] ("look barrels:", 2411 "They look Old!"); 2412 elsif player.room = TORTURE_ROOM then 2413 message := [] ("look table:", 2414 "It's covered with Blood!"); 2415 end if; 2416 when {'|'}: 2417 if player.room = SORCERERS_QUARTERS then 2418 message := [] ("look mirror:", 2419 "It looks Magical!"); 2420 elsif player.room = BALCONY then 2421 message := [] ("look balcony:", 2422 "The balcony is made of stone."); 2423 end if; 2424 when {'+'}: 2425 message := [] ("look bush:", 2426 "This is a small bush."); 2427 when {'*'}: 2428 message := [] ("look bush:", 2429 "This is a big bush."); 2430 when {'a' .. 'z'}: 2431 item_ident := itemType conv (room[player.room].data[line][column]); 2432 if item_ident <> NO_ITEM then 2433 message := [] ("look " & item[item_ident].name & ":"); 2434 message &:= getItemMessage(item_ident); 2435 end if; 2436 when {' '}: 2437 monster_ident := searchMonster(xPos, yPos); 2438 if monster_ident <> NO_MONSTER then 2439 message := getMonsterMessage(monster_ident); 2440 elsif xPos >= player.xPos and 2441 xPos < player.xPos + PIXMAP_SIZE and 2442 yPos >= player.yPos and 2443 yPos < player.yPos + PIXMAP_SIZE then 2444 if player.room = SORCERERS_QUARTERS and 2445 room[SORCERERS_QUARTERS].data[10][20] = '#' then 2446 message := [] ("look player:", 2447 "You see an ugly face in the mirror."); 2448 else 2449 message := [] ("look player:", 2450 "This is only possible with a mirror."); 2451 end if; 2452 else 2453 message := [] ("look floor:", 2454 "The FLOORS are made of Gray Stone."); 2455 end if; 2456 end case; 2457 end if; 2458 end func; 2459 2460 2461const proc: lookItem is func 2462 local 2463 var itemType: item_ident is NO_ITEM; 2464 begin 2465 displayBox(light_red); 2466 message := [] ("look"); 2467 displayMessage; 2468 message := 0 times ""; 2469 item_ident := selectItem(eye_pixmap, "Look at", 0); 2470 if item_ident <> NO_ITEM then 2471 message := [] ("look " & item[item_ident].name & ":"); 2472 message &:= getItemMessage(item_ident); 2473 else 2474 lookItemInRoom; 2475 end if; 2476 displayMessage; 2477 displayBox(white); 2478 end func; 2479 2480 2481const proc: welcomeScreen is func 2482 begin 2483 clear(curr_win, black); 2484 displayRoom(room[CASTLE]); 2485 setPos(screen, 5, 63); 2486 writeln(screen, "C A S T L E"); 2487 setPos(screen, 7, 49); 2488 writeln(screen, "Copyright (C) 2004, 2005 Thomas Mertes"); 2489 setPos(screen, 9, 49); 2490 writeln(screen, "This program is free software under the"); 2491 setPos(screen, 10, 49); 2492 writeln(screen, "terms of the GNU General Public License"); 2493 setPos(screen, 12, 43); 2494 writeln(screen, "Castle is written in the Seed7 programming language"); 2495 setPos(screen, 13, 48); 2496 writeln(screen, "Homepage: http://seed7.sourceforge.net"); 2497 end func; 2498 2499 2500const proc: endOfGame is func 2501 local 2502 var char: command is ' '; 2503 begin 2504 showStatus; 2505 setPos(screen, BUTTON_TEXT_LINE1 + 5, 104); 2506 write(screen, "Play Again (Y/N)?"); 2507 setPos(screen, BUTTON_TEXT_LINE1 + 6, 105); 2508 write(screen, " "); 2509 repeat 2510 command := upper(getc(KEYBOARD)); 2511 until command in {'Y', 'N'}; 2512 if command = 'Y' then 2513 initGame; 2514 displayAll; 2515 end if; 2516 end func; 2517 2518 2519const func char: getField (in integer: xPos, in integer: yPos) is func 2520 result 2521 var char: field is ' '; 2522 local 2523 var integer: line is 0; 2524 var integer: column is 0; 2525 begin 2526 line := succ(yPos div PIXMAP_SIZE); 2527 column := succ(xPos div PIXMAP_SIZE); 2528 field := room[player.room].data[line][column]; 2529 if field = ' ' then 2530 if xPos rem PIXMAP_SIZE <> 0 then 2531 field := room[player.room].data[line][succ(column)]; 2532 if field = ' ' then 2533 if yPos rem PIXMAP_SIZE <> 0 then 2534 field := room[player.room].data[succ(line)][column]; 2535 if field = ' ' then 2536 field := room[player.room].data[succ(line)][succ(column)]; 2537 end if; 2538 end if; 2539 end if; 2540 else 2541 if yPos rem PIXMAP_SIZE <> 0 then 2542 field := room[player.room].data[succ(line)][column]; 2543 end if; 2544 end if; 2545 end if; 2546 end func; 2547 2548 2549const proc: checkField (inout char: field) is func 2550 local 2551 var itemType: item_ident is NO_ITEM; 2552 var integer: line is 0; 2553 var integer: column is 0; 2554 begin 2555 if field <> ' ' then 2556 if field = '=' then 2557 if player.room = COURTYARD then 2558 message := [] ("The Gate is locked."); 2559 end if; 2560 displayMessage; 2561 elsif field in {'a' .. 'z'} then 2562 item_ident := itemType conv field; 2563 if item_ident <> NO_ITEM then 2564 if card(player.inventory) < MAX_INVENTORY then 2565 line := succ(item[item_ident].yPos div PIXMAP_SIZE); 2566 column := succ(item[item_ident].xPos div PIXMAP_SIZE); 2567 room[player.room].data[line] @:= [column] ' '; 2568 field := ' '; 2569 incl(player.inventory, item_ident); 2570 put(curr_win, BORDER_DIST + pred(column) * PIXMAP_SIZE, 2571 BORDER_DIST + pred(line) * PIXMAP_SIZE, floor_pixmap); 2572 displayLegend; 2573 displayInventory; 2574 message := 0 times ""; 2575 else 2576 message := [] ("take " & item[item_ident].name & ":", 2577 "Can't carry any more!"); 2578 end if; 2579 displayMessage; 2580 end if; 2581 end if; 2582 end if 2583 end func; 2584 2585 2586const func char: hitWall (in integer: xPos, in integer: yPos) is func 2587 result 2588 var char: field is ' '; 2589 begin 2590 field := getField(xPos, yPos); 2591 checkField(field); 2592 end func; 2593 2594 2595const func boolean: checkCollision (in integer: xPos, in integer: yPos) is func 2596 result 2597 var boolean: collision is FALSE; 2598 local 2599 var char: ch is ' '; 2600 begin 2601 ch := getField(xPos, yPos); 2602 collision := ch <> ' '; 2603 end func; 2604 2605 2606const func boolean: hitPlayer (in graphObj: obj1, in graphObj: obj2) is func 2607 result 2608 var boolean: hit is FALSE; 2609 begin 2610 if abs(obj1.xPos - obj2.xPos) < PIXMAP_SIZE and 2611 abs(obj1.yPos - obj2.yPos) < PIXMAP_SIZE then 2612 hit := TRUE; 2613 end if; 2614 end func; 2615 2616 2617const proc: moveMonsters is func 2618 local 2619 var integer: x_diff is 0; 2620 var integer: y_diff is 0; 2621 var monsterType: current_monster is NO_MONSTER; 2622 var monsterType: monster_ident is NO_MONSTER; 2623 begin 2624 for monster_ident range MIN_MONSTER to MAX_MONSTER do 2625 if monster[monster_ident].room_num = player.room and 2626 monster[monster_ident].living then 2627 x_diff := monster[monster_ident].xPos - player.xPos; 2628 y_diff := monster[monster_ident].yPos - player.yPos; 2629 2630 if abs(x_diff) >= abs(y_diff) then 2631 if x_diff >= 0 then 2632 monster[monster_ident].direction := WEST; 2633 else 2634 monster[monster_ident].direction := EAST; 2635 end if; 2636 else 2637 if y_diff >= 0 then 2638 monster[monster_ident].direction := NORTH; 2639 else 2640 monster[monster_ident].direction := SOUTH; 2641 end if; 2642 end if; 2643 2644 if monster_ident <= BAT then 2645 if monster[monster_ident].yPos > player.yPos then 2646 monster[monster_ident].yPos -:= 8; 2647 if hitPlayer(player, monster[monster_ident]) then 2648 current_monster := monster_ident; 2649 monster[monster_ident].yPos +:= 8; 2650 elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then 2651 monster[monster_ident].yPos +:= 8; 2652 else 2653 displayObj(monster[monster_ident]); 2654 end if; 2655 end if; 2656 if monster[monster_ident].yPos < player.yPos then 2657 monster[monster_ident].yPos +:= 8; 2658 if hitPlayer(player, monster[monster_ident]) then 2659 current_monster := monster_ident; 2660 monster[monster_ident].yPos -:= 8; 2661 elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then 2662 monster[monster_ident].yPos -:= 8; 2663 else 2664 displayObj(monster[monster_ident]); 2665 end if; 2666 end if; 2667 if monster[monster_ident].xPos > player.xPos then 2668 monster[monster_ident].xPos -:= 8; 2669 if hitPlayer(player, monster[monster_ident]) then 2670 current_monster := monster_ident; 2671 monster[monster_ident].xPos +:= 8; 2672 elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then 2673 monster[monster_ident].xPos +:= 8; 2674 else 2675 displayObj(monster[monster_ident]); 2676 end if; 2677 end if; 2678 if monster[monster_ident].xPos < player.xPos then 2679 monster[monster_ident].xPos +:= 8; 2680 if hitPlayer(player, monster[monster_ident]) then 2681 current_monster := monster_ident; 2682 monster[monster_ident].xPos -:= 8; 2683 elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then 2684 monster[monster_ident].xPos -:= 8; 2685 else 2686 displayObj(monster[monster_ident]); 2687 end if; 2688 end if; 2689 end if; 2690 end if; 2691 end for; 2692 2693 if current_monster > NO_MONSTER then 2694 if rand(1, 10) <= 4 then 2695 player.strength -:= monster[current_monster].attack; 2696 if player.strength < 1 then 2697 message &:= [] ("The " & monster[current_monster].name & " has killed you!"); 2698 player.living := FALSE; 2699 else 2700 message &:= [] ("The " & monster[current_monster].name & " struck you!"); 2701 if rand(1, 2) = 1 and HELMET in player.inventory then 2702 player.strength +:= monster[current_monster].attack; 2703 message &:= [] ("The Helmet helped."); 2704 end if; 2705 end if; 2706 else 2707 message &:= [] ("The " & monster[current_monster].name & " missed you!"); 2708 end if; 2709 displayMessage; 2710 message := 0 times ""; 2711 end if; 2712 end func; 2713 2714 2715const proc: enterRoom (in integer: room_number) is func 2716 begin 2717 message := 0 times ""; 2718 player.room := room_number; 2719 end func; 2720 2721 2722const proc: moveDelta (in integer: delta_x, in integer: delta_y) is func 2723 local 2724 var char: field is ' '; 2725 var directionType: stair is NORTH; 2726 var monsterType: monster_ident is NO_MONSTER; 2727 begin 2728 field := hitWall(player.xPos + delta_x, player.yPos + delta_y); 2729 if field <> ' ' then 2730 if field = 'U' then 2731 stair := UP; 2732 elsif field = 'D' then 2733 stair := DOWN; 2734 end if; 2735 if stair in {UP, DOWN} and room[player.room].exits[stair] <> 0 then 2736 if room[player.room].exits[stair] in {WINE_CELLAR, DUNGEON_ENTRANCE} and 2737 not LAMP in player.inventory then 2738 message := [] ("It's too dark to go that way!"); 2739 displayMessage; 2740 else 2741 enterRoom(room[player.room].exits[stair]); 2742 player.saved_pixmap := PRIMITIVE_WINDOW.value; 2743 displayAll; 2744 end if; 2745 end if; 2746 else 2747 monster_ident := hitMonster(player.xPos + delta_x, player.yPos + delta_y); 2748 if monster_ident <> NO_MONSTER then 2749 if monster_ident <= BAT then 2750 if SWORD in player.inventory then 2751 if rand(1, 10) <= 4 then 2752 monster[monster_ident].strength -:= rand(10, 19); 2753 message := [] ("You struck the " & monster[monster_ident].name & "!"); 2754 if monster[monster_ident].strength < 1 then 2755 message := [] ("You killed the " & monster[monster_ident].name & "!"); 2756 monster[monster_ident].living := FALSE; 2757 monster[monster_ident].adjective := "Dead"; 2758 displayLegend; 2759 displayInventory; 2760 end if; 2761 else 2762 message := [] ("You missed the " & monster[monster_ident].name & "!"); 2763 end if; 2764 else 2765 message := [] ("You have no Weapon"); 2766 end if; 2767 displayMessage; 2768 elsif monster_ident = VAMPIRE then 2769 message := [] ("The " & monster[monster_ident].name & " is blocking your way.", 2770 "He can't be hurt!"); 2771 displayMessage; 2772 elsif monster_ident = FAIRY1 or 2773 monster_ident = FAIRY2 then 2774 message := [] ("The " & monster[monster_ident].name & " is blocking your way.", 2775 "She can't be hurt!"); 2776 displayMessage; 2777 elsif monster_ident = DOOR1 or 2778 monster_ident = DOOR2 then 2779 if KEY in player.inventory then 2780 monster[DOOR1].living := FALSE; 2781 monster[DOOR2].living := FALSE; 2782 monster[DOOR1].adjective := "Open"; 2783 message := [] ("You open the door with the key"); 2784 displayMessage; 2785 else 2786 message := [] ("The door is locked"); 2787 displayMessage; 2788 end if; 2789 elsif monster_ident = DOOR3 or 2790 monster_ident = DOOR4 then 2791 if KEY in player.inventory then 2792 monster[DOOR3].living := FALSE; 2793 monster[DOOR4].living := FALSE; 2794 monster[DOOR3].adjective := "Open"; 2795 message := [] ("You open the door with the key"); 2796 displayMessage; 2797 else 2798 message := [] ("The door is locked"); 2799 displayMessage; 2800 end if; 2801 end if; 2802 else 2803 player.xPos +:= delta_x; 2804 player.yPos +:= delta_y; 2805 displayObj(player); 2806 end if; 2807 end if; 2808 end func; 2809 2810 2811const proc: move (in directionType: direction) is func 2812 begin 2813 player.direction := direction; 2814 if player.direction = WEST then 2815 if player.xPos - STEP_SIZE < 0 then 2816 if room[player.room].exits[WEST] <> 0 then 2817 enterRoom(room[player.room].exits[WEST]); 2818 player.saved_pixmap := PRIMITIVE_WINDOW.value; 2819 player.xPos := 736; 2820 displayAll; 2821 end if; 2822 else 2823 moveDelta(-STEP_SIZE, 0); 2824 end if; 2825 elsif player.direction = EAST then 2826 if player.xPos + STEP_SIZE > 736 then 2827 if room[player.room].exits[EAST] <> 0 then 2828 enterRoom(room[player.room].exits[EAST]); 2829 player.saved_pixmap := PRIMITIVE_WINDOW.value; 2830 player.xPos := 0; 2831 displayAll; 2832 end if; 2833 else 2834 moveDelta(STEP_SIZE, 0); 2835 end if; 2836 elsif player.direction = NORTH then 2837 if player.yPos - STEP_SIZE < 0 then 2838 if room[player.room].exits[NORTH] <> 0 then 2839 enterRoom(room[player.room].exits[NORTH]); 2840 player.saved_pixmap := PRIMITIVE_WINDOW.value; 2841 player.yPos := 544; 2842 displayAll; 2843 end if; 2844 else 2845 moveDelta(0, -STEP_SIZE); 2846 end if; 2847 elsif player.direction = SOUTH then 2848 if player.yPos + STEP_SIZE > 544 then 2849 if room[player.room].exits[SOUTH] <> 0 then 2850 enterRoom(room[player.room].exits[SOUTH]); 2851 player.saved_pixmap := PRIMITIVE_WINDOW.value; 2852 player.yPos := 0; 2853 displayAll; 2854 end if; 2855 else 2856 moveDelta(0, STEP_SIZE); 2857 end if; 2858 end if; 2859 end func; 2860 2861 2862const proc: moveTo (in integer: xPos, in integer: yPos) is func 2863 local 2864 var integer: old_x is 0; 2865 var integer: old_y is 0; 2866 var integer: old_room is 0; 2867 var time: curr_time is time.value; 2868 begin 2869 if abs(xPos - player.xPos) > STEP_SIZE div 2 or 2870 abs(yPos - player.yPos) > STEP_SIZE div 2 then 2871 old_room := player.room; 2872 repeat 2873 curr_time := time(NOW); 2874 old_x := player.xPos; 2875 old_y := player.yPos; 2876 if abs(xPos - player.xPos) > abs(yPos - player.yPos) then 2877 if xPos > player.xPos then 2878 move(EAST); 2879 else 2880 move(WEST); 2881 end if; 2882 if abs(yPos - player.yPos) > STEP_SIZE div 2 and 2883 old_x = player.xPos and old_y = player.yPos then 2884 if yPos > player.yPos then 2885 move(SOUTH); 2886 else 2887 move(NORTH); 2888 end if; 2889 end if; 2890 else 2891 if yPos > player.yPos then 2892 move(SOUTH); 2893 else 2894 move(NORTH); 2895 end if; 2896 if abs(xPos - player.xPos) > STEP_SIZE div 2 and 2897 old_x = player.xPos and old_y = player.yPos then 2898 if xPos > player.xPos then 2899 move(EAST); 2900 else 2901 move(WEST); 2902 end if; 2903 end if; 2904 end if; 2905 checkRoom; 2906 moveMonsters; 2907 flushGraphic; 2908 await(curr_time + 30000 . MICRO_SECONDS); 2909 until abs(xPos - player.xPos) <= STEP_SIZE div 2 and 2910 abs(yPos - player.yPos) <= STEP_SIZE div 2 or 2911 old_x = player.xPos and old_y = player.yPos or 2912 old_room <> player.room or keypressed(KEYBOARD); 2913 end if; 2914 end func; 2915 2916 2917const proc: takeItem (in itemType: item_ident, in string: name, 2918 in integer: line, in integer: column) is func 2919 begin 2920 if item[item_ident].xPos = pred(column) * PIXMAP_SIZE and 2921 item[item_ident].yPos = pred(line) * PIXMAP_SIZE and 2922 item[item_ident].room_num = NO_ROOM and 2923 not item_ident in player.inventory then 2924 message := [] ("take " & item[item_ident].name); 2925 displayMessage; 2926 message := 0 times ""; 2927 moveTo(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE); 2928 if abs(succ(player.yPos div PIXMAP_SIZE) - line) <= 2 and 2929 abs(succ(player.xPos div PIXMAP_SIZE) - column) <= 2 then 2930 if card(player.inventory) < MAX_INVENTORY then 2931 incl(player.inventory, item_ident); 2932 displayAll; 2933 else 2934 message := [] ("take " & item[item_ident].name & ":", 2935 "Can't carry any more!"); 2936 end if; 2937 else 2938 message := [] ("take " & item[item_ident].name & ":", 2939 "I can't reach it!"); 2940 end if; 2941 else 2942 message := [] ("take " & name & ":", 2943 upper(name) & "S are too heavy!"); 2944 end if; 2945 end func; 2946 2947 2948const proc: takeItem is func 2949 local 2950 var char: command is ' '; 2951 var integer: xPos is 0; 2952 var integer: yPos is 0; 2953 var integer: line is 0; 2954 var integer: column is 0; 2955 var itemType: item_ident is NO_ITEM; 2956 var monsterType: monster_ident is NO_MONSTER; 2957 begin 2958 displayBox(light_red); 2959 message := [] ("take"); 2960 displayMessage; 2961 message := 0 times ""; 2962 command := getc(KEYBOARD); 2963 xPos := getxpos(KEYBOARD); 2964 yPos := getypos(KEYBOARD); 2965 xPos -:= BORDER_DIST; 2966 yPos -:= BORDER_DIST; 2967 line := succ(yPos div PIXMAP_SIZE); 2968 column := succ(xPos div PIXMAP_SIZE); 2969 if line >= 1 and line <= ROOM_LINES and 2970 column >= 1 and column <= ROOM_COLUMNS then 2971 case room[player.room].data[line][column] of 2972 when {'#', '&', ':', ';'}: 2973 message := [] ("take wall:", 2974 "Impossible!!"); 2975 when {'W', 'R', 'N', 'P', 'Y'}: 2976 message := [] ("take bed:", 2977 "BEDS are too heavy!"); 2978 when {'U', 'D'}: 2979 message := [] ("take staircase:", 2980 "Impossible!!"); 2981 when {'='}: 2982 message := [] ("take gate:", 2983 "Impossible!!"); 2984 when {'>'}: 2985 message := [] ("take balcony:", 2986 "Impossible!!"); 2987 when {'?'}: 2988 if player.room = GARDEN_SOUTH then 2989 takeItem(LARGE_GEM, "fountain", line, column); 2990 elsif player.room = BALCONY then 2991 message := [] ("take fountain:", 2992 "FOUNTAINS are too heavy!"); 2993 end if; 2994 when {'{'}: 2995 message := [] ("take chains:", 2996 "They're Connected to the wall."); 2997 when {'$'}: 2998 takeItem(NECKLACE, "statue", line, column); 2999 when {'%'}: 3000 if player.room = KITCHEN then 3001 message := [] ("take table:", 3002 "TABLES are too heavy!"); 3003 elsif player.room = THRONE_ROOM then 3004 message := [] ("take throne:", 3005 "THRONES are too heavy!"); 3006 end if; 3007 when {'@'}: 3008 if player.room = CHEFS_QUARTERS then 3009 takeItem(WINE_FLASK, "desk", line, column); 3010 elsif player.room = YELLOW_ROOM then 3011 takeItem(GLASSES, "desk", line, column); 3012 elsif player.room = KINGS_STUDY then 3013 takeItem(KEY, "desk", line, column); 3014 elsif player.room = LIBRARY_WEST_END then 3015 takeItem(BOOK, "shelve", line, column); 3016 elsif player.room = LIBRARY_EAST_END then 3017 message := [] ("take shelve:", 3018 "SHELVES are too heavy!"); 3019 elsif player.room = STORAGE_ROOM then 3020 message := [] ("take shelve:", 3021 "SHELVES are too heavy!"); 3022 elsif player.room = WINE_CELLAR then 3023 message := [] ("take barrel:", 3024 "BARRELS are too heavy!"); 3025 elsif player.room = TORTURE_ROOM then 3026 message := [] ("take table:", 3027 "TABLES are too heavy!"); 3028 end if; 3029 when {'|'}: 3030 if player.room = SORCERERS_QUARTERS then 3031 message := [] ("take mirror:", 3032 "MIRRORS are too heavy!"); 3033 elsif player.room = BALCONY then 3034 message := [] ("take balcony:", 3035 "Impossible!!"); 3036 end if; 3037 when {'+', '*'}: 3038 message := [] ("take bush:", 3039 "Impossible!!"); 3040 when {'a' .. 'z'}: 3041 item_ident := itemType conv (room[player.room].data[line][column]); 3042 if item_ident <> NO_ITEM then 3043 message := [] ("take " & item[item_ident].name); 3044 displayMessage; 3045 message := 0 times ""; 3046 moveTo(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE); 3047 end if; 3048 when {' '}: 3049 monster_ident := searchMonster(xPos, yPos); 3050 if monster_ident <> NO_MONSTER then 3051 message := [] ("take " & monster[monster_ident].name & ":", 3052 "I don't think that would be very safe!"); 3053 elsif xPos >= player.xPos and 3054 xPos < player.xPos + PIXMAP_SIZE and 3055 yPos >= player.yPos and 3056 yPos < player.yPos + PIXMAP_SIZE then 3057 message := [] ("take player:", 3058 "Impossible!!"); 3059 else 3060 message := [] ("take floor:", 3061 "Impossible!!"); 3062 end if; 3063 end case; 3064 end if; 3065 displayMessage; 3066 displayBox(white); 3067 end func; 3068 3069 3070const proc: quitGame is func 3071 begin 3072 if isOkay([]("Quit the castle game?")) then 3073 exitGame := TRUE; 3074 end if; 3075 end func; 3076 3077 3078const proc: playGame is func 3079 local 3080 var char: command is ' '; 3081 var integer: xPos is 0; 3082 var integer: yPos is 0; 3083 begin 3084 displayAll; 3085 while player.living and not exitGame do 3086 3087 command := getc(KEYBOARD); 3088 case command of 3089 when {KEY_LEFT}: move(WEST); 3090 when {KEY_RIGHT}: move(EAST); 3091 when {KEY_UP}: move(NORTH); 3092 when {KEY_DOWN}: move(SOUTH); 3093 when {KEY_ESC}: bossMode(exitGame); 3094 when {'Q', 'q', KEY_CLOSE}: quitGame; 3095 when {KEY_MOUSE1}: 3096 xPos := getxpos(KEYBOARD); 3097 yPos := getypos(KEYBOARD); 3098 if xPos >= BUTTONS_1_XPOS and xPos < BUTTONS_1_XPOS + 80 and 3099 yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 3 * 32 then 3100 case (yPos - BUTTON_YPOS_MIN) div 32 of 3101 when {0}: loadGame; 3102 when {1}: saveGame; 3103 when {2}: quitGame; 3104 end case; 3105 end if; 3106 if xPos >= BUTTONS_2_XPOS and xPos < BUTTONS_2_XPOS + 80 and 3107 yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 2 * 32 then 3108 case (yPos - BUTTON_YPOS_MIN) div 32 of 3109 when {0}: takeItem; 3110 when {1}: dropItem; 3111 end case; 3112 end if; 3113 if xPos >= BUTTONS_3_XPOS and xPos < BUTTONS_3_XPOS + 80 and 3114 yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 2 * 32 then 3115 case (yPos - BUTTON_YPOS_MIN) div 32 of 3116 when {0}: lookItem; 3117 when {1}: useItem; 3118 end case; 3119 end if; 3120 if xPos < 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE and 3121 yPos < 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE then 3122 moveTo(xPos - BORDER_DIST - STEP_SIZE, yPos - BORDER_DIST - STEP_SIZE); 3123 end if; 3124 end case; 3125 3126 checkRoom; 3127 3128 moveMonsters; 3129 3130 if player.room = ESCAPED or not player.living then 3131 exitGame := TRUE; 3132 endOfGame; 3133 end if; 3134 end while; 3135 end func; 3136 3137 3138const proc: main is func 3139 local 3140 var char: command is ' '; 3141 begin 3142 screen(1024, 768); 3143 selectInput(curr_win, KEY_CLOSE, TRUE); 3144 clear(curr_win, white); 3145 screen := open(curr_win, 16); 3146 KEYBOARD := GRAPH_KEYBOARD; 3147 initGame; 3148 welcomeScreen; 3149 command := getc(KEYBOARD); 3150 if upper(command) <> 'Q' and command <> KEY_CLOSE and command <> KEY_ESC then 3151 playGame; 3152 end if; 3153 end func; 3154