$ include "seed7_05.s7i";
include "osfiles.s7i";
include "float.s7i";
include "draw.s7i";
include "keybd.s7i";
include "dialog.s7i";
include "pic32.s7i";
include "time.s7i";
include "duration.s7i";
include "bstring.s7i";
include "getf.s7i";
include "strifile.s7i";
const integer: ROOM_LINES is 18;
const integer: ROOM_COLUMNS is 24;
const integer: INVENTORY_LINE is 16;
const integer: MAX_STRENGTH is 200;
const integer: MAX_INVENTORY is 6;
const integer: PIXMAP_SIZE is 32;
const integer: STEP_SIZE is 16;
const integer: BORDER_DIST is 20;
const integer: LEGEND_XPOS is 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE + 16;
const integer: LEGEND_YPOS_MIN is 8;
const integer: LEGEND_COLUMN is (LEGEND_XPOS + PIXMAP_SIZE) div 6 + 3;
const integer: BUTTONS_1_XPOS is LEGEND_XPOS - 3 * 96;
const integer: BUTTONS_2_XPOS is LEGEND_XPOS - 2 * 96;
const integer: BUTTONS_3_XPOS is LEGEND_XPOS - 96;
const integer: BUTTONS_1_COLUMN is (BUTTONS_1_XPOS + PIXMAP_SIZE) div 6 + 3;
const integer: BUTTONS_2_COLUMN is (BUTTONS_2_XPOS + PIXMAP_SIZE) div 6 + 3;
const integer: BUTTONS_3_COLUMN is (BUTTONS_3_XPOS + PIXMAP_SIZE) div 6 + 3;
const integer: BUTTON_YPOS_MIN is 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE + 16;
const integer: BUTTON_TEXT_LINE1 is BUTTON_YPOS_MIN div 16 + 2;
const type: directionType is new enum
NORTH, SOUTH, EAST, WEST, UP, DOWN
end enum;
const func string: str (in directionType: direction) is
return str(ord(direction));
const func directionType: (attr directionType) parse (in string: stri) is
return directionType conv (integer(stri));
enable_io(directionType);
const type: itemType is new enum
NO_ITEM, BOOK, CRYSTAL_BALL, GLASSES, HELMET,
KEY, LAMP, MAGIC_WAND, SWORD, WINE_FLASK,
CROWN, DIAMOND, FANCY_GOBLET, GOLDBAR, HARP,
HOLY_CROSS, HOURGLASS, JADE_FIGURINE, LARGE_GEM,
NECKLACE, RUBYS, SCEPTER, SILVER_BARS
end enum;
const itemType: MIN_ITEM is succ(itemType.first);
const itemType: MAX_ITEM is itemType.last;
const type: monsterType is new enum
NO_MONSTER, ANGRY_DEMON1, ANGRY_DEMON2,
UGLY_OGRE1, UGLY_OGRE2, BIG_SPIDER,
SMALL_SPIDER, SNAKE, BAT, VAMPIRE,
FAIRY1, FAIRY2, DOOR1, DOOR2, DOOR3, DOOR4
end enum;
const monsterType: MIN_MONSTER is succ(monsterType.first);
const monsterType: MAX_MONSTER is monsterType.last;
const integer: NO_ROOM is 0;
const integer: COURTYARD is 1;
const integer: WEST_BALLROOM is 4;
const integer: WEST_DINING_ROOM is 8;
const integer: KITCHEN is 9;
const integer: CHEFS_QUARTERS is 10;
const integer: STORAGE_ROOM is 11;
const integer: MUSEUM is 12;
const integer: THRONE_ROOM is 14;
const integer: GARDEN_NORTH is 17;
const integer: GARDEN_SOUTH is 18;
const integer: UPPER_HALL_CENTER is 19;
const integer: UPPER_HALL_WEST is 20;
const integer: UPPER_HALL_EAST is 21;
const integer: GUARDS_HALL is 22;
const integer: KNIGHTS_HALL is 24;
const integer: LOWER_BATTLEMENT is 26;
const integer: CORRIDOR28 is 28;
const integer: GUEST_ROOM is 29;
const integer: BALCONY is 33;
const integer: RED_ROOM is 37;
const integer: YELLOW_ROOM is 40;
const integer: CORRIDOR52 is 52;
const integer: CORRIDOR54 is 54;
const integer: KINGS_STUDY is 56;
const integer: EMPTY_ROOM is 57;
const integer: LIBRARY_WEST_END is 58;
const integer: LIBRARY_EAST_END is 59;
const integer: CASTLE_WALL is 60;
const integer: WEST_TOWER_MIDDLE is 62;
const integer: EAST_TOWER_TOP is 65;
const integer: LABORATORY is 66;
const integer: SORCERERS_QUARTERS is 67;
const integer: WINE_CELLAR is 68;
const integer: MAZE70 is 70;
const integer: MAZE73 is 73;
const integer: MAZE74 is 74;
const integer: WINDING_PASSAGE1 is 76;
const integer: WINDING_PASSAGE2 is 77;
const integer: WINDING_PASSAGE3 is 78;
const integer: TORTURE_ROOM is 79;
const integer: DUNGEON_ENTRANCE is 82;
const integer: SECRET_ROOM is 83;
const integer: ESCAPED is 84;
const integer: CASTLE is 85;
const integer: MAX_ROOM is 85;
const type: itemSet is set of itemType;
const func string: str (in itemSet: aSet) is
return str(bitset conv aSet);
const func itemSet: (attr itemSet) parse (in string: stri) is
return itemSet conv (bitset(stri));
enable_io(itemSet);
const type: graphObj is new struct
var string: name is "";
var string: adjective is "";
var array string: picture is 0 times "";
var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value;
var integer: xPos is 0;
var integer: yPos is 0;
var PRIMITIVE_WINDOW: saved_pixmap is PRIMITIVE_WINDOW.value;
var integer: saved_xPos is 0;
var integer: saved_yPos is 0;
end struct;
const type: itemObj is sub graphObj struct
var itemType: ident is NO_ITEM;
var integer: room_num is 0;
end struct;
const type: monsterObj is sub graphObj struct
var monsterType: ident is NO_MONSTER;
var integer: attack is 0;
var integer: strength is 0;
var integer: room_num is 0;
var directionType: direction is NORTH;
var boolean: living is FALSE;
end struct;
const type: playerObj is sub graphObj struct
var integer: room is 0;
var directionType: direction is NORTH;
var itemSet: inventory is itemSet.EMPTY_SET;
var integer: strength is 0;
var boolean: living is TRUE;
end struct;
const type: roomType is new struct
var array string: data is ROOM_LINES times "";
var array string: description is 5 times "";
var array [directionType] integer: exits is directionType times 0;
end struct;
const type: scoreType is new struct
var string: name is "";
var integer: points is 0;
end struct;
var text: screen is STD_NULL;
var array [itemType] itemObj: item is itemType times itemObj.value;
var array [monsterType] monsterObj: monster is monsterType times monsterObj.value;
var playerObj: player is playerObj.value;
var array roomType: room is MAX_ROOM times roomType.value;
var scoreType: highScore is scoreType.value;
var graphObj: stair_up is graphObj.value;
var graphObj: stair_down is graphObj.value;
var array string: message is 0 times "";
var boolean: flaskFilled is FALSE;
var boolean: exitGame is FALSE;
var PRIMITIVE_WINDOW: query_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: wall_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: colored_wall1_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: colored_wall2_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: vertical_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: horizontal_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: left_upper_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: right_upper_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: left_lower_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: right_lower_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: railing_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: gate_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: small_bush_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: big_bush_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: statue_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: fountain_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: wood_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: stone_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: gray_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: water_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_left_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_right_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_top_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_bottom_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_white_middle_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_red_middle_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_blue_middle_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_purple_middle_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: bed_yellow_middle_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: chain_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: k_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: b_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: floor_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: eye_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: hand_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: take_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: drop_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: load_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: save_pixmap is PRIMITIVE_WINDOW.value;
var PRIMITIVE_WINDOW: exit_pixmap is PRIMITIVE_WINDOW.value;
const array string: query_pic is [](
" WWWW ",
" W W ",
" W W ",
" WW ",
" WW ",
" WW ",
" ",
" WW ");
const array string: wall_pic is [](
"WBBBBBBBWBBBBBBB",
"WBBBBBBBWBBBBBBB",
"WBBBBBBBWBBBBBBB",
"WWWWWWWWWWWWWWWW",
"RRRRWRRRRRRRWRRR",
"RRRRWRRRRRRRWRRR",
"RRRRWRRRRRRRWRRR",
"WWWWWWWWWWWWWWWW",
"WBBBBBBBWBBBBBBB",
"WBBBBBBBWBBBBBBB",
"WBBBBBBBWBBBBBBB",
"WWWWWWWWWWWWWWWW",
"RRRRWRRRRRRRWRRR",
"RRRRWRRRRRRRWRRR",
"RRRRWRRRRRRRWRRR",
"WWWWWWWWWWWWWWWW");
const array string: colored_wall1_pic is [](
"WGGGGGGGWMMMMMMM",
"WGGGGGGGWMMMMMMM",
"WGGGGGGGWMMMMMMM",
"WWWWWWWWWWWWWWWW",
"RRRRWmmmmmmmWBBB",
"RRRRWmmmmmmmWBBB",
"RRRRWmmmmmmmWBBB",
"WWWWWWWWWWWWWWWW",
"WgggggggWOOOOOOO",
"WgggggggWOOOOOOO",
"WgggggggWOOOOOOO",
"WWWWWWWWWWWWWWWW",
"YYYYWbbbbbbbWBBB",
"YYYYWbbbbbbbWBBB",
"YYYYWbbbbbbbWBBB",
"WWWWWWWWWWWWWWWW");
const array string: colored_wall2_pic is [](
"WgggggggWOOOOOOO",
"WgggggggWOOOOOOO",
"WgggggggWOOOOOOO",
"WWWWWWWWWWWWWWWW",
"BBBBWbbbbbbbWRRR",
"BBBBWbbbbbbbWRRR",
"BBBBWbbbbbbbWRRR",
"WWWWWWWWWWWWWWWW",
"WGGGGGGGWMMMMMMM",
"WGGGGGGGWMMMMMMM",
"WGGGGGGGWMMMMMMM",
"WWWWWWWWWWWWWWWW",
"BBBBWrrrrrrrWYYY",
"BBBBWrrrrrrrWYYY",
"BBBBWrrrrrrrWYYY",
"WWWWWWWWWWWWWWWW");
const array string: vertical_pic is [](
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ");
const array string: horizontal_pic is [](
" ",
" ",
" ",
" ",
" ",
" ",
" ",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
" ",
" ",
" ",
" ",
" ",
" ",
" ");
const array string: left_upper_pic is [](
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" WWWWWWWWW",
" WWWWWWWWW",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ");
const array string: right_upper_pic is [](
" ",
" ",
" ",
" ",
" ",
" ",
" ",
"WWWWWWWWW ",
"WWWWWWWWW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ");
const array string: left_lower_pic is [](
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WWWWWWWWW",
" WWWWWWWWW",
" ",
" ",
" ",
" ",
" ",
" ",
" ");
const array string: right_lower_pic is [](
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
"WWWWWWWWW ",
"WWWWWWWWW ",
" ",
" ",
" ",
" ",
" ",
" ",
" ");
const array string: railing_pic is [](
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WWWWWWWWW",
" WWWWWWWWW",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ",
" WW ");
const array string: gate_pic is [](
" ",
" ",
" ",
" ",
" ",
" bbbbbbbbbbbbbb ",
"bbbbbrrrrrbbbrrr",
"brrrrbbbbbrrrbbb",
"bbbbbbrrrbbbbbbb",
"rrrrrrbbbrrrrrbb",
" bbbbbbbbbbbbbb ",
" ",
" ",
" ",
" ",
" ");
const array string: small_bush_pic is [](
" G GG ",
" G GG GG G ",
" G G G G G ",
" GGGG GG G GGG ",
" GG GGG ",
" GGG G G GG ",
" GGG GG GG GGG",
" G G GG G G ",
" G GG G GG G G",
"GG GG Gg g GG ",
" G g g g G ",
"GGG g ggGG GGGG",
" g gg g ",
" g g gGG ",
" g g g ",
" ggg ");
const array string: big_bush_pic is [](
" G G GG GG ",
" GG GG gG GG ",
" G g gGg G gG ",
" GGgg gg g ggGG",
"GG gg ggg ",
" GgGG Gg gG GgG",
" ggG gg gg ggG",
"GG g gg g g ",
"GgG gg gG gg G G",
"Gg gg gb bG gG ",
" g b b b g ",
"GggG b bbgG ggGG",
" b bb b ",
" GGb b bgGG ",
" b b b ",
" bbb ");
const array string: wood_pic is [](
"bbbbbbbbbbbbbbrr",
"rrbbbbbrrrrbbbbb",
"bbrrrrrbbbbrrrbb",
"bbbbbbbbbbbbbbbb",
"rrrbbbbbbbbbbbbb",
"bbbrrbbbbrrrrrrb",
"bbbbbrrrrrbbbbbb",
"bbbbbbbbbbbbrrrr",
"rrrrbbbbbrrrbbbb",
"bbbbrrrrrbbbbbbb",
"bbbbbbbbbbbbbrrr",
"rrbbbbbbrrrrrbbb",
"bbbbbbbbbbbbbbbb",
"bbbrrrrbbbbbrrrb",
"rrrbbbbrrrrrbbbb",
"bbbbbbbbbbbbbbbb");
const array string: stone_pic is [](
"xxxxxxxxxWxxxxxx",
"xxxxxxxxxWxxxxxx",
"xxxxxxxxxWxxxxxx",
"xxxxxxxxxWxxxxxx",
"WWWWWWWWWWWWWWWW",
"xxxWxxxxxxxxxxxx",
"xxxWxxxxxxxxxxxx",
"xxxWxxxxxxxxxxxx",
"xxxWxxxxxxxxxxxx",
"xxxWxxxxxxxxxxxx",
"WWWWWWWWWWWWWWWW",
"xxxxxxxxxxxxWxxx",
"xxxxxxxxxxxxWxxx",
"xxxxxxxxxxxxWxxx",
"xxxxxxxxxxxxWxxx",
"WWWWWWWWWWWWWWWW");
const array string: gray_pic is [](
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxx");
const array string: water_pic is [](
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB");
const array string: bed_left_pic is [](
" bbbb",
" bbbb",
" bbbb",
" bbbb",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bbbb",
" bbbb",
" bbbb",
" bbbb");
const array string: bed_right_pic is [](
"bbbb ",
"bbbb ",
"bbbb ",
"bbbb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
" bb ",
"bbbb ",
"bbbb ",
"bbbb ",
"bbbb ");
const array string: bed_top_pic is [](
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
"bbbb bbbb",
"bbbbbbbbbbbbbbbb",
"bbbbbbbbbbbbbbbb",
"bbbb bbbb");
const array string: bed_bottom_pic is [](
"bbbb bbbb",
"bbbbbbbbbbbbbbbb",
"bbbbbbbbbbbbbbbb",
"bbbb bbbb",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ");
const array string: bed_white_middle_pic is [](
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW",
"WWWWWWWWWWWWWWWW");
const array string: bed_red_middle_pic is [](
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR",
"RRRRRRRRRRRRRRRR");
const array string: bed_blue_middle_pic is [](
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB",
"BBBBBBBBBBBBBBBB");
const array string: bed_purple_middle_pic is [](
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm",
"mmmmmmmmmmmmmmmm");
const array string: bed_yellow_middle_pic is [](
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY",
"YYYYYYYYYYYYYYYY");
const array string: chain_pic is [](
" BBB BB",
" B B B ",
" B BBBBB ",
" BB B B ",
" BBBB BB",
" BB ",
" BBB ",
" B B B ",
" B B ",
" B B B ",
" BBB ",
" BBBBB BB",
" BB B B ",
" B BBBBB ",
" B B B ",
" BBB BB");
const array string: k_pic is [](
" WW ",
" W ",
" W ",
" W WW ",
" W WW ",
" WWW ",
" W WW ",
" WW WW ");
const array string: b_pic is [](
" WW ",
" W ",
" W ",
" WWWW ",
" W W ",
" W W ",
" W W ",
" W WWW ");
const array string: up_pic is [](
" WddW ",
" WdddW ",
" WddddW ",
" WWWWWWWdddddW ",
" WW WdddddW ",
" WdW WdddddW ",
" WddW WdddddW ",
" WdddW WdddddWWWW",
" WddddW WddddW ",
" WWWWWWWdddddW WdddW ",
" WW WdddddW WddW ",
" WdW WdddddW WdW ",
" WddW WdddddW WW ",
" WdddW WdddddWWWWWWW ",
" WddddW WddddW ",
"WWWWWWWdddddW WdddW W",
"WW WdddddW WddW W ",
"WdW WdddddW WdW W ",
"WddW WdddddW WW W ",
"WdddW WdddddWWWWWWW W ",
"WddddW WddddW W ",
"WdddddW WdddW W ",
" WdddddW WddW W ",
" WdddddW WdW W ",
" WdddddW WW W ",
" WdddddWWWWWWW W ",
" WddddW W ",
" WdddW W ",
" WddW W ",
" WdW W ",
" WW W ",
" WWWWWW ");
const array string: down_pic is [](
" WWWWWWWWWWWWWWWWWWWWW",
" WW ",
" WdW ",
" WddW ",
" WdddW W ",
" WddddW W ",
" WdddddWWWWWWW W ",
" WdddddW WW W W ",
" WdddddW WdW W W ",
" WdddddW WddW W W ",
" WdddddW WdddW WW ",
"WdddddW WddddW WWWWW ",
"WddddW WdddddWWWWWWW ",
"WdddW WdddddW WW ",
"WddW WdddddW WdW ",
"WdW WdddddW WddW ",
"WW WdddddW WdddW ",
"WWWWWWWdddddW WddddW ",
" WddddW WdddddWWWWWWW ",
" WdddW WdddddW WW ",
" WddW WdddddW WdW ",
" WdW WdddddW WddW ",
" WW WdddddW WdddW ",
" WWWWWWWdddddW WddddW ",
" WddddW WdddddWWW",
" WdddW WdddddW ",
" WddW WdddddW ",
" WdW WdddddW ",
" WW WdddddW ",
" WWWWWWWdddddW ",
" WddddW ",
" WdddW ");
const array string: big_spider_pic is [](
" B B ",
" B B ",
" B B ",
" B B ",
" B B ",
"BBB B B BBB",
" BBBWWWWBBB ",
" WWWWWW ",
" WWWWWW ",
" BBBWWWWBBB ",
"BBB B B BBB",
" B B ",
" B B ",
" B B ",
" B B ",
" B B ");
const array string: small_spider_pic is [](
" ",
" B B ",
" B B ",
" B B ",
" B B ",
" BBB B B BBB ",
" BBBWWBBB ",
" WWWW ",
" BBBWWBBB ",
" BBB B B BBB ",
" B B ",
" B B ",
" B B ",
" B B ",
" ",
" ");
const array string: fairy_pic is [](
" xxxx YYYYY xxxx ",
" xxccxx YYYYYYY xxccxx",
" xccccxx YYWWWWWYY xxccccx",
" xcccccxx YYWBWBWYY xxcccccx",
" xxcccccxx YYWWWWWYY xxcccccxx",
" xccccccxx YYWOWOWYY xxccccccx ",
" xxccBcBccxx XWWOWWX xxcccccccxx",
" xcccccccccxxXXWWWXXxxcccccccccx",
" xccBcWcBcccWWWWWWWWWccccccccccx",
" xxcccRccccWWRRWWWRRWWccccccccxx",
" xccBRBccWWRRRRWRRRRWWcccccccx ",
" xxcccRccWWWRRRRWRRRRWWWccccccxx",
" xccccRcWWWcxRRWWWRRxcWWWccccccx",
" xccccRWWWcxxXWWWWWXxxcWWWWccccx",
" xxccWWWWcxx XWWYWWX xxcWWWWccxx",
" xccWWWcxx XWWWWWWWX xxcWWWccx ",
" xxcccccxx XRRRRRRRRRX xxcccccxx",
" xcccccxx XWWRRRRRWWX xxcccccx",
" xccccxx XWWWRRRWWWX xxccccx",
" xxccxx XWWWWRWWWWX xxccxx",
" xxxx XWWWXWWWX xxxx ",
" XWWWXWWWX ",
" XWWWXWWWX ",
" XWWWXWWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWXWWX ",
" XWWWXWWWX ");
const array string: large_gem_pic is [](
" ",
" RRRR RRRR ",
" RrrrrR RrrrrR ",
"RrrrrrrRRrrrrrrR",
"RrrrrrrrrrrrrrrR",
"RrrrrrrrrrrrrrrR",
"RrrrrrrrrrrrrrrR",
"RrrrrrrrrrrrrrrR",
" RrrrrrrrrrrrrR ",
" RrrrrrrrrrrR ",
" RrrrrrrrrR ",
" RrrrrrrR ",
" RrrrrR ",
" RrrR ",
" RR ",
" ");
const array string: floor_pic is [](
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ");
const array string: player_pic is [](
" bbbb ",
" bbbbbb ",
" bBOOBb ",
" OOOOOO ",
" OWWWWO ",
" OOOO ",
" xbbbbbbbbx ",
" xxbbbbbbbbxx ",
" xx bbbbbbbb xx ",
"Ox bbbbbbbb xO",
"OO bbbbbbbb OO",
" YY YY ",
" YY YY ",
" YY YY ",
" YY YY ",
" rrrr rrrr ");
const func PRIMITIVE_WINDOW: createPixmap (in array string: pattern) is
return createPixmap(pattern, PIXMAP_SIZE div length(pattern), black);
const bstring: castleData is bstring(getf(dir(PROGRAM) & "/castle.dat"));
const proc: initRoomData is func
local
var file: dat_file is STD_NULL;
var integer: number is 0;
var integer: line is 0;
var directionType: direction is NORTH;
begin
dat_file := openStriFile(str(castleData));
for number range 1 to MAX_ROOM do
for line range 1 to ROOM_LINES do
room[number].data[line] := getln(dat_file);
end for;
for line range 1 to 5 do
room[number].description[line] := getln(dat_file);
end for;
for direction range NORTH to DOWN do
read(dat_file, room[number].exits[direction]);
end for;
end for;
close(dat_file);
end func;
const proc: initMonster (
in monsterType: monster_ident,
in string: monster_adjective,
in string: monster_name,
in array string: monster_pic,
in integer: monster_line,
in integer: monster_column,
in integer: monster_attack,
in integer: monster_strength,
in integer: monster_room_num) is func
begin
monster[monster_ident].ident := monster_ident;
monster[monster_ident].adjective := monster_adjective;
monster[monster_ident].name := monster_name;
monster[monster_ident].picture := monster_pic;
monster[monster_ident].pixmap := PRIMITIVE_WINDOW.value;
monster[monster_ident].yPos := pred(monster_line) * PIXMAP_SIZE;
monster[monster_ident].xPos := pred(monster_column) * PIXMAP_SIZE;
monster[monster_ident].attack := monster_attack;
monster[monster_ident].strength := monster_strength;
monster[monster_ident].room_num := monster_room_num;
monster[monster_ident].direction := NORTH;
monster[monster_ident].living := TRUE;
end func;
const proc: initMonsterData is func
begin
initMonster(ANGRY_DEMON1, "Angry", "Demon", demon_pic, 7, 13, 5, 160, THRONE_ROOM);
initMonster(ANGRY_DEMON2, "Angry", "Demon", demon_pic, 10, 6, 5, 160, KNIGHTS_HALL);
initMonster(UGLY_OGRE1, "Ugly", "Ogre", ogre_pic, 9, 13, 4, 80, WEST_BALLROOM);
initMonster(UGLY_OGRE2, "Ugly", "Ogre", ogre_pic, 12, 12, 4, 80, UPPER_HALL_EAST);
initMonster(BIG_SPIDER, "Big", "Spider", big_spider_pic, 14, 18, 3, 80, MAZE73);
initMonster(SMALL_SPIDER, "Small", "Spider", small_spider_pic, 5, 17, 1, 60, MAZE70);
initMonster(SNAKE, "", "Snake", snake_pic, 14, 17, 3, 60, GARDEN_NORTH);
initMonster(BAT, "", "Bat", bat_pic, 7, 18, 2, 40, WINE_CELLAR);
initMonster(VAMPIRE, "", "Vampire", vampire_pic, 10, 24, 0, 0, CORRIDOR28);
initMonster(FAIRY1, "", "Fairy", fairy_pic, 10, 1, 0, 0, CORRIDOR52);
initMonster(FAIRY2, "", "Fairy", fairy_pic, 1, 12, 0, 0, CORRIDOR54);
initMonster(DOOR1, "", "Door", grating_pic, 15, 9, 0, 0, WINE_CELLAR);
initMonster(DOOR2, "", "", grating_pic, 15, 10, 0, 0, WINE_CELLAR);
initMonster(DOOR3, "", "Door", grating_pic, 9, 14, 0, 0, DUNGEON_ENTRANCE);
initMonster(DOOR4, "", "", grating_pic, 10, 14, 0, 0, DUNGEON_ENTRANCE);
end func;
const func itemType: (attr itemType) conv (in char: ch) is func
result
var itemType: item_ident is NO_ITEM;
local
var integer: number is 0;
begin
number := succ(ord(ch) - ord('a'));
if number >= ord(MIN_ITEM) and number <= ord(MAX_ITEM) then
item_ident := itemType conv number;
end if;
end func;
const func char: (attr char) conv (in itemType: anItem) is
return chr(pred(ord('a') + ord(anItem)));
const proc: initItem (
in itemType: item_ident,
in string: item_name,
in array string: item_pic,
in integer: item_line,
in integer: item_column,
in integer: item_room_num) is func
begin
item[item_ident].ident := item_ident;
item[item_ident].name := item_name;
item[item_ident].picture := item_pic;
item[item_ident].pixmap := PRIMITIVE_WINDOW.value;
item[item_ident].yPos := pred(item_line) * PIXMAP_SIZE;
item[item_ident].xPos := pred(item_column) * PIXMAP_SIZE;
item[item_ident].room_num := item_room_num;
if item_room_num <> NO_ROOM then
room[item_room_num].data[item_line] @:= [item_column] char conv item_ident;
end if;
end func;
const proc: initItemData is func
begin
initItem(BOOK, "Book", book_pic, 11, 11, NO_ROOM);
initItem(CRYSTAL_BALL, "Crystal Ball", crystal_ball_pic, 13, 10, LABORATORY);
initItem(GLASSES, "Eye Glasses", glasses_pic, 12, 18, NO_ROOM);
initItem(HELMET, "Helmet", helmet_pic, 5, 12, GUARDS_HALL);
initItem(KEY, "Key", key_pic, 7, 12, NO_ROOM);
initItem(LAMP, "Lamp", lamp_pic, 14, 19, GARDEN_NORTH);
initItem(MAGIC_WAND, "Magic Wand", magic_wand_pic, 9, 4, KNIGHTS_HALL);
initItem(SWORD, "Sword", sword_pic, 5, 11, MUSEUM);
initItem(WINE_FLASK, "Wine Flask", flask_pic, 11, 8, NO_ROOM);
initItem(CROWN, "Crown", crown_pic, 5, 9, THRONE_ROOM);
initItem(DIAMOND, "Diamond", diamond_pic, 10, 13, EMPTY_ROOM);
initItem(FANCY_GOBLET, "Fancy Goblet", goblet_pic, 14, 6, WEST_DINING_ROOM);
initItem(GOLDBAR, "Goldbar", goldbar_pic, 14, 23, MAZE74);
initItem(HARP, "Harp", harp_pic, 8, 16, EAST_TOWER_TOP);
initItem(HOLY_CROSS, "Holy Cross", holy_cross_pic, 13, 15, RED_ROOM);
initItem(HOURGLASS, "Hourglass", hourglass_pic, 14, 6, UPPER_HALL_WEST);
initItem(JADE_FIGURINE, "Jade Figurine", jade_figurine_pic, 10, 13, GUEST_ROOM);
initItem(LARGE_GEM, "Large Gem", large_gem_pic, 10, 12, NO_ROOM);
initItem(NECKLACE, "Necklace", necklace_pic, 9, 12, NO_ROOM);
initItem(RUBYS, "Ruby", ruby_pic, 16, 4, CASTLE_WALL);
initItem(SCEPTER, "Scepter", scepter_pic, 10, 12, SECRET_ROOM);
initItem(SILVER_BARS, "Silver Bars", silver_bars_pic, 8, 7, LOWER_BATTLEMENT);
end func;
const proc: initPlayerData is func
begin
player.pixmap := createPixmap(player_pic);
player.xPos := 13 * PIXMAP_SIZE;
player.yPos := 14 * PIXMAP_SIZE;
player.saved_pixmap := PRIMITIVE_WINDOW.value;
player.saved_xPos := 0;
player.saved_yPos := 0;
player.room := COURTYARD;
player.direction := SOUTH;
player.inventory := itemSet.EMPTY_SET;
player.strength := MAX_STRENGTH;
player.living := TRUE;
end func;
const proc: loadHighScore is func
local
var file: aFile is STD_NULL;
begin
aFile := open("castle.scr", "r");
if aFile <> STD_NULL then
read(aFile, highScore.points);
read(aFile, highScore.name);
close(aFile);
else
highScore.name := "";
highScore.points := 0;
end if;
end func;
const proc: saveHighScore is func
local
var file: aFile is STD_NULL;
begin
aFile := open("castle.scr", "w");
if aFile <> STD_NULL then
write(aFile, highScore.points);
write(aFile, " ");
writeln(aFile, highScore.name);
close(aFile);
end if;
end func;
const proc: initGame is func
begin
query_pixmap := createPixmap(query_pic);
wall_pixmap := createPixmap(wall_pic);
colored_wall1_pixmap := createPixmap(colored_wall1_pic);
colored_wall2_pixmap := createPixmap(colored_wall2_pic);
vertical_pixmap := createPixmap(vertical_pic);
horizontal_pixmap := createPixmap(horizontal_pic);
left_upper_pixmap := createPixmap(left_upper_pic);
right_upper_pixmap := createPixmap(right_upper_pic);
left_lower_pixmap := createPixmap(left_lower_pic);
right_lower_pixmap := createPixmap(right_lower_pic);
railing_pixmap := createPixmap(railing_pic);
gate_pixmap := createPixmap(gate_pic);
small_bush_pixmap := createPixmap(small_bush_pic);
big_bush_pixmap := createPixmap(big_bush_pic);
statue_pixmap := createPixmap(statue_pic);
fountain_pixmap := createPixmap(fountain_pic);
wood_pixmap := createPixmap(wood_pic);
stone_pixmap := createPixmap(stone_pic);
gray_pixmap := createPixmap(gray_pic);
water_pixmap := createPixmap(water_pic);
bed_left_pixmap := createPixmap(bed_left_pic);
bed_right_pixmap := createPixmap(bed_right_pic);
bed_top_pixmap := createPixmap(bed_top_pic);
bed_bottom_pixmap := createPixmap(bed_bottom_pic);
bed_white_middle_pixmap := createPixmap(bed_white_middle_pic);
bed_red_middle_pixmap := createPixmap(bed_red_middle_pic);
bed_blue_middle_pixmap := createPixmap(bed_blue_middle_pic);
bed_purple_middle_pixmap := createPixmap(bed_purple_middle_pic);
bed_yellow_middle_pixmap := createPixmap(bed_yellow_middle_pic);
chain_pixmap := createPixmap(chain_pic);
k_pixmap := createPixmap(k_pic);
b_pixmap := createPixmap(b_pic);
floor_pixmap := createPixmap(floor_pic);
eye_pixmap := createPixmap(eye_pic);
hand_pixmap := createPixmap(hand_pic);
take_pixmap := createPixmap(take_pic);
drop_pixmap := createPixmap(drop_pic);
load_pixmap := createPixmap(load_pic);
save_pixmap := createPixmap(save_pic);
exit_pixmap := createPixmap(exit_pic);
stair_up.pixmap := createPixmap(up_pic);
stair_up.name := "Stairs up";
stair_down.pixmap := createPixmap(down_pic);
stair_down.name := "Stairs down";
message := 0 times "";
exitGame := FALSE;
flaskFilled := FALSE;
initRoomData;
initMonsterData;
initItemData;
initPlayerData;
loadHighScore;
end func;
const proc: displayBox (in color: boxColor) is func
local
const integer: width is 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE;
const integer: height is 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE;
begin
hline(1, 0, width - 2, boxColor);
vline(0, 1, height - 2, boxColor);
hline(1, height - 1, width - 2, boxColor);
vline(width - 1, 1, height - 2, boxColor);
point(1, 1, boxColor);
point(width - 2, 1, boxColor);
point(width - 2, height - 2, boxColor);
point(1, height - 2, boxColor);
end func;
const func PRIMITIVE_WINDOW: getPixmap (inout graphObj: currObject) is func
result
var PRIMITIVE_WINDOW: pixmap is PRIMITIVE_WINDOW.value;
begin
if currObject.pixmap = PRIMITIVE_WINDOW.value then
currObject.pixmap := createPixmap(currObject.picture,
PIXMAP_SIZE div length(currObject.picture), black);
end if;
pixmap := currObject.pixmap;
end func;
const proc: displayRoom (in roomType: current_room) is func
local
var integer: line is 0;
var integer: column is 0;
var char: ch is ' ';
var PRIMITIVE_WINDOW: field_pixmap is PRIMITIVE_WINDOW.value;
var itemType: item_ident is NO_ITEM;
var integer: number is 0;
begin
for line range 1 to ROOM_LINES do
for column range 1 to length(current_room.data[line]) do
ch := current_room.data[line][column];
if ch <> ' ' then
case ch of
when {'#'}: field_pixmap := wall_pixmap;
when {':'}: field_pixmap := colored_wall1_pixmap;
when {';'}: field_pixmap := colored_wall2_pixmap;
when {'|'}: field_pixmap := vertical_pixmap;
when {'-'}: field_pixmap := horizontal_pixmap;
when {','}: field_pixmap := left_upper_pixmap;
when {'.'}: field_pixmap := right_upper_pixmap;
when {'`'}: field_pixmap := left_lower_pixmap;
when {'''}: field_pixmap := right_lower_pixmap;
when {'>'}: field_pixmap := railing_pixmap;
when {'='}: field_pixmap := gate_pixmap;
when {'+'}: field_pixmap := small_bush_pixmap;
when {'*'}: field_pixmap := big_bush_pixmap;
when {'$'}: field_pixmap := statue_pixmap;
when {'?'}: field_pixmap := fountain_pixmap;
when {'@'}: field_pixmap := wood_pixmap;
when {'&'}: field_pixmap := stone_pixmap;
when {'%'}: field_pixmap := gray_pixmap;
when {'~'}: field_pixmap := water_pixmap;
when {']'}: field_pixmap := bed_left_pixmap;
when {'['}: field_pixmap := bed_right_pixmap;
when {'_'}: field_pixmap := bed_top_pixmap;
when {'^'}: field_pixmap := bed_bottom_pixmap;
when {'W'}: field_pixmap := bed_white_middle_pixmap;
when {'R'}: field_pixmap := bed_red_middle_pixmap;
when {'N'}: field_pixmap := bed_blue_middle_pixmap;
when {'P'}: field_pixmap := bed_purple_middle_pixmap;
when {'Y'}: field_pixmap := bed_yellow_middle_pixmap;
when {'{'}: field_pixmap := chain_pixmap;
when {'K'}: field_pixmap := k_pixmap;
when {'B'}: field_pixmap := b_pixmap;
when {'U'}: field_pixmap := stair_up.pixmap;
when {'D'}: field_pixmap := stair_down.pixmap;
when {' '}: field_pixmap := floor_pixmap;
when {'a' .. 'z'}:
item_ident := itemType conv ch;
if item_ident <> NO_ITEM then
field_pixmap := getPixmap(item[item_ident]);
else
field_pixmap := query_pixmap;
end if;
otherwise:
field_pixmap := query_pixmap;
write("undefined char no ");
writeln(ord(ch));
end case;
put(curr_win, BORDER_DIST + pred(column) * PIXMAP_SIZE,
BORDER_DIST + pred(line) * PIXMAP_SIZE, field_pixmap);
end if;
end for;
end for;
rect(8, BUTTON_YPOS_MIN, 300, 50, black);
color(white, black);
for number range 1 to length(current_room.description) do
setPos(screen, pred(BUTTON_TEXT_LINE1 + number), 2);
write(screen, current_room.description[number]);
end for;
end func;
const proc: displayObj (inout graphObj: currObject) is func
begin
put(curr_win, BORDER_DIST + currObject.saved_xPos,
BORDER_DIST + currObject.saved_yPos, currObject.saved_pixmap);
currObject.saved_pixmap := getPixmap(BORDER_DIST + currObject.xPos,
BORDER_DIST + currObject.yPos, PIXMAP_SIZE, PIXMAP_SIZE);
put(curr_win, BORDER_DIST + currObject.xPos,
BORDER_DIST + currObject.yPos, getPixmap(currObject));
currObject.saved_xPos := currObject.xPos;
currObject.saved_yPos := currObject.yPos;
end func;
const proc: displayMonster is func
local
var monsterType: monster_ident is NO_MONSTER;
begin
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room then
displayObj(monster[monster_ident]);
end if;
end for;
end func;
const proc: objectLegend (inout graphObj: currObject, in integer: line) is func
begin
put(curr_win, LEGEND_XPOS, LEGEND_YPOS_MIN + pred(line) * PIXMAP_SIZE, getPixmap(currObject));
color(white, black);
setPos(screen, 2 * line, LEGEND_COLUMN);
if currObject.adjective <> "" then
write(screen, currObject.adjective & " " & currObject.name);
else
write(screen, currObject.name);
end if;
end func;
const proc: displayLegend is func
local
var monsterType: monster_ident is NO_MONSTER;
var itemType: item_ident is NO_ITEM;
var integer: line is 1;
begin
rect(LEGEND_XPOS, LEGEND_YPOS_MIN, 200, 576, black);
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room and
monster[monster_ident].name <> "" then
objectLegend(monster[monster_ident], line);
incr(line);
end if;
end for;
for item_ident range MIN_ITEM to MAX_ITEM do
if item[item_ident].room_num = player.room and
not item_ident in player.inventory then
objectLegend(item[item_ident], line);
incr(line);
end if;
end for;
if room[player.room].exits[UP] <> 0 then
objectLegend(stair_up, line);
incr(line);
end if;
if room[player.room].exits[DOWN] <> 0 then
objectLegend(stair_down, line);
incr(line);
end if;
end func;
const func integer: sizeOfLegend is func
result
var integer: line is 0;
local
var monsterType: monster_ident is NO_MONSTER;
var itemType: item_ident is NO_ITEM;
begin
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room and
monster[monster_ident].name <> "" then
incr(line);
end if;
end for;
for item_ident range MIN_ITEM to MAX_ITEM do
if item[item_ident].room_num = player.room and
not item_ident in player.inventory then
incr(line);
end if;
end for;
if room[player.room].exits[UP] <> 0 then
incr(line);
end if;
if room[player.room].exits[DOWN] <> 0 then
incr(line);
end if;
end func;
const proc: collectedTreasures is func
local
var itemType: item_ident is NO_ITEM;
var integer: line is 1;
begin
rect(LEGEND_XPOS, 0, width(curr_win) - LEGEND_XPOS,
BORDER_DIST + PIXMAP_SIZE * 14, black);
color(white, black);
setPos(screen, 2 * line - 1, LEGEND_COLUMN);
write(screen, "You have collected");
setPos(screen, 2 * line, LEGEND_COLUMN);
write(screen, "these Treasures");
incr(line);
for item_ident range CROWN to MAX_ITEM do
if item_ident in player.inventory or
item[item_ident].room_num = COURTYARD then
objectLegend(item[item_ident], line);
incr(line);
end if;
end for;
if line = 2 then
color(white, black);
setPos(screen, 2 * line, LEGEND_COLUMN);
write(screen, "NONE");
end if;
end func;
const proc: killedMonsters is func
local
var monsterType: monster_ident is NO_MONSTER;
var integer: line is 16;
begin
rect(LEGEND_XPOS, 15 * PIXMAP_SIZE, width(curr_win) - LEGEND_XPOS,
BORDER_DIST + PIXMAP_SIZE * 7, black);
color(white, black);
setPos(screen, 2 * line - 1, LEGEND_COLUMN);
write(screen, "You have killed");
setPos(screen, 2 * line, LEGEND_COLUMN);
write(screen, "these Monsters");
incr(line);
if not monster[ANGRY_DEMON1].living or not monster[ANGRY_DEMON2].living then
objectLegend(monster[ANGRY_DEMON1], line);
if not monster[ANGRY_DEMON1].living and not monster[ANGRY_DEMON2].living then
setPos(screen, 2 * line, LEGEND_COLUMN + 15);
write(screen, "two times");
end if;
incr(line);
end if;
if not monster[UGLY_OGRE1].living or not monster[UGLY_OGRE2].living then
objectLegend(monster[UGLY_OGRE1], line);
if not monster[UGLY_OGRE1].living and not monster[UGLY_OGRE2].living then
setPos(screen, 2 * line, LEGEND_COLUMN + 15);
write(screen, "two times");
end if;
incr(line);
end if;
for monster_ident range BIG_SPIDER to BAT do
if not monster[monster_ident].living and
monster[monster_ident].name <> "" then
objectLegend(monster[monster_ident], line);
incr(line);
end if;
end for;
if line = 17 then
color(white, black);
setPos(screen, 2 * line, LEGEND_COLUMN);
write(screen, "NONE");
end if;
end func;
const func integer: getInventoryStartLine is func
result
var integer: startLine is 0;
begin
startLine := succ(sizeOfLegend);
if startLine < INVENTORY_LINE then
startLine := INVENTORY_LINE;
end if;
end func;
const proc: displayInventoryItem (in integer: item_num) is func
local
var integer: item_line is 1;
var itemType: item_ident is NO_ITEM;
begin
for item_ident range MIN_ITEM to MAX_ITEM do
if item_ident in player.inventory then
if item_line = item_num then
objectLegend(item[item_ident], getInventoryStartLine + item_line);
end if;
incr(item_line);
end if;
end for;
end func;
const proc: displayInventoryList is func
local
var integer: line is 0;
var itemType: item_ident is NO_ITEM;
begin
line := succ(getInventoryStartLine);
if player.inventory = itemSet.EMPTY_SET then
color(white, black);
setPos(screen, 2 * line, LEGEND_COLUMN);
write(screen, "Nothing");
incr(line);
else
for item_ident range MIN_ITEM to MAX_ITEM do
if item_ident in player.inventory then
objectLegend(item[item_ident], line);
incr(line);
end if;
end for;
end if;
end func;
const proc: displayInventory is func
local
var integer: startLine is 0;
begin
startLine := getInventoryStartLine;
rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
182, PIXMAP_SIZE * (card(player.inventory) + 2), black);
color(white, black);
setPos(screen, 2 * startLine, LEGEND_COLUMN);
write(screen, "Inventory");
displayInventoryList;
end func;
const proc: displayMessage is func
local
var integer: number is 0;
begin
rect(186, BUTTON_YPOS_MIN, 346, 70, black);
color(screen, white, black);
for number range 1 to length(message) do
setPos(screen, BUTTON_TEXT_LINE1 + pred(number), 32);
write(screen, message[number]);
end for;
end func;
const proc: displayCommands (in PRIMITIVE_WINDOW: bmp) is func
begin
put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN, load_pixmap);
setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_1_COLUMN);
write(screen, "Load");
put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN + 32, save_pixmap);
setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_1_COLUMN);
write(screen, "Save");
put(curr_win, BUTTONS_1_XPOS, BUTTON_YPOS_MIN + 64, exit_pixmap);
setPos(screen, BUTTON_TEXT_LINE1 + 4, BUTTONS_1_COLUMN);
write(screen, "Exit");
put(curr_win, BUTTONS_2_XPOS, BUTTON_YPOS_MIN, take_pixmap);
setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_2_COLUMN);
write(screen, "Take");
put(curr_win, BUTTONS_2_XPOS, BUTTON_YPOS_MIN + 32, drop_pixmap);
setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_2_COLUMN);
write(screen, "Drop");
put(curr_win, BUTTONS_3_XPOS, BUTTON_YPOS_MIN, eye_pixmap);
setPos(screen, BUTTON_TEXT_LINE1, BUTTONS_3_COLUMN);
write(screen, "Look");
put(curr_win, BUTTONS_3_XPOS, BUTTON_YPOS_MIN + 32, hand_pixmap);
setPos(screen, BUTTON_TEXT_LINE1 + 2, BUTTONS_3_COLUMN);
write(screen, "Use");
end func;
const proc: displayAll is func
begin
clear(curr_win, black);
displayRoom(room[player.room]);
displayMessage;
displayMonster;
displayObj(player);
displayLegend;
displayInventory;
displayCommands(curr_win);
displayBox(white);
end func;
const proc: floodTrap is func
local
var string: s1 is "";
var string: s2 is "";
var integer: number is 0;
begin
s1 := room[WINDING_PASSAGE3].data[9];
s2 := room[WINDING_PASSAGE3].data[10];
s1 @:= [12] '#';
s1 @:= [24] '#';
s2 @:= [12] '#';
s2 @:= [24] '#';
room[WINDING_PASSAGE3].data[9] := s1;
room[WINDING_PASSAGE3].data[10] := s2;
for number range 13 to 23 do
s1 @:= [number] '~';
s2 @:= [number] '~';
room[WINDING_PASSAGE3].data[9] := s1;
room[WINDING_PASSAGE3].data[10] := s2;
displayAll;
end for;
end func;
const proc: checkRoom is func
begin
case player.room of
when {WINDING_PASSAGE1}:
room[WINDING_PASSAGE2].data[18] := " #################### ";
when {WINDING_PASSAGE3}:
room[WINDING_PASSAGE2].data[18] := " #################### ";
if player.xPos = 544 and not NECKLACE in player.inventory then
message := [] ("You have sprung a Trap!!");
displayAll;
floodTrap;
message &:= [] ("The room has filled with water and you drowned!");
displayAll;
player.living := FALSE;
end if;
when {SECRET_ROOM}:
room[WINDING_PASSAGE2].data[18] := " ######## ########## ";
when {WINDING_PASSAGE2}:
if room[WINDING_PASSAGE2].data[18][12] = '#' and player.yPos > 512 then
room[WINDING_PASSAGE2].data[18] := " ######## ########## ";
end if;
when {WEST_TOWER_MIDDLE}:
room[SORCERERS_QUARTERS].data[8] := "###### |# ";
room[SORCERERS_QUARTERS].data[9] := " |# ";
room[SORCERERS_QUARTERS].data[10] := " |# ";
room[SORCERERS_QUARTERS].data[11] := "###### |# ";
when {LABORATORY}:
room[SORCERERS_QUARTERS].data[8] := "###### #####";
room[SORCERERS_QUARTERS].data[9] := " ";
room[SORCERERS_QUARTERS].data[10] := " ";
room[SORCERERS_QUARTERS].data[11] := "###### #####";
when {SORCERERS_QUARTERS}:
if room[SORCERERS_QUARTERS].data[10][20] = '#' and player.xPos > 544 then
room[SORCERERS_QUARTERS].data[8] := "###### #####";
room[SORCERERS_QUARTERS].data[9] := " ";
room[SORCERERS_QUARTERS].data[10] := " ";
room[SORCERERS_QUARTERS].data[11] := "###### #####";
end if;
end case;
end func;
const proc: hideItem (in itemObj: anItem) is func
local
var integer: line is 0;
var integer: column is 0;
begin
if anItem.room_num <> NO_ROOM then
line := succ(anItem.yPos div PIXMAP_SIZE);
column := succ(anItem.xPos div PIXMAP_SIZE);
room[anItem.room_num].data[line] @:= [column] ' ';
end if;
end func;
const proc: showItem (in itemObj: anItem) is func
local
var integer: line is 0;
var integer: column is 0;
begin
if anItem.room_num <> NO_ROOM then
line := succ(anItem.yPos div PIXMAP_SIZE);
column := succ(anItem.xPos div PIXMAP_SIZE);
room[anItem.room_num].data[line] @:= [column] char conv (anItem.ident);
end if;
end func;
const proc: loadGame is func
local
var file: load_file is STD_NULL;
var monsterType: monster_ident is NO_MONSTER;
var itemType: item_ident is NO_ITEM;
begin
if fileType("castle.sav") = FILE_REGULAR then
if isOkay([]("Do you want to load a saved game.", "This will end the current game?")) then
load_file := open("castle.sav", "r");
for monster_ident range MIN_MONSTER to MAX_MONSTER do
readln(load_file, monster[monster_ident].adjective);
readln(load_file, monster[monster_ident].xPos);
readln(load_file, monster[monster_ident].yPos);
readln(load_file, monster[monster_ident].strength);
readln(load_file, monster[monster_ident].direction);
readln(load_file, monster[monster_ident].living);
end for;
for item_ident range MIN_ITEM to MAX_ITEM do
hideItem(item[item_ident]);
readln(load_file, item[item_ident].xPos);
readln(load_file, item[item_ident].yPos);
readln(load_file, item[item_ident].room_num);
end for;
readln(load_file, player.xPos);
readln(load_file, player.yPos);
readln(load_file, player.room);
readln(load_file, player.direction);
readln(load_file, player.inventory);
readln(load_file, player.strength);
close(load_file);
message := [] ("Game Loaded Successful!");
for item_ident range MIN_ITEM to MAX_ITEM do
if item_ident not in player.inventory then
showItem(item[item_ident]);
end if;
end for;
player.saved_pixmap := PRIMITIVE_WINDOW.value;
checkRoom;
displayAll;
end if;
else
message := [] ("There Is No Saved Game To Load!");
displayMessage;
end if;
end func;
const proc: saveGame is func
local
var file: save_file is STD_NULL;
var monsterType: monster_ident is NO_MONSTER;
var itemType: item_ident is NO_ITEM;
begin
if fileType("castle.sav") = FILE_REGULAR then
if isOkay([]("Do you want to overwrite the", "game currently saved?")) then
removeFile("castle.sav");
end if;
end if;
if fileType("castle.sav") = FILE_ABSENT then
save_file := open("castle.sav", "w");
for monster_ident range MIN_MONSTER to MAX_MONSTER do
writeln(save_file, monster[monster_ident].adjective);
writeln(save_file, monster[monster_ident].xPos);
writeln(save_file, monster[monster_ident].yPos);
writeln(save_file, monster[monster_ident].strength);
writeln(save_file, monster[monster_ident].direction);
writeln(save_file, monster[monster_ident].living);
end for;
for item_ident range MIN_ITEM to MAX_ITEM do
writeln(save_file, item[item_ident].xPos);
writeln(save_file, item[item_ident].yPos);
writeln(save_file, item[item_ident].room_num);
end for;
writeln(save_file, player.xPos);
writeln(save_file, player.yPos);
writeln(save_file, player.room);
writeln(save_file, player.direction);
writeln(save_file, player.inventory);
writeln(save_file, player.strength);
close(save_file);
message := [] ("Game Saved Successful!");
displayMessage;
end if;
end func;
const func monsterType: searchMonster (in integer: xPos, in integer: yPos) is func
result
var monsterType: monsterFound is NO_MONSTER;
local
var monsterType: monster_ident is NO_MONSTER;
begin
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room and
xPos >= monster[monster_ident].xPos and
xPos < monster[monster_ident].xPos + PIXMAP_SIZE and
yPos >= monster[monster_ident].yPos and
yPos < monster[monster_ident].yPos + PIXMAP_SIZE then
monsterFound := monster_ident;
end if;
end for;
end func;
const func monsterType: hitMonster (in integer: xPos, in integer: yPos) is func
result
var monsterType: monsterMet is NO_MONSTER;
local
var monsterType: monster_ident is NO_MONSTER;
begin
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room and monster[monster_ident].living then
if abs(xPos - monster[monster_ident].xPos) < PIXMAP_SIZE and
abs(yPos - monster[monster_ident].yPos) < PIXMAP_SIZE then
monsterMet := monster_ident;
end if;
end if;
end for;
end func;
const func itemType: selectItem (in PRIMITIVE_WINDOW: symbol, in string: name, in integer: invSize) is func
result
var itemType: itemSelected is NO_ITEM;
local
var char: command is ' ';
var integer: startLine is 0;
var integer: position is 0;
var itemType: item_ident is NO_ITEM;
var integer: count is 0;
var boolean: getCommand is FALSE;
var integer: xPos is 0;
var integer: yPos is 0;
begin
if card(player.inventory) >= invSize then
startLine := getInventoryStartLine;
rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
PIXMAP_SIZE, PIXMAP_SIZE, black);
box(LEGEND_XPOS - 3, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE - 3,
187, succ(card(player.inventory)) * PIXMAP_SIZE + 6, light_red);
rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
150, PIXMAP_SIZE, light_gray);
put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
symbol);
color(white, black);
setPos(screen, 2 * startLine, LEGEND_COLUMN + 5);
write(screen, name);
displayInventoryList;
position := 0;
command := getc(KEYBOARD);
while command not in {' ', KEY_NL, KEY_ESC} do
getCommand := TRUE;
rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE,
150, PIXMAP_SIZE, black);
if position >= 1 then
displayInventoryItem(position);
else
put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
symbol);
color(white, black);
setPos(screen, 2 * startLine, LEGEND_COLUMN + 5);
write(screen, name);
end if;
if command = KEY_UP and position > 1 then
decr(position);
elsif command = KEY_DOWN and position < card(player.inventory) then
incr(position);
elsif command = KEY_MOUSE1 then
xPos := clickedXPos(KEYBOARD);
yPos := clickedYPos(KEYBOARD);
if xPos >= LEGEND_XPOS and xPos < LEGEND_XPOS + 128 and
yPos >= LEGEND_YPOS_MIN + startLine * PIXMAP_SIZE and
yPos <= LEGEND_YPOS_MIN + (startLine + card(player.inventory)) * PIXMAP_SIZE then
position := (yPos - LEGEND_YPOS_MIN - startLine * PIXMAP_SIZE) div 32 + 1;
else
position := 0;
end if;
command := ' ';
getCommand := FALSE;
end if;
rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE,
150, PIXMAP_SIZE, light_gray);
if position >= 1 then
displayInventoryItem(position);
else
put(curr_win, LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
symbol);
color(white, black);
setPos(screen, 2 * startLine, LEGEND_COLUMN + 5);
write(screen, name);
end if;
if getCommand then
command := getc(KEYBOARD);
end if;
end while;
rect(LEGEND_XPOS + PIXMAP_SIZE, LEGEND_YPOS_MIN + pred(startLine + position) * PIXMAP_SIZE,
150, PIXMAP_SIZE, black);
displayInventoryItem(position);
if position >= 1 and command in {' ', KEY_NL} then
count := 0;
for item_ident range MIN_ITEM to MAX_ITEM do
if item_ident in player.inventory then
incr(count);
if count = position then
itemSelected := item_ident;
end if;
end if;
end for;
end if;
rect(LEGEND_XPOS, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE,
182, PIXMAP_SIZE, black);
setPos(screen, 2 * startLine, LEGEND_COLUMN);
color(white, black);
write(screen, "Inventory");
box(LEGEND_XPOS - 3, LEGEND_YPOS_MIN + pred(startLine) * PIXMAP_SIZE - 3,
187, succ(card(player.inventory)) * PIXMAP_SIZE + 6, black);
end if;
end func;
const proc: dropItem (in itemType: item_ident) is func
local
var directionType: direction is NORTH;
var integer: column is 0;
var integer: line is 0;
begin
direction := player.direction;
repeat
if direction = NORTH then
line := player.yPos div PIXMAP_SIZE;
column := player.xPos div PIXMAP_SIZE + 1;
incr(direction);
elsif direction = SOUTH then
line := (player.yPos + STEP_SIZE) div PIXMAP_SIZE + 2;
column := player.xPos div PIXMAP_SIZE + 1;
incr(direction);
elsif direction = EAST then
line := player.yPos div PIXMAP_SIZE + 1;
column := (player.xPos + STEP_SIZE) div PIXMAP_SIZE + 2;
incr(direction);
elsif direction = WEST then
line := player.yPos div PIXMAP_SIZE + 1;
column := player.xPos div PIXMAP_SIZE;
direction := NORTH;
end if;
until line >= 1 and line <= ROOM_LINES and
column >= 1 and column <= ROOM_COLUMNS and
room[player.room].data[line][column] = ' ' and
hitMonster(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE) = NO_MONSTER or
direction = player.direction;
if room[player.room].data[line][column] = ' ' then
item[item_ident].xPos := pred(column) * PIXMAP_SIZE;
item[item_ident].yPos := pred(line) * PIXMAP_SIZE;
item[item_ident].room_num := player.room;
showItem(item[item_ident]);
excl(player.inventory, item_ident);
put(curr_win, BORDER_DIST + item[item_ident].xPos,
BORDER_DIST + item[item_ident].yPos, getPixmap(item[item_ident]));
displayLegend;
displayInventory;
else
displayInventory;
message := [] ("Something is in the way!");
displayMessage;
end if;
end func;
const proc: dropItem is func
local
var itemType: item_ident is NO_ITEM;
begin
item_ident := selectItem(drop_pixmap, "Drop", 1);
if item_ident <> NO_ITEM then
dropItem(item_ident);
end if;
end func;
const proc: useItem (in itemType: item_ident) is func
local
var boolean: done is FALSE;
begin
case item_ident of
when {BOOK}:
if GLASSES in player.inventory then
message := [] ("The book reads:",
" Wave Scepter");
else
message := [] ("You can't see well enough.",
"It's all Blurry.");
end if;
done := TRUE;
when {CRYSTAL_BALL}:
message := [] ("In the Crystal Ball....",
" You see a man in a winding passage, waving a Wand.");
done := TRUE;
when {HELMET}:
message := [] ("Ok. I'm wearing it.");
done := TRUE;
when {MAGIC_WAND}:
if player.room = WINDING_PASSAGE2 then
message := [] ("As you wave the WAND....",
" There is a *Puff* of smoke Revealing a Secret passage!");
room[WINDING_PASSAGE2].data[18] := " ######## ########## ";
elsif player.room = SORCERERS_QUARTERS then
message := [] ("As you wave the WAND....",
" There is a *Puff* of smoke Revealing a Secret passage!");
room[SORCERERS_QUARTERS].data[8] := "###### #####";
room[SORCERERS_QUARTERS].data[9] := " ";
room[SORCERERS_QUARTERS].data[10] := " ";
room[SORCERERS_QUARTERS].data[11] := "###### #####";
else
message := [] ("As you wave the WAND....",
" Nothing Happens!");
end if;
done := TRUE;
when {WINE_FLASK}:
if flaskFilled then
message := [] ("That was good!",
"I feel much better now!");
player.strength := MAX_STRENGTH;
else
message := [] ("You don't have any WATER!");
end if;
done := TRUE;
when {HARP}:
message := [] ("The Harp makes Beautiful Music!");
if player.room = CORRIDOR52 or player.room = CORRIDOR54 then
monster[FAIRY1].room_num := -1;
monster[FAIRY1].living := FALSE;
monster[FAIRY2].room_num := -1;
monster[FAIRY2].living := FALSE;
message := [] ("The fairy likes the music and leaves!");
end if;
done := TRUE;
when {HOLY_CROSS}:
if player.room = CORRIDOR28 then
monster[VAMPIRE].room_num := -1;
message := [] ("The vampire sees the holy cross and disappears!");
done := TRUE;
end if;
when {SCEPTER}:
if player.room = COURTYARD then
message := [] ("As you wave the scepter...",
"The Gate opens by itself!");
room[COURTYARD].data[18] := "########## ##########";
else
message := [] ("As you wave the SCEPTER....",
" Nothing Happens!");
end if;
done := TRUE;
end case;
if not done then
message := [] ("You look awful Silly waving that " & item[item_ident].name);
end if;
displayAll;
end func;
const proc: useItem is func
local
var itemType: item_ident is NO_ITEM;
begin
item_ident := selectItem(hand_pixmap, "Use", 1);
if item_ident <> NO_ITEM then
useItem(item_ident);
end if;
end func;
const func array string: getMonsterMessage (in monsterType: monster_ident) is func
result
var array string: message is 0 times "";
begin
case monster_ident of
when {ANGRY_DEMON1, ANGRY_DEMON2, UGLY_OGRE1, UGLY_OGRE2,
BIG_SPIDER, SMALL_SPIDER, SNAKE, BAT, VAMPIRE}:
if monster[monster_ident].living then
message := [] ("look " & monster[monster_ident].name & ":",
"The " & monster[monster_ident].name & " looks Mean!");
else
message := [] ("look " & monster[monster_ident].name & ":",
"The " & monster[monster_ident].name & " looks Dead!");
end if;
when {FAIRY1, FAIRY2}:
message := [] ("look " & monster[monster_ident].name & ":",
"The " & monster[monster_ident].name & " looks pretty but unhappy.");
when {DOOR1, DOOR2, DOOR3, DOOR4}:
message := [] ("look door:",
"It looks very Strong.");
end case;
end func;
const func array string: getItemMessage (in itemType: item_ident) is func
result
var array string: message is 0 times "";
begin
case item_ident of
when {BOOK}:
message := [] ("It is titled",
" 'The Gate'");
when {CRYSTAL_BALL}:
message := [] ("In the Crystal Ball....",
" You see a man in a winding passage, waving a Wand.");
when {GLASSES}:
message := [] ("They're Bifocals");
when {HELMET}:
message := [] ("It looks Tough!");
when {KEY}:
message := [] ("It looks Old!");
when {LAMP}:
message := [] ("It's lit Magically");
when {MAGIC_WAND}:
message := [] ("It looks Magical!");
when {SWORD}:
message := [] ("It looks Sharp!");
when {WINE_FLASK}:
if flaskFilled then
message := [] ("It's filled with water.");
else
message := [] ("It's empty.");
end if;
when {CROWN}:
message := [] ("It's made of Gold!");
when {DIAMOND}:
message := [] ("It looks Expensive!");
when {FANCY_GOBLET}:
message := [] ("It's made of Gold!");
when {GOLDBAR}:
message := [] ("It looks Expensive!");
when {HARP}:
message := [] ("It's made of Gold!");
when {HOLY_CROSS}:
message := [] ("It's made of Gold!");
when {HOURGLASS}:
message := [] ("It's made of Gold!");
when {JADE_FIGURINE}:
message := [] ("It looks Expensive!");
when {LARGE_GEM}:
message := [] ("It looks Expensive!");
when {NECKLACE}:
message := [] ("On the back it says:",
"Protection from Traps.");
when {RUBYS}:
message := [] ("They look Expensive!");
when {SCEPTER}:
message := [] ("It looks Expensive!");
when {SILVER_BARS}:
message := [] ("They look Expensive!");
end case;
end func;
const func integer: getScore is func
result
var integer: score is 0;
local
var monsterType: monster_ident is NO_MONSTER;
var itemType: item_ident is NO_ITEM;
begin
for monster_ident range MIN_MONSTER to BAT do
if not monster[monster_ident].living then
score +:= 100;
end if;
end for;
for item_ident range CROWN to MAX_ITEM do
if item_ident in player.inventory or
item[item_ident].room_num = COURTYARD then
score +:= 50;
end if;
end for;
if player.room = ESCAPED then
score +:= 100;
end if;
if score > highScore.points then
highScore.points := score;
highScore.name := player.name;
end if;
end func;
const proc: showStatus is func
local
var char: command is ' ';
begin
rect(BUTTONS_1_XPOS, BUTTON_YPOS_MIN, 272, 128, black);
box(BUTTONS_1_XPOS, BUTTON_YPOS_MIN, 272, 128, light_red);
color(screen, white, black);
if player.room = ESCAPED then
setPos(screen, BUTTON_TEXT_LINE1, 100);
write(screen, "You've Escaped the Castle!");
elsif player.living then
setPos(screen, BUTTON_TEXT_LINE1, 100);
write(screen, " Your current status:");
else
setPos(screen, BUTTON_TEXT_LINE1, 100);
write(screen, "You have failed to Escape!");
end if;
rect(LEGEND_XPOS, 0, width(curr_win) - LEGEND_XPOS, height(curr_win), black);
collectedTreasures;
killedMonsters;
setPos(screen, BUTTON_TEXT_LINE1 + 2, 105);
write(screen, "Your Score: " <& getScore);
setPos(screen, BUTTON_TEXT_LINE1 + 3, 104);
write(screen, "(1550 is perfect)");
saveHighScore;
setPos(screen, BUTTON_TEXT_LINE1 + 5, 104);
write(screen, "- Press any key -");
repeat
command := upper(getc(KEYBOARD));
if command in {'Y', 'N'} then
setPos(screen, BUTTON_TEXT_LINE1 + 6, 105);
write(screen, "(Except Y or N)");
end if;
until command not in {'Y', 'N'};
end func;
const proc: lookItemInRoom is func
local
var integer: xPos is 0;
var integer: yPos is 0;
var integer: line is 0;
var integer: column is 0;
var itemType: item_ident is NO_ITEM;
var monsterType: monster_ident is NO_MONSTER;
begin
xPos := clickedXPos(KEYBOARD);
yPos := clickedYPos(KEYBOARD);
xPos -:= BORDER_DIST;
yPos -:= BORDER_DIST;
line := succ(yPos div PIXMAP_SIZE);
column := succ(xPos div PIXMAP_SIZE);
if line >= 1 and line <= ROOM_LINES and
column >= 1 and column <= ROOM_COLUMNS then
case room[player.room].data[line][column] of
when {'#', '&'}:
if player.room = COURTYARD then
if highScore.name = "" then
message := [] ("look wall:",
"Writing on the wall says...",
"Highscore: " & str(highScore.points));
else
message := [] ("look wall:",
"Writing on the wall says...",
"Highscore: " & str(highScore.points) &
" by " & highScore.name);
end if;
displayMessage;
showStatus;
displayCommands(curr_win);
displayAll;
message := 0 times "";
elsif player.room = MAZE74 then
message := [] ("look wall:",
"The Wall Says:",
"Kevin Bales was here!");
else
message := [] ("look wall:",
"The WALLS are made of Gray Stone.");
end if;
when {':', ';'}:
message := [] ("look wall:",
"The walls are many colors!");
when {'K', 'B'}:
message := [] ("look wall:",
"The Wall Says:",
"Kevin Bales was here!");
when {'W'}:
message := [] ("look bed:",
"It's Old.");
when {'R'}:
message := [] ("look bed:",
"It's Red.");
when {'N'}:
message := [] ("look bed:",
"It's Blue.");
when {'P'}:
message := [] ("look bed:",
"It's Purple.");
when {'Y'}:
message := [] ("look bed:",
"It's Yellow.");
when {'U'}:
message := [] ("look staircase:",
"The Staircase leads up.");
when {'D'}:
message := [] ("look staircase:",
"The Staircase leads down.");
when {'='}:
message := [] ("look gate:",
"It looks very Strong.");
when {'>'}:
message := [] ("look balcony:",
"The balcony is made of stone.");
when {'?'}:
if player.room = GARDEN_SOUTH then
message := [] ("look fountain:",
"The fountain is filled with water.",
"But you can't see In it.");
elsif player.room = BALCONY then
if item[LARGE_GEM].room_num = NO_ROOM and not LARGE_GEM in player.inventory then
message := [] ("look fountain:",
"There is a BIG Gem in the Garden Fountain!");
else
message := [] ("look fountain:",
"The Garden Has A Fountain in the middle.");
end if;
end if;
when {'{'}:
message := [] ("look chains:",
"They look Magical!");
when {'$'}:
if item[NECKLACE].room_num = NO_ROOM and not NECKLACE in player.inventory then
message := [] ("look statue:",
"The statue is wearing a Necklace");
else
message := [] ("look statue:",
"The statue looks like The King!");
end if;
when {'%'}:
if player.room = KITCHEN then
message := [] ("look table:",
"It's made of Stone.");
elsif player.room = THRONE_ROOM then
message := [] ("look throne:",
"The throne is made of Stone.");
end if;
when {'@'}:
if player.room = CHEFS_QUARTERS then
if item[WINE_FLASK].room_num = NO_ROOM and not WINE_FLASK in player.inventory then
put(curr_win, BORDER_DIST + item[WINE_FLASK].xPos,
BORDER_DIST + item[WINE_FLASK].yPos, getPixmap(item[WINE_FLASK]));
message := [] ("look desk:",
"There is a Wine Flask on top.");
else
message := [] ("look desk:",
"It's made of Wood.");
end if;
elsif player.room = YELLOW_ROOM then
if item[GLASSES].room_num = NO_ROOM and not GLASSES in player.inventory then
put(curr_win, BORDER_DIST + item[GLASSES].xPos,
BORDER_DIST + item[GLASSES].yPos, getPixmap(item[GLASSES]));
message := [] ("look desk:",
"There is a Pair of Eye Glasses on Top.");
else
message := [] ("look desk:",
"It's made of Wood.");
end if;
elsif player.room = KINGS_STUDY then
if item[KEY].room_num = NO_ROOM and not KEY in player.inventory then
put(curr_win, BORDER_DIST + item[KEY].xPos,
BORDER_DIST + item[KEY].yPos, getPixmap(item[KEY]));
message := [] ("look desk:",
"There is a Key on top.");
else
message := [] ("look desk:",
"It's made of Wood.");
end if;
elsif player.room = LIBRARY_WEST_END then
if item[BOOK].room_num = NO_ROOM and not BOOK in player.inventory then
put(curr_win, BORDER_DIST + item[BOOK].xPos,
BORDER_DIST + item[BOOK].yPos, getPixmap(item[BOOK]));
message := [] ("look shelves:",
"There's a book on one.");
else
message := [] ("look shelves:",
"They're made of wood.");
end if;
elsif player.room = LIBRARY_EAST_END then
message := [] ("look shelves:",
"They're made of wood.");
elsif player.room = STORAGE_ROOM then
message := [] ("look shelves:",
"They're made of wood.");
elsif player.room = WINE_CELLAR then
message := [] ("look barrels:",
"They look Old!");
elsif player.room = TORTURE_ROOM then
message := [] ("look table:",
"It's covered with Blood!");
end if;
when {'|'}:
if player.room = SORCERERS_QUARTERS then
message := [] ("look mirror:",
"It looks Magical!");
elsif player.room = BALCONY then
message := [] ("look balcony:",
"The balcony is made of stone.");
end if;
when {'+'}:
message := [] ("look bush:",
"This is a small bush.");
when {'*'}:
message := [] ("look bush:",
"This is a big bush.");
when {'a' .. 'z'}:
item_ident := itemType conv (room[player.room].data[line][column]);
if item_ident <> NO_ITEM then
message := [] ("look " & item[item_ident].name & ":");
message &:= getItemMessage(item_ident);
end if;
when {' '}:
monster_ident := searchMonster(xPos, yPos);
if monster_ident <> NO_MONSTER then
message := getMonsterMessage(monster_ident);
elsif xPos >= player.xPos and
xPos < player.xPos + PIXMAP_SIZE and
yPos >= player.yPos and
yPos < player.yPos + PIXMAP_SIZE then
if player.room = SORCERERS_QUARTERS and
room[SORCERERS_QUARTERS].data[10][20] = '#' then
message := [] ("look player:",
"You see an ugly face in the mirror.");
else
message := [] ("look player:",
"This is only possible with a mirror.");
end if;
else
message := [] ("look floor:",
"The FLOORS are made of Gray Stone.");
end if;
end case;
end if;
end func;
const proc: lookItem is func
local
var itemType: item_ident is NO_ITEM;
begin
displayBox(light_red);
message := [] ("look");
displayMessage;
message := 0 times "";
item_ident := selectItem(eye_pixmap, "Look at", 0);
if item_ident <> NO_ITEM then
message := [] ("look " & item[item_ident].name & ":");
message &:= getItemMessage(item_ident);
else
lookItemInRoom;
end if;
displayMessage;
displayBox(white);
end func;
const proc: welcomeScreen is func
begin
clear(curr_win, black);
displayRoom(room[CASTLE]);
setPos(screen, 5, 63);
writeln(screen, "C A S T L E");
setPos(screen, 7, 49);
writeln(screen, "Copyright (C) 2004, 2005 Thomas Mertes");
setPos(screen, 9, 49);
writeln(screen, "This program is free software under the");
setPos(screen, 10, 49);
writeln(screen, "terms of the GNU General Public License");
setPos(screen, 12, 43);
writeln(screen, "Castle is written in the Seed7 programming language");
setPos(screen, 13, 48);
writeln(screen, "Homepage: http://seed7.sourceforge.net");
end func;
const proc: endOfGame is func
local
var char: command is ' ';
begin
showStatus;
setPos(screen, BUTTON_TEXT_LINE1 + 5, 104);
write(screen, "Play Again (Y/N)?");
setPos(screen, BUTTON_TEXT_LINE1 + 6, 105);
write(screen, " ");
repeat
command := upper(getc(KEYBOARD));
until command in {'Y', 'N'};
if command = 'Y' then
initGame;
displayAll;
end if;
end func;
const func char: getField (in integer: xPos, in integer: yPos) is func
result
var char: field is ' ';
local
var integer: line is 0;
var integer: column is 0;
begin
line := succ(yPos div PIXMAP_SIZE);
column := succ(xPos div PIXMAP_SIZE);
field := room[player.room].data[line][column];
if field = ' ' then
if xPos rem PIXMAP_SIZE <> 0 then
field := room[player.room].data[line][succ(column)];
if field = ' ' then
if yPos rem PIXMAP_SIZE <> 0 then
field := room[player.room].data[succ(line)][column];
if field = ' ' then
field := room[player.room].data[succ(line)][succ(column)];
end if;
end if;
end if;
else
if yPos rem PIXMAP_SIZE <> 0 then
field := room[player.room].data[succ(line)][column];
end if;
end if;
end if;
end func;
const proc: checkField (inout char: field) is func
local
var itemType: item_ident is NO_ITEM;
var integer: line is 0;
var integer: column is 0;
begin
if field <> ' ' then
if field = '=' then
if player.room = COURTYARD then
message := [] ("The Gate is locked.");
end if;
displayMessage;
elsif field in {'a' .. 'z'} then
item_ident := itemType conv field;
if item_ident <> NO_ITEM then
if card(player.inventory) < MAX_INVENTORY then
line := succ(item[item_ident].yPos div PIXMAP_SIZE);
column := succ(item[item_ident].xPos div PIXMAP_SIZE);
room[player.room].data[line] @:= [column] ' ';
field := ' ';
incl(player.inventory, item_ident);
put(curr_win, BORDER_DIST + pred(column) * PIXMAP_SIZE,
BORDER_DIST + pred(line) * PIXMAP_SIZE, floor_pixmap);
displayLegend;
displayInventory;
message := 0 times "";
else
message := [] ("take " & item[item_ident].name & ":",
"Can't carry any more!");
end if;
displayMessage;
end if;
end if;
end if
end func;
const func char: hitWall (in integer: xPos, in integer: yPos) is func
result
var char: field is ' ';
begin
field := getField(xPos, yPos);
checkField(field);
end func;
const func boolean: checkCollision (in integer: xPos, in integer: yPos) is func
result
var boolean: collision is FALSE;
local
var char: ch is ' ';
begin
ch := getField(xPos, yPos);
collision := ch <> ' ';
end func;
const func boolean: hitPlayer (in graphObj: obj1, in graphObj: obj2) is func
result
var boolean: hit is FALSE;
begin
if abs(obj1.xPos - obj2.xPos) < PIXMAP_SIZE and
abs(obj1.yPos - obj2.yPos) < PIXMAP_SIZE then
hit := TRUE;
end if;
end func;
const proc: moveMonsters is func
local
var integer: x_diff is 0;
var integer: y_diff is 0;
var monsterType: current_monster is NO_MONSTER;
var monsterType: monster_ident is NO_MONSTER;
begin
for monster_ident range MIN_MONSTER to MAX_MONSTER do
if monster[monster_ident].room_num = player.room and
monster[monster_ident].living then
x_diff := monster[monster_ident].xPos - player.xPos;
y_diff := monster[monster_ident].yPos - player.yPos;
if abs(x_diff) >= abs(y_diff) then
if x_diff >= 0 then
monster[monster_ident].direction := WEST;
else
monster[monster_ident].direction := EAST;
end if;
else
if y_diff >= 0 then
monster[monster_ident].direction := NORTH;
else
monster[monster_ident].direction := SOUTH;
end if;
end if;
if monster_ident <= BAT then
if monster[monster_ident].yPos > player.yPos then
monster[monster_ident].yPos -:= 8;
if hitPlayer(player, monster[monster_ident]) then
current_monster := monster_ident;
monster[monster_ident].yPos +:= 8;
elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then
monster[monster_ident].yPos +:= 8;
else
displayObj(monster[monster_ident]);
end if;
end if;
if monster[monster_ident].yPos < player.yPos then
monster[monster_ident].yPos +:= 8;
if hitPlayer(player, monster[monster_ident]) then
current_monster := monster_ident;
monster[monster_ident].yPos -:= 8;
elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then
monster[monster_ident].yPos -:= 8;
else
displayObj(monster[monster_ident]);
end if;
end if;
if monster[monster_ident].xPos > player.xPos then
monster[monster_ident].xPos -:= 8;
if hitPlayer(player, monster[monster_ident]) then
current_monster := monster_ident;
monster[monster_ident].xPos +:= 8;
elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then
monster[monster_ident].xPos +:= 8;
else
displayObj(monster[monster_ident]);
end if;
end if;
if monster[monster_ident].xPos < player.xPos then
monster[monster_ident].xPos +:= 8;
if hitPlayer(player, monster[monster_ident]) then
current_monster := monster_ident;
monster[monster_ident].xPos -:= 8;
elsif checkCollision(monster[monster_ident].xPos, monster[monster_ident].yPos) then
monster[monster_ident].xPos -:= 8;
else
displayObj(monster[monster_ident]);
end if;
end if;
end if;
end if;
end for;
if current_monster > NO_MONSTER then
if rand(1, 10) <= 4 then
player.strength -:= monster[current_monster].attack;
if player.strength < 1 then
message &:= [] ("The " & monster[current_monster].name & " has killed you!");
player.living := FALSE;
else
message &:= [] ("The " & monster[current_monster].name & " struck you!");
if rand(1, 2) = 1 and HELMET in player.inventory then
player.strength +:= monster[current_monster].attack;
message &:= [] ("The Helmet helped.");
end if;
end if;
else
message &:= [] ("The " & monster[current_monster].name & " missed you!");
end if;
displayMessage;
message := 0 times "";
end if;
end func;
const proc: enterRoom (in integer: room_number) is func
begin
message := 0 times "";
player.room := room_number;
end func;
const proc: moveDelta (in integer: delta_x, in integer: delta_y) is func
local
var char: field is ' ';
var directionType: stair is NORTH;
var monsterType: monster_ident is NO_MONSTER;
begin
field := hitWall(player.xPos + delta_x, player.yPos + delta_y);
if field <> ' ' then
if field = 'U' then
stair := UP;
elsif field = 'D' then
stair := DOWN;
end if;
if stair in {UP, DOWN} and room[player.room].exits[stair] <> 0 then
if room[player.room].exits[stair] in {WINE_CELLAR, DUNGEON_ENTRANCE} and
not LAMP in player.inventory then
message := [] ("It's too dark to go that way!");
displayMessage;
else
enterRoom(room[player.room].exits[stair]);
player.saved_pixmap := PRIMITIVE_WINDOW.value;
displayAll;
end if;
end if;
else
monster_ident := hitMonster(player.xPos + delta_x, player.yPos + delta_y);
if monster_ident <> NO_MONSTER then
if monster_ident <= BAT then
if SWORD in player.inventory then
if rand(1, 10) <= 4 then
monster[monster_ident].strength -:= rand(10, 19);
message := [] ("You struck the " & monster[monster_ident].name & "!");
if monster[monster_ident].strength < 1 then
message := [] ("You killed the " & monster[monster_ident].name & "!");
monster[monster_ident].living := FALSE;
monster[monster_ident].adjective := "Dead";
displayLegend;
displayInventory;
end if;
else
message := [] ("You missed the " & monster[monster_ident].name & "!");
end if;
else
message := [] ("You have no Weapon");
end if;
displayMessage;
elsif monster_ident = VAMPIRE then
message := [] ("The " & monster[monster_ident].name & " is blocking your way.",
"He can't be hurt!");
displayMessage;
elsif monster_ident = FAIRY1 or
monster_ident = FAIRY2 then
message := [] ("The " & monster[monster_ident].name & " is blocking your way.",
"She can't be hurt!");
displayMessage;
elsif monster_ident = DOOR1 or
monster_ident = DOOR2 then
if KEY in player.inventory then
monster[DOOR1].living := FALSE;
monster[DOOR2].living := FALSE;
monster[DOOR1].adjective := "Open";
message := [] ("You open the door with the key");
displayMessage;
else
message := [] ("The door is locked");
displayMessage;
end if;
elsif monster_ident = DOOR3 or
monster_ident = DOOR4 then
if KEY in player.inventory then
monster[DOOR3].living := FALSE;
monster[DOOR4].living := FALSE;
monster[DOOR3].adjective := "Open";
message := [] ("You open the door with the key");
displayMessage;
else
message := [] ("The door is locked");
displayMessage;
end if;
end if;
else
player.xPos +:= delta_x;
player.yPos +:= delta_y;
displayObj(player);
end if;
end if;
end func;
const proc: move (in directionType: direction) is func
begin
player.direction := direction;
if player.direction = WEST then
if player.xPos - STEP_SIZE < 0 then
if room[player.room].exits[WEST] <> 0 then
enterRoom(room[player.room].exits[WEST]);
player.saved_pixmap := PRIMITIVE_WINDOW.value;
player.xPos := 736;
displayAll;
end if;
else
moveDelta(-STEP_SIZE, 0);
end if;
elsif player.direction = EAST then
if player.xPos + STEP_SIZE > 736 then
if room[player.room].exits[EAST] <> 0 then
enterRoom(room[player.room].exits[EAST]);
player.saved_pixmap := PRIMITIVE_WINDOW.value;
player.xPos := 0;
displayAll;
end if;
else
moveDelta(STEP_SIZE, 0);
end if;
elsif player.direction = NORTH then
if player.yPos - STEP_SIZE < 0 then
if room[player.room].exits[NORTH] <> 0 then
enterRoom(room[player.room].exits[NORTH]);
player.saved_pixmap := PRIMITIVE_WINDOW.value;
player.yPos := 544;
displayAll;
end if;
else
moveDelta(0, -STEP_SIZE);
end if;
elsif player.direction = SOUTH then
if player.yPos + STEP_SIZE > 544 then
if room[player.room].exits[SOUTH] <> 0 then
enterRoom(room[player.room].exits[SOUTH]);
player.saved_pixmap := PRIMITIVE_WINDOW.value;
player.yPos := 0;
displayAll;
end if;
else
moveDelta(0, STEP_SIZE);
end if;
end if;
end func;
const proc: moveTo (in integer: xPos, in integer: yPos) is func
local
var integer: old_x is 0;
var integer: old_y is 0;
var integer: old_room is 0;
var time: curr_time is time.value;
begin
if abs(xPos - player.xPos) > STEP_SIZE div 2 or
abs(yPos - player.yPos) > STEP_SIZE div 2 then
old_room := player.room;
repeat
curr_time := time(NOW);
old_x := player.xPos;
old_y := player.yPos;
if abs(xPos - player.xPos) > abs(yPos - player.yPos) then
if xPos > player.xPos then
move(EAST);
else
move(WEST);
end if;
if abs(yPos - player.yPos) > STEP_SIZE div 2 and
old_x = player.xPos and old_y = player.yPos then
if yPos > player.yPos then
move(SOUTH);
else
move(NORTH);
end if;
end if;
else
if yPos > player.yPos then
move(SOUTH);
else
move(NORTH);
end if;
if abs(xPos - player.xPos) > STEP_SIZE div 2 and
old_x = player.xPos and old_y = player.yPos then
if xPos > player.xPos then
move(EAST);
else
move(WEST);
end if;
end if;
end if;
checkRoom;
moveMonsters;
flushGraphic;
await(curr_time + 30000 . MICRO_SECONDS);
until abs(xPos - player.xPos) <= STEP_SIZE div 2 and
abs(yPos - player.yPos) <= STEP_SIZE div 2 or
old_x = player.xPos and old_y = player.yPos or
old_room <> player.room or inputReady(KEYBOARD);
end if;
end func;
const proc: takeItem (in itemType: item_ident, in string: name,
in integer: line, in integer: column) is func
begin
if item[item_ident].xPos = pred(column) * PIXMAP_SIZE and
item[item_ident].yPos = pred(line) * PIXMAP_SIZE and
item[item_ident].room_num = NO_ROOM and
not item_ident in player.inventory then
message := [] ("take " & item[item_ident].name);
displayMessage;
message := 0 times "";
moveTo(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE);
if abs(succ(player.yPos div PIXMAP_SIZE) - line) <= 2 and
abs(succ(player.xPos div PIXMAP_SIZE) - column) <= 2 then
if card(player.inventory) < MAX_INVENTORY then
incl(player.inventory, item_ident);
displayAll;
else
message := [] ("take " & item[item_ident].name & ":",
"Can't carry any more!");
end if;
else
message := [] ("take " & item[item_ident].name & ":",
"I can't reach it!");
end if;
else
message := [] ("take " & name & ":",
upper(name) & "S are too heavy!");
end if;
end func;
const proc: takeItem is func
local
var char: command is ' ';
var integer: xPos is 0;
var integer: yPos is 0;
var integer: line is 0;
var integer: column is 0;
var itemType: item_ident is NO_ITEM;
var monsterType: monster_ident is NO_MONSTER;
begin
displayBox(light_red);
message := [] ("take");
displayMessage;
message := 0 times "";
command := getc(KEYBOARD);
xPos := clickedXPos(KEYBOARD);
yPos := clickedYPos(KEYBOARD);
xPos -:= BORDER_DIST;
yPos -:= BORDER_DIST;
line := succ(yPos div PIXMAP_SIZE);
column := succ(xPos div PIXMAP_SIZE);
if line >= 1 and line <= ROOM_LINES and
column >= 1 and column <= ROOM_COLUMNS then
case room[player.room].data[line][column] of
when {'#', '&', ':', ';'}:
message := [] ("take wall:",
"Impossible!!");
when {'W', 'R', 'N', 'P', 'Y'}:
message := [] ("take bed:",
"BEDS are too heavy!");
when {'U', 'D'}:
message := [] ("take staircase:",
"Impossible!!");
when {'='}:
message := [] ("take gate:",
"Impossible!!");
when {'>'}:
message := [] ("take balcony:",
"Impossible!!");
when {'?'}:
if player.room = GARDEN_SOUTH then
takeItem(LARGE_GEM, "fountain", line, column);
elsif player.room = BALCONY then
message := [] ("take fountain:",
"FOUNTAINS are too heavy!");
end if;
when {'{'}:
message := [] ("take chains:",
"They're Connected to the wall.");
when {'$'}:
takeItem(NECKLACE, "statue", line, column);
when {'%'}:
if player.room = KITCHEN then
message := [] ("take table:",
"TABLES are too heavy!");
elsif player.room = THRONE_ROOM then
message := [] ("take throne:",
"THRONES are too heavy!");
end if;
when {'@'}:
if player.room = CHEFS_QUARTERS then
takeItem(WINE_FLASK, "desk", line, column);
elsif player.room = YELLOW_ROOM then
takeItem(GLASSES, "desk", line, column);
elsif player.room = KINGS_STUDY then
takeItem(KEY, "desk", line, column);
elsif player.room = LIBRARY_WEST_END then
takeItem(BOOK, "shelve", line, column);
elsif player.room = LIBRARY_EAST_END then
message := [] ("take shelve:",
"SHELVES are too heavy!");
elsif player.room = STORAGE_ROOM then
message := [] ("take shelve:",
"SHELVES are too heavy!");
elsif player.room = WINE_CELLAR then
message := [] ("take barrel:",
"BARRELS are too heavy!");
elsif player.room = TORTURE_ROOM then
message := [] ("take table:",
"TABLES are too heavy!");
end if;
when {'|'}:
if player.room = SORCERERS_QUARTERS then
message := [] ("take mirror:",
"MIRRORS are too heavy!");
elsif player.room = BALCONY then
message := [] ("take balcony:",
"Impossible!!");
end if;
when {'+', '*'}:
message := [] ("take bush:",
"Impossible!!");
when {'a' .. 'z'}:
item_ident := itemType conv (room[player.room].data[line][column]);
if item_ident <> NO_ITEM then
message := [] ("take " & item[item_ident].name);
displayMessage;
message := 0 times "";
moveTo(pred(column) * PIXMAP_SIZE, pred(line) * PIXMAP_SIZE);
end if;
when {' '}:
monster_ident := searchMonster(xPos, yPos);
if monster_ident <> NO_MONSTER then
message := [] ("take " & monster[monster_ident].name & ":",
"I don't think that would be very safe!");
elsif xPos >= player.xPos and
xPos < player.xPos + PIXMAP_SIZE and
yPos >= player.yPos and
yPos < player.yPos + PIXMAP_SIZE then
message := [] ("take player:",
"Impossible!!");
else
message := [] ("take floor:",
"Impossible!!");
end if;
end case;
end if;
displayMessage;
displayBox(white);
end func;
const proc: quitGame is func
begin
if isOkay([]("Quit the castle game?")) then
exitGame := TRUE;
end if;
end func;
const proc: playGame is func
local
var char: command is ' ';
var integer: xPos is 0;
var integer: yPos is 0;
begin
displayAll;
while player.living and not exitGame do
command := getc(KEYBOARD);
case command of
when {KEY_LEFT}: move(WEST);
when {KEY_RIGHT}: move(EAST);
when {KEY_UP}: move(NORTH);
when {KEY_DOWN}: move(SOUTH);
when {KEY_ESC}: bossMode(exitGame);
when {'Q', 'q', KEY_CLOSE}: quitGame;
when {KEY_MOUSE1}:
xPos := clickedXPos(KEYBOARD);
yPos := clickedYPos(KEYBOARD);
if xPos >= BUTTONS_1_XPOS and xPos < BUTTONS_1_XPOS + 80 and
yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 3 * 32 then
case (yPos - BUTTON_YPOS_MIN) div 32 of
when {0}: loadGame;
when {1}: saveGame;
when {2}: quitGame;
end case;
end if;
if xPos >= BUTTONS_2_XPOS and xPos < BUTTONS_2_XPOS + 80 and
yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 2 * 32 then
case (yPos - BUTTON_YPOS_MIN) div 32 of
when {0}: takeItem;
when {1}: dropItem;
end case;
end if;
if xPos >= BUTTONS_3_XPOS and xPos < BUTTONS_3_XPOS + 80 and
yPos >= BUTTON_YPOS_MIN and yPos <= BUTTON_YPOS_MIN + 2 * 32 then
case (yPos - BUTTON_YPOS_MIN) div 32 of
when {0}: lookItem;
when {1}: useItem;
end case;
end if;
if xPos < 2 * BORDER_DIST + ROOM_COLUMNS * PIXMAP_SIZE and
yPos < 2 * BORDER_DIST + ROOM_LINES * PIXMAP_SIZE then
moveTo(xPos - BORDER_DIST - STEP_SIZE, yPos - BORDER_DIST - STEP_SIZE);
end if;
end case;
checkRoom;
moveMonsters;
if player.room = ESCAPED or not player.living then
exitGame := TRUE;
endOfGame;
end if;
end while;
end func;
const proc: main is func
local
var char: command is ' ';
begin
screen(1024, 768);
selectInput(curr_win, KEY_CLOSE, TRUE);
clear(curr_win, white);
screen := open(curr_win, 16);
KEYBOARD := GRAPH_KEYBOARD;
initGame;
welcomeScreen;
command := getc(KEYBOARD);
if upper(command) <> 'Q' and command <> KEY_CLOSE and command <> KEY_ESC then
playGame;
end if;
end func;