thorns.inf

Download
!% ++puny
!% $GRAMMAR_META_FLAG=1
!% $ZCODE_FILE_END_PADDING=0
!% $MAX_ABBREVS=95
!% -e
!% $MAX_DYNAMIC_STRINGS=1
!% $OMIT_UNUSED_ROUTINES=1
!% $ZCODE_LESS_DICT_DATA=1
!% $ZCODE_COMPACT_GLOBALS=1
!% $ZCODE_MAX_INLINE_STRING=9999

!===============================================================================
!=========================================================================== TOC
!
! - Constants
! - Include globals.h
! - New Attributes & Properties
! - Global variables
! - Library message replacements
! - Entry points
! - Include puny.h
! - Include extension libraries
! - Replacement entry points (need to be after puny.h)
! - Classes
! - Scenes & services
! - Locations & objects
! - General routines
! - Grammar: scope routines, meta, life, general grammar
! - Debugging grammar
! - Include hints & quotes

! I originally intended for this to be a retro-sized game, but as it grew, I had
! to include lots of conditionals to exclude less-critical things and still get
! it to fit in a .z3 game. That worked, and I optimized away some every-turn
! checks and such, so it performed decently on an Apple ][e. However, it got
! harder and harder to maintain the z3 version, so removed it. This now only
! compiles on z5.
!
! It runs decently on a very nice 8-bit computer with a z5 interpreter if
! USE_HINTS is not defined (I run it on a 10MHz CPM computer decently).
!
! However, some of the evidence of trying to optimize memory can definitely be
! felt in code; there's some needless optimization and such remaining. This
! doesn't hurt anything other than clarity for the reader.



Constant Story "Our Lady of Thorns";
Constant Headline
  "^A medieval monastic mystery/tragedy
  ^by Joel Burton <joel@@64joelburton.com>
  ^Site: https://lady-of-thorns.netlify.app^";
Release 2;
Array UUID_ARRAY string "UUID://2BB74FC0-C667-485D-9D4A-0DB142E4FF57//";
#IfDef UUID_ARRAY; #EndIf;

Constant CUSTOM_ABBREVIATIONS;
Include "thorns-abbrevs.inf";

Constant STATUSLINE_SCORE; Statusline score;

Constant CUSTOM_PLAYER_OBJECT = BrAldwin;
Constant DEATH_MENTION_UNDO;
Constant DEFAULT_CAPACITY = 5;
Constant HAS_HINTS;
Constant HAS_QUOTES;
Constant INITIAL_LOCATION_VALUE = BrAldwinCot;
Constant MAX_CARRIED = 3;
Constant MAX_INPUT_CHARS 200;
Constant MAX_FLOATING_OBJECTS 24;  ! number in source, saves a few bytes
Constant MAX_SCOPE 60;
Constant OPTIONAL_ALLOW_WRITTEN_NUMBERS;
Constant OPTIONAL_EXTENDED_METAVERBS;
Constant OPTIONAL_EXTENDED_VERBSET;
Constant OPTIONAL_LANGUAGE_NUMBER;
Constant OPTIONAL_LIST_TOGETHER;
Constant OPTIONAL_PROVIDE_UNDO;
Constant OPTIONAL_SIMPLE_DOORS;
Constant SACK_OBJECT = Basket;

! Dynamic strings
Constant DS_LIGHT 0;


! -------------------------------------- scoring

Constant OPTIONAL_FULL_SCORE;
Constant MAX_SCORE = 55;
Constant NUMBER_TASKS = 24;
Constant TASKS_PROVIDED;
Array task_scores -> 5 5 5 5   3 3 3 3 3   2 2 2 2 2   1 1 1 1 1 1 1 1 1 1;

! Evidence
Constant TASK_EVIDENCE_COINS = 0;           ! 5
Constant TASK_EVIDENCE_PSALTER = 1;         ! 5
Constant TASK_EVIDENCE_HENBANE_DECOCT = 2;  ! 5
Constant TASK_EVIDENCE_LETTER = 3;          ! 5

! Big puzzles
Constant TASK_SOLAR_DOOR = 4;               ! 3
Constant TASK_FA_CRYPT = 5;                 ! 3
Constant TASK_ESCAPE_CRYPT = 6;             ! 3
Constant TASK_LIBRARY = 7;                  ! 3
Constant TASK_OPENED_MEDICINE_CABINET = 8;  ! 3

! Small puzzles
Constant TASK_BRIBE_WITH_BASIL = 9;         ! 2
Constant TASK_READ_CHRONICLE = 10;          ! 2
Constant TASK_FA_PANEL = 11;                ! 2
Constant TASK_ROSE_LETTERS = 12;            ! 2
Constant TASK_GARDEN_KEY = 13;              ! 2

! Progress
Constant TASK_HID_CONTRABAND = 14;          ! 1
Constant TASK_LEARNED_FOUNDING_DATE = 15;   ! 1
Constant TASK_MATCH_SYMPTOMS = 16;          ! 1
Constant TASK_USED_REGISTRUM = 17;          ! 1
Constant TASK_USED_HERBAL = 18;             ! 1
Constant TASK_SOURCE_LIGHT = 19;            ! 1
Constant TASK_COMPLETED_OFFICE = 20;        ! 1
Constant TASK_BECAME_SUSPICIOUS = 21;       ! 1
Constant TASK_IDENTIFIED_ROSEHIPS = 22;     ! 1
Constant TASK_LISTED_OFFICES = 23;          ! 1

! =============================================================================

Property individual list_together;

Include "globals.h";

! ------------------------------------------------------ Attributes / Properties
!
! These are very limited in z3 games, so aliasing some where possible.

Attribute active alias general; ! for scenes, is it active (running at all)
Attribute awake alias on;       ! for people, are they awake? defaults on
Attribute convo;
Attribute evidence;             ! item is a piece of evidence
Attribute ok_carry;             ! item isn't contraband, can openly carry
Attribute toxic alias on;       ! for plants, are they toxic?


! Common properties
Property cheap_scenery;
Property simple_name;
Property time_start;
Property toward_slype;

! Don't need to declare these, but it's good documentation to do so
Property individual aldwin_joining;   ! is aldwin req'd for this service
Property individual attending;        ! is monk attending service t/f
Property individual check_combo;      ! check door combo for solar door
Property individual check;            ! check for failure in crypt scene
Property individual die;              ! routine of murder attempt by hugh
Property individual dont_need;        ! for candles, do they need to get one?
Property individual failed_office;    ! failed at performing in service
Property individual has_sung;         ! has sung in service
Property individual home;             ! home location for monk
Property individual job_title;        ! title for monk
Property individual learn_name;       ! routine to learn pax's name
Property individual move_to_service;  ! Routine to move monks 1 turn
Property individual noises;           ! noises heard in crypt
Property individual notice_fratrum;   ! routine to notice fratrum in lib
Property individual owning_monk;      ! owner of chest/cot
Property individual possess;          ! possessive names (eg 'hughs' 'hugh^s')
Property individual pressed_count;    ! count actually pressed now
Property individual pressed;          ! array of buttons pressed for Prior door
Property individual req_monks_actual; ! how many monks will be attending
Property individual req_monks;        ! num monks required for office to start
Property individual scene_start;      ! routine on scene start
Property individual scene_stop;       ! ... and stop
Property individual service_length;   ! how many rounds (mins) is a service?
Property individual set_me;           ! routine for infirmary cabinet
Property individual setting;          ! setting of infirmary cabinet
Property individual start_light;      ! turning candle on
Property individual stop_light;       ! ... and off
Property individual tired_count;      ! Wilfred: keep track of yawn messages
Property individual walk_home;        ! path monks walk to home
Property individual walk_index;       ! where is monk in moving path?
Property individual walk_matins;      ! Path for walking to first office
Property individual walk_office;      ! Path for walking to other offices
Property individual wont_talk;        ! routine to handle monk not talking
Property individual yawn;             ! Force Wilfred to yawn

! only rooms can get this, so save space by alias them to non-room props
Property cloister_detail alias grammar;
Property on_first_entry alias invent;

! Common religious terms, since it might be weird for the game to reply it
! hasn't heard of these terms (others are in Core cs_all cheap_scenery)
Dictionary 'abbot';
Dictionary 'angel';
Dictionary 'angels//p';
Dictionary 'bible';
Dictionary 'bibles//p';
Dictionary 'mass';
Dictionary 'sacred';
Dictionary 'scripture';
Dictionary 'sin';
Dictionary 'sins//p';
Dictionary 'soul';
Dictionary 'souls//p';


! ----------------------------------------------------- Global variables & flags

Global f_already_careless;
Global f_been_in_dark;
Global f_been_on_cloister;
Global f_can_complex_wait;
Global f_check_wait_during_service;
Global f_did_confess;
Global f_enough_evidence;
Global f_ever_offered_confession;
Global f_explained_look;
Global f_explained_follow;
Global f_forgive_contraband_one_turn;
Global f_found_darkness;
Global f_gave_hint_about_ask_re_brothers;
Global f_gave_hint_about_body_search;
Global f_gave_hint_about_key_search;
Global f_hid_contraband;
Global f_hugh_refuses_talk;
Global f_movement_here;
Global f_noted_having_contraband_first_time;
Global f_offer_confession;
Global f_offer_shout;
Global f_offered_shout;
Global f_printed_first_prompt;
Global f_seen_pax;
Global f_set_herobj;
Global f_set_himobj;
Global f_set_itobj;
Global f_set_themobj;
Global f_show_time_command;
Global f_silent_wait_ending;
Global f_singing_mentioned;
Global f_suggested_next_step;
Global f_told_can_take_plant_part;
Global f_warned_about_barrel_open_time;
Global f_warned_about_barrel_search_time;
Global f_warned_contraband;
Global f_wilfred_sees_aldwin_with_pax;

Global g_current_service = nothing;
Global g_evidence_count = 0;
Global g_last_accurate_time = -1000;
Global g_narc_loc;
Global g_narc;
Global g_next_service = nothing;
Global g_previous_location;
Global g_suspicion_level = 0;

Global ev_chronicle;           ! has read chronicle
Global ev_coins;               ! has examined coins
Global ev_hen_symptoms;        ! knows symptoms of henbane poisoning
Global ev_hugh_attempt;        ! hugh tried to kill you
Global ev_note;                ! has read note
Global ev_psalter;             ! has examined stolen psalter
Global ev_rose_letters;        ! has read rose letters
Global ev_rosehips;            ! has identified rosehips
Global ev_symptoms;            ! examined aelred's body
Global ev_took_poison;         ! knows symptoms & knows aelreds, has poison

Global waittime_waiting = false;


! ------------------------------------------------------------- default messages


Constant SKIP_MSG_GIVE_DEFAULT;

Constant MSG_ATTACK_DEFAULT
  "Peace, Brother. Violence isn't the answer.";
Constant MSG_BUY_DEFAULT
  "The sin of avarice takes many forms.";
Constant MSG_INVENTORY_EMPTY
  "You are without possessions.";
Constant MSG_JUMP
  "You do so, feeling self-conscious the entire time.";
Constant MSG_KISS_DEFAULT
  "Such displays of affection are... inappropriate. And forbidden. Very
  forbidden.";
Constant MSG_KISS_PLAYER
  "That would start to feel like a mortal sin.";
Constant MSG_LISTEN_DEFAULT
  "You listen carefully, but don't hear anything unexpected.";
Constant MSG_MILD_DEFAULT
  "Mind your tongue, Brother.";
Constant MSG_PARSER_NO_INPUT
  "Come again, Brother?";
Constant MSG_PARSER_ONLY_TO_ANIMATE
  "You can do that only to a living creature.";
Constant MSG_PARSER_UNKNOWN_VERB
  "That is not a verb I recognise.";
Constant MSG_PRAY_DEFAULT
  "You pray fervently, but nothing apparent happens.";
Constant MSG_SHOUT_DEFAULT
  "Novices do not shout.";
Constant MSG_SING_DEFAULT
  "You're a novice, not a cantor. Save your voice for the offices.";
Constant MSG_SLEEP_DEFAULT
  "Sloth is one of the seven deadly sins. Brother Oswald would find work for
  idle hands.";
Constant MSG_SMELL_DEFAULT
  "You sniff carefully, but don't smell anything unexpected.";
Constant MSG_SORRY_DEFAULT
  "This isn't confession.";
Constant MSG_STRONG_DEFAULT
  "Jesus wept.";
Constant MSG_TAKE_YOURSELF
  "You're far too modest for that.";
Constant MSG_THINK_DEFAULT
  "Silent reflection is always good.";
Constant MSG_WAIT_DEFAULT
  "You wait a minute.";
Constant MSG_WAKE_DEFAULT
  "You are already awake.";

! The actual numbers don't matter; just that they're unique and >1000, so
! Puny won't include the standard message.

Constant MSG_PROMPT = 1001;
Constant MSG_LOOK_BEFORE_ROOMNAME = 1002;
Constant MSG_NOW_DARK = 1003;
Constant MSG_CUT_NO_USE = 1004;
Constant MSG_CONSULT_NOTHING_INTERESTING = 1005;
Constant MSG_PARSER_NO_NEED_REFER_TO = 1006;
Constant MSG_PARSER_UNKNOWN_PERSON = 1007;
Constant MSG_ENTER_NOT_OPEN = 1008;
Constant MSG_EXIT_NOT_OPEN = 1009;
Constant MSG_INSERT_NOT_OPEN = 1010;
Constant MSG_GO_DOOR_CLOSED = 1011;
Constant MSG_EMPTY_IS_CLOSED = 1012;
Constant MSG_WAVE_DEFAULT = 1013;
Constant MSG_RESTART_RESTORE_OR_QUIT = 1014;

[ LibraryMessages p_msg p_arg_1 ; ! p_arg_2;
  switch(p_msg) {

    MSG_PROMPT:
      if (~~f_printed_first_prompt) {
        f_printed_first_prompt = true;
        ! For the very first turn, I have a custom listing of the monks in the
        ! room, so I don't want the lib to print its own listing. Therefore,
        ! after the first turn, un-conceal them so the lib will list them.
        give BrAelred ~concealed;
        give BrBenedict ~concealed;
        give BrHugh ~concealed;
        give BrAnselm ~concealed;
        print "What will you do, Brother?^";
      }
      #IfDef FULL_DEBUG; print (RealTime) the_time, " "; #EndIf;
      print "> ";

    MSG_LOOK_BEFORE_ROOMNAME:
      new_line;

    MSG_NOW_DARK:
      NowInDark();
       "^It is now pitch dark in here.";

    MSG_CUT_NO_USE:
      "You have nothing suitable for cutting.";

    MSG_CONSULT_NOTHING_INTERESTING:
      "I'm not sure what you're using to research.";

    MSG_PARSER_NO_NEED_REFER_TO:
      "You don't need to refer to ~", (_PrintUnknownWord) 0, "~ here.";

    MSG_PARSER_UNKNOWN_PERSON:
      if ((parse + 0)-->1 == 'aldwin') "You shouldn't talk to yourself.";
      "I can't see who you are referring to.";

    MSG_ENTER_NOT_OPEN, MSG_EXIT_NOT_OPEN, MSG_INSERT_NOT_OPEN,
    MSG_GO_DOOR_CLOSED, MSG_EMPTY_IS_CLOSED:
      ! p_arg_1 = the object which is closed, thus blocking the player's action.
      print "You can't, since ", (ObjIs) p_arg_1;
      if (p_arg_1 has locked) " locked."; " closed.";

    MSG_WAVE_DEFAULT:
      "You wave ", (the) noun, ", feeling self-conscious the entire time.";

    MSG_RESTART_RESTORE_OR_QUIT:
      print "^Would you like to RESTART, RESTORE";
        if(((HDR_GAMEFLAGS->1) & 16) ~= 0)
          print ", UNDO the last move";
      print ", give the FULL score for that game";
      if (f_enough_evidence)
        print ", read the full SOLUTION,";
      print " or QUIT? ";
      rtrue;
  }
];

! Custom common messages

Constant MSG_ABSOLUTE_SILENCE
  "He puts his finger to his lips to remind you to be silent while the service
  is underway.";
Constant MSG_ANOTHER_BROTHERS_PROPERTY_WRONG
  "another brother's property without reason just feels wrong.";
Constant MSG_CANT_LEAVE
  "As a novice, you're not to leave the priory grounds without permission.";
Constant MSG_DARE_NOT_ANOTHER_BROTHER
  "You dare not, especially with another brother in the area.";
Constant MSG_DARE_NOT_TOXIC
  "You dare not. It's toxic and irritating to the touch.";
Constant MSG_DISTURBING_DEAD
  "Disturbing the Christian dead is a mortal sin.";
Constant MSG_WONT_GO_DARK
  "You dare not head down to darkness without a light source.";


Array theft_messages static table
  "You take it, feeling the weight of this theft."
  "You take it, promising yourself you will return it."
  "You hesitate before proceeding to steal it. God sees, you think. God sees
    everything."
  "You know it is wrong to take things, but you somehow justify this."
  "You take it quickly, before your conscience can object.";


! ================================================================= Entry Points

Replace LockSub;
Replace UnlockSub;
Replace BurnSub;
Replace PraySub;
Replace ConsultSub;

Replace ImplicitGrabIfNotHeld OriginalImplicitGrab;
Replace _AskWhichNoun OriginalAskWhichNoun;


[ BeforeParsing _i _len;
  ! Allow "X ST. JUDE" to work --- this replaces the "." into "ST", which
  ! means it will think the user typed "X ST ST JUDE", which is strange, but
  ! works fine, and is easier than removing the period and re-parsing
  ! everything.
  if (deadflag && f_enough_evidence) {
    if ((parse-2)-->2 == 'solution') {
      print_ret "^",
        (string) Hint_Solution.&the_hints-->1,
        "^^---^^",
        (string) Hint_Solution.&the_hints-->2,
        "^";
    }
  }

  _len = NumberWords();
  for (_i = 2 : _i < NumberWords(): _i++) {
    if (WordValue(_i) == './/' && WordValue(_i-1) == 'st') {
      (parse-2)-->(_i*2) = 'st';
    }
  }
];


[ GamePostRoutine m ;
  objectloop(m ofclass Monk) {
    m.prev_loc = 0;
    m.prev_dir = 0;
  }
  rfalse;
];


[ PrintTaskName task_number;
  switch (task_number) {
    TASK_EVIDENCE_COINS: "found sack of coins";
    TASK_EVIDENCE_PSALTER: "found stolen psalter";
    TASK_EVIDENCE_HENBANE_DECOCT: "found henbane poison";
    TASK_EVIDENCE_LETTER: "read the offer note";

    TASK_SOLAR_DOOR: "unlocked door to Prior's Solar";
    TASK_FA_CRYPT: "discovered secret of the lion";
    TASK_ESCAPE_CRYPT: "escaped the Crypt";
    TASK_LIBRARY: "got into the Library";
    TASK_OPENED_MEDICINE_CABINET: "opened medicine cabinet";

    TASK_BRIBE_WITH_BASIL: "bribed Remigio";
    TASK_READ_CHRONICLE: "read the Chronicle";
    TASK_FA_PANEL: "escaped FitzAlan Crypt";
    TASK_ROSE_LETTERS: "found letters to Rose";
    TASK_GARDEN_KEY: "found key to Restricted Garden";

    TASK_LEARNED_FOUNDING_DATE: "learned about priory's history";
    TASK_HID_CONTRABAND: "found way to carry contraband";
    TASK_MATCH_SYMPTOMS: "matched symptoms of the poison";
    TASK_USED_REGISTRUM: "consulted Registrum Fratrum";
    TASK_USED_HERBAL: "consulted Aelred's Herbal";
    TASK_SOURCE_LIGHT: "discovered a source of light";
    TASK_COMPLETED_OFFICE: "participated in an office";
    TASK_BECAME_SUSPICIOUS:"noticed suspicious symptoms";
    TASK_IDENTIFIED_ROSEHIPS: "identified a plant";
    TASK_LISTED_OFFICES: "learned schedule of offices";
  }
];


! Help with chests & barrels, so this could work:
!
! OPEN HUGH'S CHEST. CLOSE CHEST.   : works!
!
! OPEN HUGH'S CHEST. OPEN WILFRED'S CHEST.
! CLOSE CHEST   : "Which do you mean, Hugh's chest or Wilfred's chest?"

[ ChooseObjectsFinal arr len _i _c _count;

  ! Seems to fix problem with "SET DIAL". XXX: this needs docs
  if (action == ##Turn or ##SetTo && location == Infirmary) {
    while (len > 0) {
      ChooseObjectsFinal_Pick(0);
      len--;
    }
  }

  ! Can close a single open chest with "CLOSE CHEST"
  if (action == ##Close or ##Insert && location == Dorter) {
    for (_i = len - 1 : _i >= 0 : _i--) {
      _c = arr-->_i;
      if ((_c ofclass Chest || _c == MyChest) && _c has open)
        _count++;
    }
    ! none are open, so all will be returned
    !   (else "You can't see any such thing")
    if (_count == 0) return;

    for (_i = len - 1 : _i >= 0 : _i--) {
      _c = arr-->_i;
      if ((_c ofclass Chest || _c == MyChest) && _c hasnt open)
        ChooseObjectsFinal_Discard(_i);
    }
  }

  ! Can close a single open barrel with "CLOSE BARREL"
  if (action == ##Close or ##Search && location == Undercroft) {
    for (_i = len - 1 : _i >= 0 : _i--) {
      _c = arr-->_i;
      if ((_c ofclass Barrel) && _c has open)
        _count++;
    }
    ! none are open, so all will be returned as suggestions
    !   (else "You can't see any such thing")
    if (_count == 0) return;

    for (_i = len - 1 : _i >= 0 : _i--) {
      _c = arr-->_i;
      if ((_c ofclass Barrel) && _c hasnt open)
        ChooseObjectsFinal_Discard(_i);
    }
  }
];


! [ DarkToDark ;
!   ! During the crypt escape, can move dark-to-dark
!   if (CryptBell has general) rfalse;
!   print
!     "You've heard dark tales of demons lurking in lightless places, and these
!     have haunted you since childhood.

!     ^^After several minutes fumbling and failing to get your bearings, terror
!     takes you and you begin screaming.

!     ^^Soon, Brother Cuthbert arrives bearing a candle. ~Brother Novice?~ he
!     demands, ~What on earth are you doing here?~";
!   KillOff(7);
! ];


Constant DEAD_DIED 1;
! Constant DEAD_WIN 2;     no "win" ending
Constant DEAD_FAILED 3;
Constant DEAD_ILL 4;
Constant DEAD_UNSOLVED 6;
Constant DEAD_JUSTICE 7;
Constant DEAD_MERCY 8;
Constant DEAD_INACTION 9;


[ DeathMessage;
  switch(deadflag) {
    ! "won" or "died" are already handled by library (but: game has no "win")
    DEAD_FAILED: print "You have failed";
    DEAD_ILL: print "You have fallen ill";
    DEAD_UNSOLVED: print "You ran out of time";
    DEAD_JUSTICE: print "You chose justice";
    DEAD_MERCY: print "You chose mercy";
    DEAD_INACTION: print "You chose inaction";
  }
];


[ NewRoom ;
  if (location provides on_first_entry && location hasnt visited) {
    location.on_first_entry();
  }

  ! Move Pax into cloister area:
  ! - not during important scenes; it's distracting
  ! - don't remove him from player
  ! - don't need to worry about removing from Wilfred, since Scriptorium
  !   isn't a cloister space
  ! Appears every 5 moves on Cloister, but not on the first 4 moves
    if (SceneFollowRemigio has general || SceneWandering has general) rfalse;
    if (location ofclass Cloister
        && parent(Pax) ~= player && ++Pax.appears_count % 5 == 0) {
      move Pax to location;
      give Pax moved;
      f_seen_pax = true;
    }
];


[ SceneryReply;
  switch (action) {
    ##Climb:
      if (CSHasNoun('stairs'))
        <<Go FAKE_U_OBJ>>;
    ##Exit:
      if (CSHasNoun('stairs'))
        <<Go FAKE_D_OBJ>>;
    ##Enter:
      if (CSHasNoun('stairs'))
        "[To ascend or descend stairs, just GO UP or GO DOWN.]";
    ##Smell:
      print_ret (string) MSG_SMELL_DEFAULT;
    ##LookUnder, ##Search:
      if (CSHasNoun('stairs')) "You cannot look under the stairs.";
      "You find nothing unexpected.";
    ##Taste:
      "This isn't something you'd taste.";
    ##Touch:
      print_ret (string) MSG_TOUCH_DEFAULT;
    ##Listen:
      print_ret (string) MSG_LISTEN_DEFAULT;
    ##Kneel:
      "This is not a place to kneel.";
    ##LieOn:
      "This is not a place to lie.";
  }
  rfalse;   ! <-- important!
];


[ TimePasses ;
  ! Called at end of turn when # moves goes up
  SetTime(the_time + 1);

  CheckPronouns();
  DescribeLight();

  ! If a service should be starting, start it
  if (g_next_service
        && g_next_service hasnt visited
        && g_next_service hasnt active
        && the_time >= g_next_service.time_start) {
    g_next_service.scene_start();
    if (waittime_waiting) {
      waittime_waiting = false;
      f_silent_wait_ending = true;
      print "^(waiting stopped because the bell rang)^";
    }
  }
  if (waittime_waiting && f_movement_here) {
    waittime_waiting = false;
    f_silent_wait_ending = true;
    print "^(waiting stopped because of movement here)^";
  }
  f_movement_here = false;

  if (f_offer_shout) {
    f_offer_shout = false;
    print_ret
      (bd) "^Accusation? ", "You know this may be your best chance to make the
      accusation and help catch the killer. If you'd like to do so, ",
      (mono) "SHOUT", " to interrupt the office.";
  }
  if (f_offer_confession) {
    f_offer_confession = false;

    "^Brother Wilfred looks up from his work and immediately sees the pain and
    confusion in your face, the weight of carrying around what you've
    discovered.

    ^^~My child~, he says, ~I can see that you carry much sorrow. Would you
    like to unburden yourself? Might I offer you confession?~^",
    (bd) "^Talk with Brother Wilfred about the murder? ",
    "You can do so with ", (mono) "CONFESS TO WILFRED", ".";
  }

  if (~~waittime_waiting) {
    g_previous_location = 0;

    CheckHidContraband();
    CheckEvidence();
    CheckForContraband();

    if (deadflag) rfalse;
    if (f_enough_evidence == 0) {
      g_evidence_count = CalculateEvidence();
      if (g_evidence_count >= 18) {
        f_enough_evidence = true;
        HintReady(Hint_Solution);
        print (bd) "^^Note: ";
        SolveSub();
      }
    }
  }

  if (the_time > (4 * 60 + 3) && ~~f_show_time_command) {
    f_show_time_command = true;
    "^[There is no clock here, but between bells ringing for offices and your
    own internal sense, you decide that it is very approximately ",
    (ReallyRoughTime) the_time,
    ". You can check this sense at any time with the command TIME.]";
  }
];


! Is this a room?
!
! In theory, this should be easy: a "room" is a subclass or Room or Cloister.
! However, Scenes would appear in the list of OBJECTS command, which is weird.

[ IsARoom p_obj ;
  if (action == ##Objects) {
    ! When using OBJECTS, lie and say a Scene is a room, so they won't appear
    if (p_obj ofclass Room or Cloister or Scene) return 1;
    return 2;
  }
  if (p_obj ofclass Room or Cloister) return 1;
  return 2;
];


! It's possible to take Pax (but she might disagree)
[ DisallowTakeAnimate p_object;
  if (p_object == Pax) rfalse;
];


#IfDef DEBUG;

  ! Allow "!foo" to be same thing as "! foo"
  [ UnknownVerb ;
    if (buffer->2 == '!') return '!//';
    rfalse;
  ];

#EndIf;



! =================================================================== Libraries

Include "ext_cheap_scenery.h";
Include "extlib/printtime.h";
Include "extlib/adjectives.h";
Include "extlib/monk_moves.h";
#IfDef HAS_QUOTES;
  Include "extlib/simple_quotes.h";
#EndIf;
#IfDef HAS_HINTS;
  include "extlib/hints.h";
#EndIf;



! Needs to be declared AFTER cheap_scenery loaded, since uses cs_match_id

[ ChooseObjects obj code ;
  ! print "*** CO ", (DebugAction) action, " ", (the) obj, " ", code, "^";

  if (code == 2) {
    ! This is for comparing which object is best-match; 0=bad-match,
    ! to 9=great-match

    ! X MONKS should always examine this object, not say something like
    ! "Which monk do you want to examine" or such
    if (obj == CheapScenery && cs_match_id == CSP_ALL_MONKS
        && action == ##Examine) return 9;

    ! Allows "BURN CANDLE [MyCandle] WITH CANDLE"
    if (obj == MyCandle && action == ##Burn
        && location == NightStairs && noun == nothing) return 9;
    if (obj == TimeCandle && action == ##Burn && noun) return 9;

    ! prefer aelred's habit to mine --- when his habit is in scope
    ! X HABIT should examine his, not yours
    if (obj == BrAelredHabit) return 9;

    ! QoL improvement: when in "right" location, automatically prefer the
    ! right key, so GET KEY, X KEY, etc, doesn't ask for disambiguation
    if (obj == LibraryKey) {
      if (location == Scriptorium) return 4; return 1;
    }
    if (obj == GardenGateKey) {
      if (location == Garden) return 4; return 1;
    }

    ! When doing X HENBANE, if in infirmary, you probably mean decoction.
    ! In garden, probably the sprig.
    if (location == Garden or RestrictedGarden && obj ofclass Herb)
      return 4;
    if (location == Infirmary && obj ofclass Decoction)
      return 4;

    ! Acting on book in Scriptorium is probably Breviary
    if (location == Scriptorium && obj == Breviary)
      return 4;

    ! Acting on book in a garden is probably Herbal
    if (location == Garden or RestrictedGarden && obj == Herbal) return 4;

    ! Since both Crypt Gate and Sacristy Door have 'door' as a name, prefer
    ! the actual door
    if (obj == SacristyDoor) return 3;

    ! Prefer beds over the plural plants for X PLANTS
    if (obj == Beds or RestBeds && action == ##Examine) return 3;

    ! Prefer the CS 'floor' over the Directions object
    if (obj == CheapScenery && cs_match_id == CSP_FLOOR) return 3;

    if (location == Dorter) {
      if (action == ##Open or ##Close && obj ofclass Chest) return 3;
      if (action == ##Enter && obj ofclass Cot) return 3;
      ! Prefer these for "shared actions" over just getting "which cot do..."
      if (obj == Cots or Chests) return 4;
    }

    ! In undercroft, Barrels object should mean "Which barrel..."
    if (location == Undercroft && obj == Barrels) return 4;

    if (location == BellTower) {
      if (obj == MyCandle) return 4;
      if (obj == CuthbertCandle) return 3;
    }

    if (obj == CheapScenery && cs_match_id == CSP_TOMBS
        && action == ##Examine or ##Search) return 3;

    ! Think we want this for a default
    ! TODO: should return 0, "can't offer any guidance"
    return 2;

  } else {
    ! This is for deciding whether to include something in ALL, eg
    ! TAKE ALL

    ! No choice made; 0 means "let default happen"
    rfalse;
  }
];


! ========================================================================= Puny

Include "puny.h";

! need to declare this library *after* puny, unlike others
Include "extlib/my_waittime.h";


!====================================================== Replacement Entry Points


! Prevent stuff like LOOK UP BROTHER IN FRATRUM returning all brothers
!  or ASK ANSELM ABOUT BROTHER

[ _AskWhichNoun p_num_matching_nouns ;
  if ( (action_to_be == ##Consult && ~~noun)
      || (action_to_be == ##Ask or ##Tell) ) {
    print "(Multiple topics matched. Be more specific.)";
    rtrue;
  }
  return OriginalAskWhichNoun(p_num_matching_nouns);
];


[ ImplicitGrabIfNotHeld arg1 arg2 sprig;
  if (arg1 == MyHood or MyRobe) rfalse;
  if (arg1 ofclass Plant) {
    ! Prevents "first taking the basil plant" with "> EAT BASIL"
    sprig = child(arg1);
    if (sprig == nothing)
      "You've already picked a sprig from ", (the) arg1,
      ". You should do this with that.";

    print "(first taking just a sprig from ", (the) arg1, ")^";
    move sprig to location;
    give sprig moved;
    noun = sprig;
    if (TryToTakeNoun(sprig) == 1) rtrue;
    rfalse;
  }
  return OriginalImplicitGrab(arg1, arg2);
];


! ====================================================================== CLASSES


Class Altar                                                             ! >Altar
  class AdjObject,
  with
    adj_name 'stone',
    noun_name 'altar',
    article "an",
    short_name "altar",
    description [;
      print "A simple stone altar, worn by generations of prayer";
      PrintContents(". On it ", self, ISARE_BIT);
      ".";
    ],
    react_before [;
      Go:
        if (player in self) {
          if (selected_direction == d_to) <<Exit self>>;
          ClimbDownFirst(self);
          rtrue;
        };
      Take, Search, Attack, Dig, Touch, JumpOver,
      Pull, Push, Rub, Smell, ThrowAt, Turn, Kiss:
        ! Prohibit these actions when on an altar
        if (noun == FitzAlanLion) rfalse;
        if (noun == CheapScenery && cs_match_id == CSP_CEILING)
          "Even from the altar top, you still cannot reach the ceiling above.";
        if (action == ##Smell && noun == nothing) rfalse;
        if (player in self && noun ~= self
            && noun notin self && ~~IndirectlyContains(player, noun)) {
              ClimbDownFirst(self);
              rtrue;
            }
    ],
    before [;
      Receive:
        if (self hasnt supporter)
          "You dare not place your worldly things on this sacred space.";
      Climb, Enter:
        if (self hasnt enterable)
          "Given how easily someone could see you, you dare not climb on this.";
        if (NarcInRoom()) print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
        if (action == ##Climb) <<Enter self>>;
      LookUnder: "You cannot lift the altar to look under it.";
    ],
    after [;
      Enter:
        "It feels deeply sacrilegious, but you climb onto the altar.";
      Exit:
        "You climb down from the altar.";
    ],
  has
    supporter enterable static;


Class Barrel                                                           ! >Barrel
  with
    parse_name [ w1 w2 ;
      w1 = NextWord();
      if (w1 == 'barrels//p') return 1;

      ! "X MUSTARD BARREL" or "X MUSTARD"
      if (w1 == self.simple_name) {
        w2 = NextWord();
        if (w2 == 'barrel') return 2;
        return 1;
      }

      ! "X BARREL MUSTARD" or "X BARREL OF MUSTARD"
      if (w1 == 'barrel') {
        w2 = NextWord();
        if (w2 == 'of') {
          w2 = NextWord();
          if (w2 == self.simple_name) return 3;
        }
        else if (w2 == self.simple_name) return 2;
        return 1;
      }

      return 0;
    ],
    simple_name,
    describe 0,
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~",
        (address) self.simple_name, "~";
      if (self has open)
        print ". It is currently open, revealing the expected contents";
      ".";
    ],
    before [;
      if (action == ##Search or ##Eat or ##Taste && self hasnt open)
        "You cannot, since the barrel is closed.";

      Receive:
        if (noun == Stick) <<Search self>>;
        "You shouldn't add anything to the barrels.";
      Dig:
        <<Search self second>>;
      Search:
        if (second && second ~= Stick)
          "Even with ", (the) second, ", you can't search the deep barrel
          completely.";
        if (second ~= Stick && Stick notin player)
          "The barrels are much too deep to search easily.";

        if (~~f_warned_about_barrel_search_time) {
          f_warned_about_barrel_search_time = true;
          print "^Searching a barrel will take several minutes. Continue? ";
          if (YesOrNo() == false) "You think better of it.";
          new_line;
        }
      LookUnder: "You cannot lift the barrel to look under it.";
      Take: "The barrels are too heavy, and you've no need of the contents.";
      Empty, Pull, Push, Turn:
        "The barrels are too heavy for you to move. Brother Hugh is much
        stronger than you.";
      Smell:
        if (self hasnt open) "With it closed, you can't detect any scent.";
      Eat:
        "You might taste it if you'd like, but not eat the whole thing.";
      Open:
        #IfDef HAS_HINTS;
          HintReady(Hint_Barrels);
          HintReady(Hint_WhichBarrel);
        #EndIf;

        if (~~f_warned_about_barrel_open_time) {
          f_warned_about_barrel_open_time = true;
          print
            "^Opening the sealed barrel will take several minutes. Are you
            sure? ";
          if (YesOrNo() == false) "You think better of it.";
          new_line;
        }
    ],
    after [;
      Open:
        the_time = the_time + 5;
        "With some time and effort, you succeed in opening it.";
      Close: "You pound on the lid to shut ", (the) self, ".";
      Search:
        the_time = the_time + 5;
        "Searching for a few minutes using the stick, you find nothing
        unexpected.";
    ]
  has static container openable ~open;



! It's not hard to find the candle, but you can't take it until you've
! proved you need it by opening the passage to the FitzAlan Chantry or
! by visiting the kitchen to see the stairs to the Undercroft.

Class Candle                                                           ! >Candle
  with
    ! name 'candle' 'light',
    dont_need [;
      if (~~f_found_darkness)
        "You've discovered no reason for this. The priory gets natural light,
        except on moonless nights, and carrying a candle would only raise
        questions.";
    ],
    start_light [;
      give self light;
      TaskDone(TASK_SOURCE_LIGHT);
      scope_modified = true;
    ],
    stop_light [;
      give self ~light;
      scope_modified = true;
    ],
    each_turn [ ;
      if (location == Porch or Passage or PassageSouth) {
        if (MyCandle in player && MyCandle has light) {
          MyCandle.stop_light();
          print "^Your candle blows out in the breeze.^";
        }
      }
    ],
    before [ helper ;
      SwitchOn: <<Burn self second>>;
      Burn:
        if (self has light) print_ret (The) self, " is already lit.";
        if (NarcInRoom())
          print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
        if (ImplicitGrabIfNotHeld(self)) rtrue;

        helper = -1;
        if (location == NightStairs) helper = TimeCandle;
        else if (location == Kitchen) helper = Hearth;
        else if (location == Scriptorium) helper = Fireplace;
        if ( (second == helper) || (second == nothing && helper ~= -1) ) {
          self.start_light();
          "You light ", (the) self, " using ", (the) helper, ".";
        }
      ! Take:
      !   return self.dont_need();
      Extinguish, SwitchOff:
        if (self hasnt light) print_ret (The) self, " isn't lit.";
        self.stop_light();
        "You extinguish ", (the) self, ".";
    ],
    after [;
      Drop:
        print "You drop the candle";
        if (self has light) {
          print " and, in doing so, extinguish it";
          self.stop_light();
        }
        ".";
    ],
  has
    ~light;


! Used for all benches & similar

Class Chair                                                             ! >Chair
  class AdjObject,
  with
    react_before [ ks ;
      Go:
        if (SceneMatins has active || SceneMeeting has active) rfalse;

        if (player in self) {
          if (selected_direction == u_to) <<Exit self>>;
          print "(first getting up from ", (the) self, ")^";
          ks = keep_silent;
          keep_silent = true;
          <Exit self>;
          keep_silent = ks;
          if (player in self) rtrue;
        };
      Take, Search, Attack, Dig, Touch, JumpOver, Enter, Climb,
      Pull, Push, Rub, Smell, ThrowAt, Turn, Kiss:
        if (noun == CheapScenery && cs_match_id == CSP_CEILING)
          "Even from here, you still cannot reach the ceiling above.";

        if (action == ##Smell && noun == nothing) rfalse;
        if (player in self && noun ~= self
            && noun notin self && ~~IndirectlyContains(player, noun))
          "First, you'd need to get up from ", (the) self, ".";
    ],
    before [;
      Sit: <<Enter self>>;
      Push, Pull, Turn:
        "You move ", (the) self, " and find nothing unexpected. You
        set ", (ItOrThem) self, " back in place.";
      Take:
        print_ret (CObjIs) self, " much too large to carry.";
      Receive:
        print_ret (CObjIs) self, " for sitting, not cluttering with stuff.";
    ],
    after [;
      Enter:
        "You sit on ", (the) self, ".";
      Exit:
        if (keep_silent) rtrue;
        "You stand up from ", (the) self, ".";
    ],
  has
    supporter enterable static;


! One for every monk; can only search them when suspicious.


Class Chest                                                             ! >Chest
  class AdjObject,
  with
    noun_name 'chest' 'box' 'chests//p' 'boxes//p',
    description [;
      print "It is a simple wooden box with a lid";
      if (self has open) print ". It is open";
      ".";
    ],
    before [;
      if (self ~= MyChest && action ~= ##Examine && NarcInRoom())
        print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
      Examine: ;
      Search:
        if (g_suspicion_level == 0) {
          #IfDef HAS_HINTS;
            HintReady(Hint_not_suspicious);
          #EndIf;
          "Searching ", (string) MSG_ANOTHER_BROTHERS_PROPERTY_WRONG;
        }
        if (self hasnt open) {
          print "(first opening ", (the) self, ")^";
          <<Open self>>;
        }
      Smell: "Just dusty.";
      Take:
        "You couldn't carry that easily---and besides, how would ",
        (The) self.owning_monk, " store anything?";
      Push, Turn, Pull:
        "There's nothing underneath it, and it will only frustrate the brothers
        to move their chests around.";
      Climb:
        "The chest is too small and fragile to stand on.";
      Enter, LieOn, Kneel:
        if (self hasnt open)
          "The chest is too small and fragile to get on.";

        "The chest is much too small to get into.";
      Open:
        if (g_suspicion_level == 0) {
          #IfDef HAS_HINTS;
            HintReady(Hint_not_suspicious);
          #EndIf;
          "Searching ", (string) MSG_ANOTHER_BROTHERS_PROPERTY_WRONG;
        }
      Lock, Unlock:
        "It has no locks.";
      default:
        if (g_suspicion_level == 0)
          "Doing anything with ", (string) MSG_ANOTHER_BROTHERS_PROPERTY_WRONG;
    ],
    after [;
      Open:
        if (child(self)) PronounNotice(child(self));
    ],
  has
    proper container ~open openable scenery;


Class Cloister                                                       ! >Cloister
  with
    name 'cloister' 'arcade',
    description [;
      if (~~f_been_on_cloister) {
        print
          "You emerge on the northern edge of the Cloister walk, the covered
          stone arcade at the centre of the priory. It's a continuous square
          path surrounding the Garth, a large open yard";
      } else {
        print "This is one of the eight sections of the Cloister";
      }
      print ". Arched openings admit ";
      switch (RoughTime()) {
        CLOCK_NIGHT: print "cold night air and pale moonlight";
        CLOCK_MORNING: print "fresh morning breeze";
        CLOCK_AFTERNOON: print "slanted autumn sun";
        default: print "dim evening light";
      }
      print ".^^";
      self.cloister_detail();
      if (~~f_been_on_cloister) {
        f_been_on_cloister = true;
        "^[Since the Cloister is so large, it is divided into eight parts:
        Cloister Northwest, Cloister North, and so on.]";
      }
    ],
    u_to "You dare not try to scale the Cloister walls.",
    cant_go "The walls of the Cloister block that direction.",
    d_to
      "The Garth is only one step down from the Cloister. To enter it, walk in
      that direction through an opening.",
    before [;
      Climb:
        "You eye the effort needed to scale the walls and think better of it.";
      Smell:
        if (noun == nothing)
          "You can faintly smell the gardens and the grass in the Garth.";
    ],
  has light;


Class Cot
  class AdjObject,
  with
    adj_name 'brother',
    noun_name 'cot' 'bed' 'mattress' 'cots//p' 'beds//p' 'mattresses//p',
    description [;
      print_ret
        (The) self, " is a simple straw mattress, lacking any
        ornamentation---but also lacking anything on or under it.";
    ],
    before [;
      Search, LookUnder:
        if (g_suspicion_level == 0)
          "Searching ", (string) MSG_ANOTHER_BROTHERS_PROPERTY_WRONG;
        "There is nothing on or below ", (the) self, ".";
      Smell:
        "It smells like a brother sleeps on it, as expected.";
      Push, Pull, Turn:
        "You shouldn't rearrange this. Leave it be.";
      PutOn:
        "Don't put things on the cot. Keep this room austere.";
      Enter, LieOn:
        "That's ", (the) self, ". You shouldn't lie there.";
    ],
  has
    scenery supporter enterable proper;


Class Decoction                                                     ! >Decoction
  with
    name 'decoction' 'decoctions//p',
    list_together [ _count _obj ;
      for(_obj = self: _obj ~= 0: _obj = NextEntry(_obj, pc_depth)) _count++;
      if (inventory_stage == 1)
        print (LanguageNumber) _count, " decoctions (";
      else if (inventory_stage == 2) print ")";
    ],
    invent [;
      if (listing_together) { print (address) self.&name-->0; rtrue; }
    ],
    before [;
      Eat, Drink: "You dare not.";
      Attack:
        "You shouldn't break this. Such bottles are valuable and communal
        property.";
      Empty:
        "These decoctions are used by Brother Benedict in healing. It would be
        wrong to waste them.";
    ],
  has
    convo ok_carry proper;


Constant MSG_NO_BUTTON_USE
  "You dare not, as any brother in the Cloister walk could see you.";

Class DoorButton                                                   ! >DoorButton
  with
    describe 0,
    name 'button' 'buttons//p',
    before [;
      Examine:
        print "A brass button engraved with ", (string) self.simple_name;
        if (self has on) print ". It is currently pressed in";
        ".";
      Push, SwitchOn:
        if (NarcInRoom() || SceneWandering has active
              || SceneFollowRemigio has active)
          print_ret (string) MSG_NO_BUTTON_USE;
        if (self has on) "That button is already pressed in.";
        give self on;
        PriorDoor.&pressed-->PriorDoor.pressed_count = self;
        PriorDoor.pressed_count++;
        print "You press the button and feel it click into place.^";
        PriorDoor.check_combo();
        rtrue;
      Pull, SwitchOff:
          if (NarcInRoom())
            print_ret (string) MSG_NO_BUTTON_USE;
        if (self hasnt on)
          "That button is not currently pressed.";
        "You cannot pull the button back out.";
      Take:
        "The button is part of the door.";
    ],
  has static ;


Class Fireplace                                                     ! >Fireplace
  with
    name 'fire' 'fireplace',
    capacity 100,
    react_before [;
      Burn:
        if (second == nothing or self && ~~noun ofclass Candle)
          <<Insert noun self>>;
    ],
    before [;
      ThrownAt:
        <<Insert noun self>>;
      Search: "Anything here would be burned to cinders.";
      Receive:
        if (noun == Pax) "You wouldn't dare.";
        if (noun ofclass Candle) <<Burn noun>>;
        remove noun;
        print "You put ", (the) noun, " into the fire and ";
        if (noun has pluralname) "they burn up.";
        "it burns up.";
      Extinguish: "You cannot put out the fire.";
      Touch: "Ow, ow, ow.";
      Smell: "Burning wood and smoke.";
      Taste: "But that would burn your tongue.";
      LookUnder: "You cannot look under the ", (the) self, ".";
      Enter:
        deadflag = DEAD_DIED;
        print "Visions of saints burning at the stake enter your head.";
        rtrue;
    ]
  has scenery container open;


Class Herb                                                               ! >Herb
  with
    name 'sprig' 'herb' 'herbs//p' 'sprigs//p',
    list_together [ _count _obj ;
      for (_obj = self: _obj ~= 0: _obj = NextEntry(_obj, pc_depth)) _count++;
      if (inventory_stage == 1) print (LanguageNumber) _count, " sprigs (";
      else if (inventory_stage == 2) print ")";
    ],
    invent [;
      if (listing_together) { print (address) self.&name-->0; rtrue; }
    ],
    before [;
      Eat:
        if (DieIfToxic(self)) rtrue;
        "You shouldn't eat the entire sprig. (If you want to merely see what it
        tastes like, say so.)";
      Touch, Take:
        if (self has toxic && Gloves hasnt worn)
          print_ret (string) MSG_DARE_NOT_TOXIC;
    ],
    after [;
      Drop: "You drop the delicate sprig.";
    ],
  has edible ok_carry ;


Array all_monks static -->
  BrAelred BrAnselm BrBenedict BrCuthbert BrHugh BrMartin BrOswald
  BrRemigio BrWilfred ;
Constant ALL_MONK_NUM 9;


Class Monk                                                               ! >Monk
  with
    name 'brother' 'monk' 'monks//p' 'brothers//p' 'brethren//p',
    describe [;
      ! we use the bulleted list in the quire to help w/sat-not-sat
      if (location == Quire || self in ChapterBenches) rtrue;
    ],
    list_together [ _count _obj ;
      for(_obj = self: _obj ~= 0: _obj = NextEntry(_obj, pc_depth)) _count++;
      if (inventory_stage == 1) print (LanguageNumber) _count, " Brothers (";
      else if (inventory_stage == 2) { print ")"; }
    ],
    invent [;
      if (listing_together) { print (string) self.simple_name; rtrue; }
    ],
    attending false,
    walk_index 0,
    went_home,
    left_home,
    prev_loc,
    prev_dir,
    wont_talk [;
      print_ret
        (The) self, " presses a finger to his lips, reminding you of the rule of
        silence preventing needless conversation.";
    ],
    life [;
      Answer, Ask, Tell: return self.wont_talk();
      Show:
        if (noun has ok_carry) {
          if (ImplicitGrabIfNotHeld(noun)) rtrue;
          print_ret (The) self, " does not remark on this presentation.";
        }
        f_forgive_contraband_one_turn = true;
        "You consider showing ", (the) self, " ", (the) noun,
        " but realizing carrying ", (ItOrThem) noun,
        " isn't something you're supposed to be doing, you decide not to.";
      Give:
        if (noun has ok_carry) {
          if (ImplicitGrabIfNotHeld(noun)) rtrue;
          print_ret
            (The) self, " refuses your gift with a gesture.";
        }
        f_forgive_contraband_one_turn = true;
        "You consider giving ", (the) self, " ", (the) noun, " but realizing
        you're not supposed to be carrying ", (ItOrThem) noun, ", you decide not
        to.";
      Attack, ThrowAt: "You have dedicated yourself to peace." ;
      WakeOther: print_ret (CObjIs) self, " already awake.";
      Order: "You're a novice, and in no position to order anyone.";
    ],
    before [;
      WaveTo:
        if (noun has awake)
          print_ret (The) self, " acknowledges your wave with a nod.";

        "There is no response to your wave.";
      ShoutAt: "You dare not raise your voice to a brother.";
      Search: "You dare not search ", (the) self, ".";
      LookUnder:
        "You awkwardly look below ", (the) self, " but find nothing
        unexpected.";
      Taste, Eat: "You won't.";
      Touch: "You decide not to---familiar touch is heavily discouraged.";
      Smell: "You awkwardly try to sniff him, but notice nothing.";
    ],
  has
    animate proper
    awake
    convo
    ! In real game, you can't carry these --- but for testing purposes,
    ! I often purloin a monk to move them where I want them --- and don't
    ! want that to trigger as contraband
    ok_carry
    light
  ;


! Base class for plants; player can't take these, but can get a sprig of
! each of these, which is an Herb (defined above)

Class Plant                                                             ! >Plant
  with
    name 'plant' 'plants//p',
    before [  p ;
      Examine:
        self.description();
        if (~~f_told_can_take_plant_part) {
          f_told_can_take_plant_part = true;
          print
            "^[If you want to take part of ", (the) self, ": PICK plant.]^";
        }
        rtrue;
      Eat:
        if (DieIfToxic(self)) rtrue;
      Touch:
        if (self has toxic && Gloves hasnt worn)
          print_ret (string) MSG_DARE_NOT_TOXIC;
      LookUnder: "You cannot see anything in the dirt below ", (the) self, ".";
      Take, Cut:
        if (self has toxic && Gloves hasnt worn)
          print_ret (string) MSG_DARE_NOT_TOXIC;
        p = child(self);
        if (p == nothing)
          "You've already taken a sprig from ", (the) self, ".";
        move p to location;
        noun = p;
        if (TryToTakeNoun(p) ~= 1) {
          PronounNotice(p);
          if (action == ##Cut)
            "You break a sprig off of it.";
          else
            "Rather than taking the entire ", (address) self.&name-->0,
            " plant, you take a sprig of it.";
        } else {
          move p to self;
        }
        rtrue;
    ],
  has
    ! not scenery because i want it to be preferred equally with decoctions of
    ! same name
    ~edible static ;


! Very light, just here so it's easy to distinguish room vs object
! with a ofclass check.

Class Room                                                               ! >Room
  with
    cant_go [;
      if (location == thedark)
        "You bump around in the dark. You can't go that way.";

      "You can only go ", (PrintExits) "or", ".";
    ],
  has light;  ! turn off in individual underground rooms



! Statues found in altars and in chapel house: Mary, St Jude, Gordian

Class Statue                                                           ! >Statue
  with
    name 'statue',
    before [;
      Take:
        "The statue has stood here for many years---and you dare not change
        that, even if you could carry it.";
      Confess:
        "Only a priest can hear your confession---certainly not a statue.";
      Heal:
        if (self has female) print "She"; else print "He";
          " is beyond your help---and, one suspects, beyond any need of it.";
      Push, Pull, Turn:
        print "With some effort, you ";
        switch (action) {
          ##Push: print "push";
          ##Pull: print "pull";
          ##Turn: print "rotate";
        }
        " the statue a bit, revealing nothing. Feeling shame about the potential
        sacrilege of this action, you reset it as it was.";
      LookUnder:
        "You can't lift the statue to search under it.";
    ],
    life [;
      Attack: "Perish the very idea!";
      Give:
        "You cannot offer ", (ItOrThem) self, " anything but your reverence.";
      Ask, Tell, Answer, Show: "The statue remains ever-silent.";
      WakeOther: "Save the miracles for others.";
      Kiss:
        "You reverently kiss the hem of ", (HisHerTheir) self, " robe.";
      Order:
        "If anything, a statue of a saint would order you around.";
    ],
  has
    scenery animate ;


Class Tomb                                                               ! >Tomb
  class AdjObject,
  with
    adj_name 'brother' 'prior',
    noun_name 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    description [;
      print_ret
        (CObjIs) self, " a stone block with a lid on which his name is carved.
        It is otherwise like the others in the room.";
    ],
    react_before [;
      Take, Search, Attack, Dig, Touch, JumpOver,
      Pull, Push, Rub, Smell, ThrowAt, Turn, Kiss:
        if (noun == CheapScenery && cs_match_id == CSP_CEILING)
          "Even from the top, you still cannot reach the ceiling above.";
        if (noun == Ladder) rfalse;
        if (action == ##Smell && noun == nothing) rfalse;
        if (player in self && noun ~= self
            && noun notin self && ~~IndirectlyContains(player, noun)) {
          ClimbDownFirst(self);
          rtrue;
        }
      Jump:
        if (player in FitzAlanSmallTomb or FitzAlanLargeTomb)
          "You jump, hoping to reach the ladder, but it's too high up.";
      Go:
        if (player in self && selected_direction == d_to) <<Exit self>>;
    ],
    before [;
      Attack:
        print_ret (string) MSG_DISTURBING_DEAD;
      Climb: <<Enter noun>>;
      Enter:
        if (self hasnt enterable) print_ret (string) MSG_DISTURBING_DEAD;
      Push, Turn, Pull, LookUnder:
        "You push, pull, twist and try to raise it, without any result. The tomb
        and the lid must weigh several hundredweight. It would take multiple men
        with levers to shift one.";
      Open: "The tomb is sealed solidly with mortar.";
    ],
    after [;
      Enter:
        "While it feels deeply sacrilegious, you climb on ", (the) self, ".";
      Exit: "You climb down from ", (the) self, ".";
    ],
  has supporter enterable scenery proper;


Class Wheel                                                             ! >Wheel
  class AdjObject,
  with
    adj_name 'brass',
    setting 0,  ! starts at I
    describe 0,
    set_me [;
      print "You turn ", (the) self, " to ", self.setting, ".^";
      InfirmaryCabinet.check_combo();
    ],
    before [;
      if (BrBenedict in Infirmary && action ~= ##Examine or ##Search or ##Smell)
        print_ret (string) MSG_DARE_NOT_WHEELS;

      SetTo:
        if (InfirmaryCabinet has open)
          print_ret (string) MSG_WHEELS_CANT_BE_TURNED;
        self.setting = second;
        self.set_me();
        rtrue;
      Turn:
        if (InfirmaryCabinet has open)
          print_ret (string) MSG_WHEELS_CANT_BE_TURNED;
        self.setting++;
        if (self.setting > 9) self.setting = 0;
        self.set_me();
        rtrue;
      Examine:
        print_ret (The) self, " is currently set to ", self.setting, ".";
    ],
  has
    static concealed;



! =================================================================== MONKS
! NAME       ROLE         AGE  GOES_TO              SERVICE
! Aelred     herbalist    63   slype                1
! Anselm     cantor       30   locutory             all
! Benedict   infirmarer   48   infirmary            all
! Cuthbert   sacrist      46   bell tower           all
! Hugh       cellarer     32   undercroft           all
! Martin     kitchener    42   kitchen              all
! Oswald     prior        52   solar                all
! Remigio    servant/lay  38   kitchen              1
! Wilfred    librarian    73   scriptorium          all
! Aldwin     novice       20                        1
!
! the PC, Aldwin, is not an instance of monk class.


Monk BrAelred "Brother Aelred"                                       ! >BrAelred
  with
    name 'aelred' 'herbalist' 'mentor',
    simple_name "Aelred",
    job_title "herbalist",
    description
      "Your beloved mentor. Brother Aelred is in his sixties, tall and
      broad-shouldered, with gentle eyes that often crinkle with quiet
      amusement. In the five months you've studied under him, his kindness has
      been matched only by his knowledge of healing herbs.",
    possess 'aelred^s' 'aelreds',
    home nothing,
    wont_talk [;
      "~Hush now, child. This is no time for talking. I'll see you
      after office in the gardens.~";
    ],
    walk_matins 0 0 (d_to) (d_to) (Stalls),
    before [;
      Smell: print_ret (The) self, " always smells a bit like herbs and dirt.";
      WaveTo:
        "Brother Aelred acknowledges your wave with a smile. ~Good morning.~";
      Confess:
        "~Now, there's no need for that right now, my friend.~";
    ],
    life [ ;
      Ask:
        switch (second) {
          BrHugh, BrRemigio, BrWilfred:
            print "His eyes show brotherly concern. ";
            rfalse;
          BrAldwin:
            "~Son, you must learn to know yourself.~ He smiles.";
          BrAelred:
            "He chuckles gently. ~An old herbalist who talks to plants.~";
          'himself': <<Ask self self>>;
          'garden', 'gardens':
            "~Yes, son. Meet me there later this morning.~";
        }
    ],
  history_text
      "Aelred (1284-). Entered the priory 1295 as a youth. Serves as herbalist.
      Fluent in several languages beyond English and Latin.

      ^^Written below this, in fresh ink in Wilfred's scratchy hand, it reads:
      ~Requiescat in pace, care frater~.",
  has animate;


Object BrAelredDying "Brother Aelred"                           ! >BrAelredDying
  with
    name 'brother' 'monk' 'aelred' 'mentor' 'herbalist' 'body',
    describe "^Brother Aelred lies on the stone floor.",
    description [;
      if (self hasnt general)
        "Your beloved mentor. In normal moments, Brother Aelred's eyes twinkled
        with kindness. Right now, though, he looks desperately ill. Sweat beads
        on his flushed face, and his pupils look strange. His limbs grab wildly
        at his habit, making it seem as though he is trying to remove something
        that isn't there.";
      "Brother Aelred lies dead on the stone floor. You pray he is at peace.";
    ],
    before [;
      WaveTo:
        "There is no reply to your wave.";
      Search:
        if (self has general) <<Search BrAelredBody>>;
      Smell:
        ev_symptoms = true;
        "There's something oddly distinctive about his breath:
        acrid and stale, reminding you of old chamber pots.";
      Eat, Taste:
        "You dare not even contemplate such an act.";
      Confess:
        "He cannot help you now.";
      Heal:
        if (self hasnt general)
          "You have neither the experience nor medicines to treat him---but you
          hold his hand for a moment, hoping this provides some comfort.";
        "He is now in God's hands.";
      Touch:
        if (self hasnt general)
          "You touch his arm and feel nothing but the convulsions his body
          makes.";
        "His body is lifeless to your touch.";
      Take:
        "You consider trying to carry him to the Infirmary---but, clearly, he is
        beyond cure. Instead, you stroke his head.";
    ],
    life [ ;
      Kiss:
        "You kiss his forehead and hope that this kind gesture might reassure
        him.";
      Ask:
        if (self has general) "It is too late for such things.";

        if (MurderWord(second))
          "He points to his throat, sputtering.";
        if (second ofclass Monk)
          "He shakes his head, perhaps indicating ~No~. His eyes are even more
          wild.";

        switch (second) {
          'gathering':
            "~He wanted, he needed---~. Brother Aelred trails off in pain. You
            think he added ~Saint Jude~, though he is hard to hear.";
          'brother', 'appointment', 'meet', 'meeting':
            "He shakes violently. ~Meet---I wanted to help---~. He trails off in
            pain.";
          JudeStatue:
            "Even through the jerking of his hand, he tries to make the sign of
            the cross.";
          Letters:
            "Perhaps in response, he points north. ~They're not alive.~";
          Scriptorium:
            "He nods his head wildly. ~Lost.~";
          RoseOrHips, 'bushes':
            "He coughs violently, and can only get out a word: ~gathering~.";
          default:
            "He mumbles something incoherent in response.";
        }


      default:
        if (self hasnt general)
          "In response, he looks at you with those strange eyes.";
        "He lies dead, and cannot respond.";
    ],
  has animate proper transparent ;


Object -> BrAelredMouth "Brother Aelred's face and mouth"
  class AdjObject
  with
    adj_name  'aelred' 'aelred^s' 'aelreds' 'brother' 'his',
    noun_name 'mouth' 'face' 'teeth' 'throat' 'odor' 'odour',
    description [;
      "You detect nothing unusual about ", (the) self, ", except for his eyes
      and the odour coming from his mouth.";
    ],
    before [;
      Smell: <<Smell BrAelredBody>>;
      Touch, Examine: ;
      Open:
        "You find nothing in his mouth and close it.";
      default: "Leave his body be.";
    ],
  has proper static ;


Object -> BrAelredOtherParts
  class AdjObject
  with
    adj_name  'aelred' 'aelred^s' 'aelreds' 'brother' 'his',
    noun_name
      'arms' 'legs' 'chest' 'torso' 'ears'
      'hair' 'feet' 'fingers',
    description
      "Your examination here finds nothing useful.",
    before [;
      Smell: <<Smell BrAelredBody>>;
      Touch, Search, Examine: ;
      default: "Leave his body be.";
    ],
  has proper concealed static ;


Object -> BrAelredHand "Brother Aelred's hands"
  class AdjObject
  with
    adj_name  'aelred' 'aelred^s' 'aelreds' 'brother' 'his',
    noun_name 'hand' 'hands',
    description
      "You notice nothing unusual about his hands.",
    before [;
      Smell: <<Smell BrAelredBody>>;
      Touch, Search, Examine: ;
      Take:
        if (BrAelredDying hasnt general)
          "You hold one of his hands for a moment, hoping he is comforted by
          this.";
        "You hold one of his hands for a moment. You hope his soul is at
        peace.";
      default: "Leave his hands be.";
    ],
  has proper concealed static ;


Object -> BrAelredEyes "Brother Aelred's eyes"                   ! >BrAelredEyes
  class AdjObject
  with
    article "his",
    adj_name 'aelred' 'aelred^s' 'brother' 'his',
    noun_name 'eyes' 'face' 'head' 'pupils',
    description [;
      ev_symptoms = true;
      "His pupils are unnaturally dilated and black, like you have never seen in
      a person living or dead.";
    ],
    before [;
      Examine, Search, Touch: ;
      Open: "His eyes are already open.";
      Close: "Leave such matters to Brother Benedict.";
      default: "Leave his body be.";
    ],
  has proper pluralname convo concealed static ;


Object -> BrAelredHabit "Brother Aelred's habit"                ! >BrAelredHabit
  class AdjObject
  with
    adj_name 'aelred' 'aelred^s' 'aelreds' 'brother' 'his',
    noun_name 'habit' 'robe',
    description
      "You see nothing unusual about his habit, and don't see the things he was
      picking at.",
    before [;
      Search:
        if (BrAelredDying has general) <<Search BrAelredBody>>;
    ],
    has proper concealed clothing ;


Constant MSG_ANSELM_MORE_INTERESTED
  "Brother Anselm is more interested in questions about other brothers.";
Constant MSG_JUST_HOPE_NOT_MURDER
  "~I hope this wasn't really murder.~";
Constant MSG_DOES_SEEM_LIKE_EVIDENCE
  "~That does seem like evidence of something.~";

Monk BrAnselm "Brother Anselm"                                       ! >BrAnselm
  with
    name 'anselm' 'cantor',
    describe [;
      if (location == Locutory)
        "^Brother Anselm is standing here, smiling at you.";
    ],
    description
      "Brother Anselm, the cantor, is barely thirty, young for his office. He
      joined the priory at a young age and was put under the tutelage of Brother
      Wilfred for many years. He has a clear, strong voice and an easy smile.
      You've learned that unlike many of the other brothers, he seems to enjoy
      conversation where the Rule permits it.",
    simple_name "Anselm",
    job_title "cantor",
    possess 'anselm^s' 'anselms',
    home Locutory,
    walk_home 0 Quire (s_to) (w_to) (s_to) (w_to),
    walk_office (e_to) (n_to) (e_to) (n_to) Stalls,
    walk_matins 0 0 (d_to) (d_to) Stalls,
    before [;
      Confess:
        "Brother Anselm looks surprised. ~I'm not a priest yet, Aldwin. I can't
        hear your confession. If you've something on your mind, perhaps you
        should talk with Brother Wilfred? He's always been very helpful when I
        needed it.~";
    ],
    life [ ;
      Tell:
        if (f_enough_evidence) {
          if (MurderWord(second) || (second == BrHugh or StolenPsalter or
              Chronicle or Coins or ScribbledNote or HenbaneDecoction or
              Henbane))
            "~This sounds very serious, Aldwin. I'm not the right person to talk
            about this with, though. I wish you peace.~";
        }

        if (second == Letters && Letters has moved)
          "~I wonder where Hugh got the silver.~";

        if (metaclass(second) == Object
              && second has evidence && second has moved)
          print_ret (string) MSG_DOES_SEEM_LIKE_EVIDENCE;

        if (MurderWord(second))
           print_ret (string) MSG_JUST_HOPE_NOT_MURDER;

        print_ret (string) MSG_ANSELM_MORE_INTERESTED;
      Ask:
        if (MurderWord(second)) print_ret (string) MSG_JUST_HOPE_NOT_MURDER;

        switch(second) {
          BrAelred:
            "~He was so kind.~ Anselm's voice catches. ~We're all going to miss
            him terribly.~";
          BrAldwin:
            "He laughs happily. ~You? You're, well, you. I think you're doing
            very well here.~";
          BrAnselm, 'himself':
            "He looks puzzled. ~We've talked many times, Aldwin.~";
          BrBenedict:
            "~When I had quinsy last year, he took excellent care of me. We were
            meeting earlier this morning in the Garth.~";
          BrCuthbert:
            "~He's so serious about the rule of silence that I've never really
            talked to him.~";
          BrHugh:
            "~Brother Hugh used to be so joyful when I arrived. I fear something
            has been on his mind for months.~";
          BrMartin:
            "~He's so busy in the Kitchen that I almost never get to talk with
            him.~";
          BrOswald:
            "~He's extremely capable---but I never get a chance to talk with
            him.~";
          BrRemigio:
            "~Oh, our poor foreign lay brother. He seems a bit like a lost soul.
            It must be very lonely for him here, especially given how little
            English he has.~";
          BrWilfred:
            "~He is such an excellent illuminator and has such a sharp mind.~";
          TombGordian:
            "~He founded the priory, you know? I've only seen a few of his brass
            devices, but they were all very clever.~";
          Pax:
            if (Pax hasnt proper) {
              print "~Oh, her? Her name is Pax.";
              Pax.learn_name();
            }
            else {
              print "~Oh, Pax?";
            }
            " She's very friendly. I've often caught Brother Wilfred napping in
            the Scriptorium with her on his lap.~";
          Library, LibraryKey:
            "~I've never been in the Library. We're not to enter---that's why
            only Wilfred has a key.~";
          HenbaneDecoction, FoxgloveDecoction, FeverfewDecoction:
            "~Brother Benedict stores the medicines, that's all I know.~";
          StolenPsalter:
            "~I heard it disappeared, that's all.~";
          'locutory':
              "~This is where I often work, planning out our choral pieces.~";
          'sing', 'song', 'singing':
            "He makes a kind comment about how your voice is improving.";
          default:
            print (string) MSG_ANSELM_MORE_INTERESTED;
            new_line;
            return AskFail();
        }
    ],
    history_text
      "Anselm (1316-). Entered 1332. Studied under Brother Wilfred as a youth.
      Appointed cantor 1344 despite his youth, owing to the exceptional clarity
      of his voice. Leads the brothers in the Divine Office."
  has ;


! general = already responded about aelred

Constant BENEDICT_ON_MURDER
  "~I examined Brother Aelred carefully before preparing his body. His heart
  stopped---he was an old man, and such is God's will. We will lay him to rest
  tomorrow with proper honour.~";

Monk BrBenedict "Brother Benedict"                                 ! >BrBenedict
  with
    name 'benedict' 'infirmarer',
    describe [;
      if (location == Infirmary)
        "^Brother Benedict is here, tidying the workbench and looking
        reflective.";
    ],
    description
      "Brother Benedict, the infirmarer, is a heavyset man in his forties with
      gentle hands and a warmer smile than his bulk might suggest. He moves with
      the careful efficiency of one who tends the suffering daily.",
    simple_name "Benedict",
    possess 'benedict^s' 'benedicts',
    job_title "infirmarer",
    home Infirmary,
    walk_home Quire (s_to) (e_to) (s_to) (s_to) (e_to) (e_to),
    walk_office (w_to) (w_to) (n_to) (n_to) (w_to) (n_to) Stalls,
    walk_matins 0 (d_to) (d_to) Stalls,
    went_home [;
      if (InfirmaryCabinet has open) {
        give InfirmaryCabinet ~open;
        print (bd) "^^Oh no! ";
        print "Brother Benedict found the infirmary cabinet open";
        return WasCareless();
      }
    ],
    wont_talk [;
      if (location == Infirmary) {
        print
          "Brother Benedict nods kindly but gestures toward his work. ~Forgive
          me, Brother Novice, but I have much to attend to.~^";
          return AskFail();
      }
      "Brother Benedict looks at you kindly, but raises his finger to his lips,
      to remind you of the rule against unnecessary speech.";
    ],
    life [ ;
      Ask:
        if (location ~= Infirmary or Slype or CloisterSE
            or CloisterE or CloisterNE or CloisterN) rfalse;

        if (MurderWord(second)) print_ret (string) BENEDICT_ON_MURDER;

        switch(second) {
          Pax:
            "~Dear brother, I have no time for such stray animals.~";
          BrHugh:
            "~Brother Hugh is very helpful. I understand he's been assisting
            Wilfred in the Library.~";
          BrWilfred:
            "~His hands may tremble and he can drift off, but his mind is as
            sharp as ever.~";
          BrRemigio:
            "~How horrible it must have been for him to find Brother Aelred
            like that.~";
          BrAnselm:
            "~I was talking to him after Matins this morning, and then he was
            very helpful earlier today with Brother Aelred's body.~";
          BrAelred:
            if (self hasnt general) {
              give self general;
              "~Our dear brother is in the Infirmary Chapel and you may seek him
              there.~";
            }
            "He only gestures toward the Infirmary Chapel.";
          BrAelredEyes:
            "~They were very dilated. Perhaps he was in pain?~";
          BrBenedict, 'himself':
            "~You know me, Brother. I care for the unwell.~";
          InfirmaryCabinet:
            "~The medicines are kept secure here.~";
          FeverFewDecoction, FoxgloveDecoction, HenbaneDecoction:
            print "~I keep that here for medicine.~";
            if (second == HenbaneDecoction && HenbaneDecoction has moved)
              print
                " He pauses. ~I thought we had more, though. I rarely use it.~";
            "";
          MandrakeRoot: "~I use that for a sedative, but rarely.~";
          Mirror:
            "~Ah, the mirror serves medicine, not pride. I can check if pupils
            respond to light, examine the tongue and throat, see if jaundice
            yellows the eyes. Observation is key to healing.~";
          'code', 'combo', 'combination', 'lock', 'wheels':
            "~It's kept locked and only for my use.~";
        }
      Tell:
        if (metaclass(second) == Object && second has evidence)
          print_ret (string) MSG_DOES_SEEM_LIKE_EVIDENCE;

        wn = consult_from;
        if (MurderWord(NextWord()))
           print_ret (string) BENEDICT_ON_MURDER;
      Show:
        if (noun == Basil) "~I don't know what that plant is.~";
        if (noun ofclass Herb)
          "~Ah. Brother Aelred grew that in the garden for my use here.~";
        if (noun ofclass Decoction) {
          print
            "~What are you doing with one of my decoctions? These are for my use
            here.~^";
          if (noun == HenbaneDecoction)
            "^~Also, why is it so empty?~ He looks suspiciously at you.";
          rtrue;
        }
        if (noun has evidence)
          print_ret (string) MSG_DOES_SEEM_LIKE_EVIDENCE;
    ],
    history_text
      "Benedict (1298-). Entered 1318. Served as infirmarer from 1328. Treats
      both brothers and villagers who seek healing. Known for his patience with
      the dying.",
  has ;


Monk BrCuthbert "Brother Cuthbert"                                 ! >BrCuthbert
  with
    name 'cuthbert' 'sacrist',
    describe [ ;
      if (location == BellTower)
        "^Brother Cuthbert is here, looking dour and staring at the view.";
    ],
    description
      "Brother Cuthbert, the sacrist, is in his late forties. Dark-haired and
      sharp-featured, he keeps the sacred vessels spotless, the candles
      well-stocked, and the bell hours precise. He rarely smiles.",
    wont_talk
      "Brother Cuthbert refuses to engage in unnecessary speech, and considers
      almost all speech as such.",
    simple_name "Cuthbert",
    job_title "sacrist",
    walk_home Quire (w_to) (u_to) (u_to),
    walk_matins 0 (d_to) (d_to) (e_to) Stalls,
    walk_office (d_to) (d_to) (e_to) Stalls,
    possess 'cuthbert^s' 'cuthberts',
    home BellTower,
    went_home [;
      if (BellTowerChest has open) {
        give BellTowerChest ~open;
        print (bd) "^^Oh no! ";
        print
          "Brother Cuthbert discovered you invaded his bell tool chest";
        return WasCareless();
      }
    ],
    before [;
      WaveTo:
        "Brother Cuthbert purses his lips and does not reply.";
      Ask:
        switch (second) {
          'candle', 'candles':
            "In a rare act, he speaks. ~You have no need for such. And stay out
            of the Sacristy, Brother Novice.~";
        }
    ],
    orders [;
      Give:
        if (noun == CuthbertCandle)
          "In a rare act, he speaks. ~You have no need for such. And stay out of
          the Sacristy, Brother Novice.~";
    ],
    history_text
      "Cuthbert (1300-). Entered 1315, son of a nobleman from the south.
      Appointed sacrist 1325. Maintains the sacred vessels and vestments with
      meticulous care. Keeps the canonical hours by ringing the great bell.",
  has transparent ;


! Cuthbert doesn't really have a candle; this hidden object is just here so
! player can try CUTHBERT, GIVE ME CANDLE or such.

Object -> CuthbertCandle "cuthbert candle"
  with
    parse_name [;
      if (location ~= BellTower) return -1;
      if (NextWord() == 'candle' or 'candles') return 1;
    ],
    before "You cannot see any such thing.",
  has
    concealed ;


Monk BrHugh "Brother Hugh"                                             ! >BrHugh
  with
    name 'hugh' 'cellarer',
    description
      "Brother Hugh, the cellarer, is lean and blond, barely thirty but already
      worry-worn. He manages the priory's worldly goods---trade, stores,
      accounts---and the weight of it shows in his troubled expression.",
    simple_name "Hugh",
    job_title "cellarer",
    home Undercroft,
    walk_home Quire (s_to) (s_to) (s_to) (s_to) (s_to) (Undercroft),
    walk_office (u_to) (n_to) (n_to) (n_to) (n_to) (n_to) Stalls,
    walk_matins (d_to) (d_to) Stalls,
    possess 'hugh^s' 'hughs',
    life [ ;
      if (f_hugh_refuses_talk)
        "It appears Hugh refuses to have further conversation with you.";

      Ask, Tell:
        if (MurderWord(second)) "He is dismissive: ~Nonsense.~";

        switch (second) {
          InfirmaryCabinet, HenbaneDecoction,
          FeverFewDecoction, FoxgloveDecoction:
            "~I know Benedict stores medicines in the cabinet, that's all.~";
          Undercroft:
            "~You stay out of there, Brother Novice.~";
          MustardBarrel, MustardPackage, StolenPsalter, Coins, Letters:
            f_hugh_refuses_talk = true;
            "His mouth opens in shock for a second and then closes. He says
            nothing.";
          'rose', 'william', 'money', 'surgeon', 'payment':
            f_hugh_refuses_talk = true;
            "~I don't see how that's your business.~";
        }
      Show:
        <<Tell second noun>>;
    ],
    history_text
      "Hugh (1314-). Brought to the priory in 1322 as a child of eight, his
      family unable to feed him after failed harvests. Raised and educated by
      the brothers. Appointed cellarer 1342. Manages stores and trade with
      exceptional diligence. Has a widowed sister in the village of Coldport who
      visited once.",
  has ;


Monk BrMartin "Brother Martin"                                       ! >BrMartin
  with
    name 'martin' 'kitchener',
    describe [;
      if (location == Kitchen)
        "^Brother Martin is here, chopping vegetables.";
    ],
    description
      "Brother Martin, the kitchener, is short, round, and quick to
      laugh---unusual in this sombre place. He and Brother Remigio, the lay
      monk, produce the simple meals that sustain the community.",
    simple_name "Martin",
    job_title "kitchener",
    home Kitchen,
    walk_home Quire (s_to) (s_to) (s_to) (s_to) (s_to),
    walk_office (n_to) (n_to) (n_to) (n_to) (n_to) Stalls,
    walk_matins 0 (n_to) (d_to) (d_to) Stalls,
    possess 'martin^s' 'martins',
    wont_talk [;
      if (location == Kitchen)
        "Brother Martin responds: ~Forgive me, but Remigio and I have so much to
        do.~";
    ],
    before [;
      Smell: print_ret (The) self,
        " always smells a bit like the fire in the Kitchen.";
      Confess:
        "Brother Martin looks surprised. ~Confess? Perhaps you should talk with
        someone more senior.~";
    ],
    life [ ;
      Ask:
        if (MurderWord(second)) print_ret (string) MSG_JUST_HOPE_NOT_MURDER;

        switch (second) {
          BrAelred: "~What a tragic day. He was the most gentle of men.~";
          BrRemigio:
            if (location ~= Kitchen)
              "~Remigio is always in the Kitchen. He works very hard.~";
          BrHugh, Undercroft:
            print "~I see Brother Hugh often ";
            if (location == Kitchen) print "here"; else print "in the Kitchen";
            " since it's directly above the Undercroft.~";
          'basil': "~I've no time for such exotic herbs.~";
          'thyme', 'sage', 'mustard':
            "~Of course, I use that often in our cooking.~";
          'pottage', 'stew', 'soup', 'meal', 'food':
            "~Hungry already? We will have leek soup tomorrow morning.~";
        }
      Order:
        if (action == ##Give && noun == Fish && second == BrAldwin) {
          Kitchen.fish_give();
          rtrue;
        }
      Tell:
        wn = consult_from;
        if (MurderWord(NextWord())) print_ret (string) MSG_JUST_HOPE_NOT_MURDER;
    ],
    history_text
      "Martin (1304-). Entered 1322. Born into a prominent Welsh family.
      Appointed kitchener 1334. Oversees the preparation of meals for the
      community, assisted by Brother Remigio.",
  has ;


Monk BrOswald "Brother Oswald"                                       ! >BrOswald
  with
    name 'oswald' 'prior',
    description
      "Brother Oswald, the prior. Lean and grey-haired, in his early fifties, he
      governs the priory with stern discipline. You've learned to measure your
      words and deeds carefully in his presence.",
    simple_name "Oswald",
    job_title "prior",
    home PriorsSolar,
    went_home [;
      if (location == PriorsSolar) {
        style bold;
        print "^^Caught! ";
        style roman;
        print "Brother Oswald found you in his solar";
        give PriorDoor ~open;
        give BrOswaldChest ~open;
        give PriorDrawer ~open;
        return WasCareless(true);   ! true = move from solar
      }
      if (PriorDoor has open || BrOswaldChest has open
            || PriorDrawer has open) {
        give PriorDoor ~open;
        give BrOswaldChest ~open;
        give PriorDrawer ~open;
        style bold;
        print "^Caught! ";
        style roman;
        print "Brother Oswald found evidence you had been in his solar";
        return WasCareless();
      }
    ],
    wont_talk
      "Brother Oswald is quite stern about maintaining silence, and makes no
      effort to hide his displeasure.",
    walk_home Quire (s_to) (w_to) 0 PriorsSolar,
    walk_office (CloisterNW) (e_to) (n_to) (Stalls),
    walk_matins 0 (CloisterNW) 0 (e_to) (n_to) (Stalls),
    left_home [;
      give PriorDoor ~open locked;
    ],
    before [;
      Confess:
        "~We will have time to talk tomorrow, Brother Novice. Be at peace.~";
    ],
    life [ ;
      Show, Give:
        "Brother Oswald considers even this exchange to break the vow of
        silence, and refuses to even look down at the offer.";
      Tell:
        if (f_enough_evidence && (MurderWord(second) ||
              second == BrHugh or StolenPsalter or Coins or ScribbledNote
              or Letters)) {
          if (location ~= Quire)
            "[Rather than talking to Brother Oswald about your findings, go to
            the next service and make a public accusation.]";
          <<Solve>>;
        }
    ],
    history_text
      "Oswald (1294-). Entered in 1312 from a minor noble family. Elected prior
      1338 upon the retirement of Brother Wilfred. Governs with strict adherence
      to the Rule of St Benedict.",
  has ;


! Outside of first service, is always in the kitchen and never leaves.
!
! PUZZLE: will allow player access to undercroft & will give a candle
!   once bribed with the basil
!
! general = bribed with basil

Monk BrRemigio "Brother Remigio"                                    ! >BrRemigio
  with
    name 'remigio' 'lay' 'kitchen' 'assistant',
    describe [;
      ! During follow-remigio scene, don't describe him in LOOK --- the
      ! scene will handle that
      if (SceneFollowRemigio has general) rtrue;
      if (location == Slype)
        "^Brother Remigio is here, looking terrified.";
      if (location == Kitchen)
        "^Brother Remigio is here, tidying the table.";
    ],
    description [;
      if (SceneFollowRemigio has general)
        "Brother Remigio looks panicked. He keeps gesturing toward the Slype and
        saying ~Frate Aelred~.";

      if (SceneDeathInSlype has general)
        "Brother Remigio looks absolutely panicked.";

      "Brother Remigio is a lay brother from Tuscany---not fully professed, but
       devoted to the work. He's in his late thirties, with sharp features and
       expressive hands. His English is poor, and he often lapses into his
       native tongue.";
    ],
    simple_name "Remigio",
    job_title "lay kitchen assistant",
    walk_matins 0 0 (n_to) (n_to) (d_to) (d_to) (Stalls),
    possess 'remigio^s' 'remigios',
    home Kitchen,
    wont_talk [;
      print "Brother Remigio listens politely, but doesn't understand.^";
      return AskFail();
    ],
    life [ ;
      if (SceneDeathInSlype has general) {
        if (second == BrAelred)
          "~I come here, and I see him on ground. I try to help, but he---~
          Remigio's voice breaks. ~He cannot speak right. I run to find you.~";
        "Remigio looks too stunned to respond to anything.";
      }
      Tell:
        if (BrMartin in Kitchen)
          "Brother Martin cuts you off with a gesture to his lips. ~No idle
          chatter, Brother.~";
        if (second == Basil) {
          if (BrRemigio hasnt general)
            "~Basilico? Here?~";
          <<Ask BrRemigio Basil>>;
        }
      Ask:
        if (BrMartin in Kitchen) {
          "Brother Remigio looks down, uncomfortable answering anything with
          Brother Martin here.";
        }

        if (MurderWord(second)) "~Assassinio?~ He looks terrified.";

        switch (second) {
          BrHugh:
            "~Frate Hugh? Good man. He work hard down there, always busy
            with...~ he gestures vaguely at the floor, ~...stores, s@`i?~";
          BrAelred:
            "~Such sad thing.~ He looks despondent.";
          BrMartin:
            "~Ah, Frate Martin! He is...~ Remigio searches for words. ~Very good
            man. Kind. We work, uh, insieme---together---in cucina, the Kitchen.
            He teach me English.~ He smiles warmly. ~He no here now. At
            church.~";
          BrBenedict:
            "~Such good eater, s@`i? I like him.~";
          BrAnselm:
            "~Cosi bravo cantante!~ He gestures expressively. ~Uh, so good
            singer. When he sing, I feel...~ he touches his chest,
            ~...home.~";
          BrCuthbert:
            "~Frate Cuthbert ring the bells. Very loud!~ He rubs his ears with
            a smile. ~But is good. Prayer good.~";
          BrOswald:
            "~Frate Oswald, uh, has many rules, but he kind to me.~";
          BrWilfred:
            "~So wise and kind. I see him talking to bella gatta.~";
          BrAldwin:
            "~You? You are...~ he grins. ~Come si dice? Tadpole. Small, new.
            But you grow, s@`i?~";
          BrRemigio, 'himself':
            "~Me?~ He laughs, a little surprised. ~I am... nobody. A man who
            walk very far.~ He wipes his hands on his habit. ~I find this place,
            they let me stay. I work hard. Is enough, no?~";
          Pax:
            "~Ah, la gatta! Frate Wilfred, he love her much. She good mouser.
            Always hungry.~";
          Basil:
            "~Ah, it makes me happy.~";
          'priory':
           "~It is safe here.~";
          'tuscany', 'toscana', 'italy', 'home':
            "~Toscana.~ He is quiet for a moment, his eyes distant. ~Is... how
            to say... the hills, they are gold in summer. The sun, he is warm.
            Not like here.~ He glances at the grey stone walls around him. ~I
            not speak of it. Is better not to.~";
        }

      Give:
        if (BrMartin in Kitchen)
          "You daren't give Brother Remigio anything with Brother Martin here.";

        if (noun == Basil) {
          #IfDef HAS_QUOTES; QuoteBoxSimple(quote_stranger); #EndIf;
          TaskDone(TASK_BRIBE_WITH_BASIL);
          remove Basil;
          give self general;
          print
            "Remigio's weathered face transforms. ~Basilico!~ he exclaims,
            taking the herb and breathing deeply. ~I not smell since Toscana.~
            His eyes glisten. ~Frate Aelred grew for me? He was brav'uomo, a
            good man.~";
          if (Kitchen has on) { ! tried going down stairs
            "^^He gestures toward the stairs, his voice thick. ~Grazie mille,
            uh, thanks you. Go. I not see you.~";
          }
          "^^He clasps your hand warmly. ~Grazie mille, uh, thanks you. You need
          to do something, Remigio let you. Yes?~";
        }
      Show:
        if (noun == Basil)
          "Brother Remigio's eye widen in surprise when he sees this herb of his
          homeland. ~Basilico!~ he exclaims.";
        if (noun ofclass Herb)
          "Brother Remigio acknowledges you showing him a plant, but makes no
          comment.";
      Order:
        if (action == ##Give && noun == Fish && second == BrAldwin) {
          if (self has general && BrMartin notin location) {
            if (TryToTakeNoun(Fish) ~= 1)
              "Brother Remigio gives you the piece of fish with a shrug.";
            rtrue;
          } else {
            "~No, no. You need ask Frate Martin.~";
          }
        }
    ],
    before [;
      Confess:
        if (BrMartin in Kitchen)
          "Brother Remigio looks down, uncomfortable answering anything with
          Brother Martin here.";

        "~Confessare? To Remigio?~ His eyes sparkle. ~I not a priest. But I say:
        forgive people. Is good, to forgive.~";
      Smell: print_ret (The) self,
        " always smells like the fire in the Kitchen.";
      WaveTo:
        if (SceneDeathInSlype has active)
          "Brother Remigio is too stunned at what he's seeing to even notice
          your wave.";
        if (location == Kitchen && BrMartin in Kitchen)
          "Brother Remigio smiles briefly at your wave, but dares not reply
          with Brother Martin here.";

        "~Is good to greet Remigio, yes!~ He smiles at your gesture.";
    ],
    history_text
      "Remigio (c.1308-). A lay brother from Tuscany, came to the priory in 1340
      seeking refuge from troubles in his homeland. Works in the Kitchen and
      performs manual labour. Has not taken full vows.",
  has ;


! Always guards the library (he's excused from other services)
!
! PUZZLE: can put him to sleep with burning mandrake
!
! He'll have limited conversation w/PC in the library.

Constant MSG_WILFRED_DEEP_IN_SLEEP = "Brother Wilfred is fast asleep.";

Monk BrWilfred "Brother Wilfred"                                    ! >BrWilfred
  with
    name 'wilfred' 'librarian',
    describe [;
      if (BrWilfred in Scriptorium) {
        print "^Brother Wilfred sits at the table, close to the fireplace";
        if (BrWilfred hasnt awake) print ", snoring heavily";
        if (Pax in self) print ". Lying on his lap is ", (the) Pax;
        ".";
      }
    ],
    description [;
      if (self hasnt awake)
        print_ret (string) MSG_WILFRED_DEEP_IN_SLEEP;
      else
        print
          "Brother Wilfred, the librarian, is the most venerated of the
          brethren, well over seventy. He's lean and wiry, with wisps of white
          hair shooting in all directions from his head. His habit has bits of
          orange fluff or fur on it";
      if (Pax in self)
        print ".^^He currently has ", (the) Pax, " on his lap";
      ".";
    ],
    simple_name "Wilfred",
    job_title "librarian",
    possess 'wilfred^s' 'wilfreds',
    tired_count 0,  ! don't repeat messages
    home Scriptorium,
    walk_home 0 Quire (s_to) (e_to) (s_to) 0 (e_to),
    walk_office 0 (w_to) (n_to) (w_to) (n_to) Stalls,
    walk_matins 0 0 (n_to) 0 0 (d_to) (d_to) Stalls,
    yawn_check 0,
    yawn [ ;
      if (BrWilfred hasnt awake || deadflag || f_ever_offered_confession
            || waittime_waiting)
        rfalse;
      self.tired_count++;
      if (self.tired_count > 5) rfalse;
      print "^Brother Wilfred ";
      switch (self.tired_count) {
        1, 6: "yawns sleepily.";
        2: "rubs his temples wearily.";
        3: "stifles a yawn.";
        4: "rubs his eyes.";
        5: "blinks his eyes heavily.";
      }
    ],
    left_home [;
      move LibraryKey to BrWilfred;
    ],
    went_home [;
      if (LibraryDoor has open) {
        give LibraryDoor ~open;
        move LibraryKey to ScriptoriumTable;
        print (bd) "^Oh no! ";
        print "Brother Wilfred discovered that the library door was open";
        return WasCareless();
      }
      if (LibraryKey notin BrWilfred or ScriptoriumTable) {
        move LibraryKey to ScriptoriumTable;
        print (bd) "^Oh no! ";
        print
          "Brother Wilfred discovered that the library key wasn't on the table
          where he keeps it";
        return WasCareless();
      }
      move LibraryKey to ScriptoriumTable;
    ],
    add_to_scope FluffOrFur,
    each_turn [ ;
      if (self in Scriptorium && ++self.yawn_check % 4 == 0) self.yawn();
      ! if (self in Scriptorium) give self transparent;
      ! else give self ~transparent;
    ],
    life [ ;
      if (action ~= ##WakeOther && BrWilfred hasnt awake)
          print_ret (string) MSG_WILFRED_DEEP_IN_SLEEP;
      WakeOther:
        self.yawn_check = 0;
        "As you're about to shake Brother Wilfred, his eyes snap open. ~Dear
        child,~ he says, ~I was just resting my eyes.~";
      Ask:
        if (MurderWord(second))
          "~Now, none of that kind of talk, dear child.~";

        switch (second) {
          BrAelred:
            "~What a loss for our community. I knew him his entire adult life,
            and such a pleasant acquaintance it was. He was always
            thoughtful---he began to bring me rosemary sprigs after he learned
            that that was my mother's name.~";
          BrAnselm:
            "~Such a beautiful voice for one so young.~";
          BrAldwin:
            "~You? You're doing well, my child.~ His eyes twinkle.";
          BrBenedict:
            "~Brother Benedict makes me valerian tea to steady me.~ He looks
            down at the small tremble in his hands.";
          BrCuthbert:
            "~Such a god-fearing man and so careful in his duties. I know he can
            be hard on novices, but he means well for your spiritual care.~";
          BrHugh:
            "~A fine cellarer. In the past few months, he's been helping me in
            the Library.~";
          BrMartin:
            "~Brother Martin keeps us all well-fed, even in these lean times. A
            generous soul.~";
          BrOswald:
            "~He's done very well as prior. That was once my role, but---~ He
            looks at you with tenderness. ~Age comes for us all, my son.~";
          BrRemigio:
            "~Brother Remigio? We speak little: his English, my Italian, neither
            sufficient.~ He chuckles. ~But we both love our little Pax, and that
            needs no words.~";
          BrWilfred:
            "~Me? I'm simply a child of God, like you, dear Aldwin.~";
          TombGordian:
            "~Before even my time, my son, but by all accounts a most clever and
            reverent man. Did amazing work in brass---almost like clockwork.~";
          Pax:
            Pax.learn_name();
            self.yawn_check = 0;
            "His eyes glisten. ~Forgive an old brother, but that cat has become
            very dear to me. I was the one who named her---'Pax', for the peace
            she brings to these old halls.~";
          Breviary:
            "~Ah, my breviary. I have done finer work.~ A pause that does not
            invite contradiction. ~But the patterns are sound. Whatever else,
            the patterns are sound.~";
          StolenPsalter:
            "~I don't understand how I misplaced it. I'm always so careful.
            Brother Hugh even helped me look for it.~";
          Library, LibraryKey:
            "~I'm afraid I can't let you in. The Library is off-limits to
            everyone but me. Strict orders from the prior.~";
          'valerian':
            "~Oh, yes. That helped a lot.~";
          'rosemary', 'mother':
            "His eyes mist, but he says nothing.";
          'fluff', 'fur', 'orange', 'habit':
            print "~Oh.~ He looks abashed, and brushes at his habit.";
            if (Pax has proper)
              " ~Dear old Pax.~";
            "";
          default:
            print "Brother Wilfred hushes you kindly. ~Never mind that.~^";
            return AskFail();
        }

      Tell:
        if (f_enough_evidence) {
          if (location ~= Scriptorium)
            "~My friend, come find me in the Scriptorium and we can talk
            there.~";
          if (MurderWord(second) || second == BrHugh or StolenPsalter or Coins
              or Chronicle or ScribbledNote or HenbaneDecoction or Henbane
              or Letters)
            "[If you'd like to tell Brother Wilfred about what you found,
            CONFESS TO WILFRED.]";
        } else if (MurderWord(second)) {
          "~Now, none of that, my child. Keep your mind on God.~";
        }

        switch (second) {
          BrHugh:
            "~I won't listen to gossip.~";
          StolenPsalter:
            if (StolenPsalter in nothing)
              "~I'm just delighted to have it back.~";
            if (StolenPsalter has moved)
              "~Found? I didn't lose it?~ He looks delighted.";
          Library, LibraryKey:
            "~I'm afraid I can't let you in.~";
          default:
            self.yawn_check = 0;
            "Brother Wilfred listens sleepily without response.";
        }

      Give:
          if (noun == Rosemary) {
            remove Rosemary;
            "Brother Wilfred accepts the gift. ~Thank you, Brother Aldwin.~";
          }
          if (noun == StolenPsalter) {
            <Ask self StolenPsalter>;
            remove StolenPsalter;
            "^He takes it, tucking it into his robe.";
          }
          if (noun == Pax) {
            if (location ~= Scriptorium)
              "Brother Wilfred strokes her head for a moment, but declines.";
            SceneLibraryCat.scene_start();
            rtrue;
          }
        Show:
          if (noun == StolenPsalter) <<Tell self StolenPsalter>>;
          if (noun == Rosemary)
            "Brother Wilfred does not comment, but you see a small smile come on
            to him on seeing this.";
          if (noun == Pax) {
            "He seems delighted and scratches her on her head.";
          }
        PutOn:
          if (noun == Pax) {
            if (location ~= Scriptorium)
              "Brother Wilfred strokes her head for a moment, but declines.";
            SceneLibraryCat.scene_start();
          }
    ],
    orders [;
      Eat:
        "Brother Wilfred adamantly refuses to eat ", (the) noun, ".";
    ],
    before [;
      Rub: <<Take FluffOrFur>>;
      Search:
        if (self hasnt awake)
          "You gingerly search the sleeping brother, but find nothing.";

      Confess:
        if (BrWilfred hasnt awake)
          print_ret (string) MSG_WILFRED_DEEP_IN_SLEEP;
        if (f_enough_evidence) {
          if (location == Quire)
            "Brother Wilfred puts his fingers to his lips, but also makes a
            gesture pointing south. You assume that he's pointing toward the
            Scriptorium, where you can talk later.";
          if (location ~= Scriptorium)
            "~My friend, come find me in the Scriptorium and we can talk
            there.~";
          SceneConfession();
          rtrue;
        }
        "~Dear child, I will always hear your confession. But later---there is
        much on my mind now.~";
    ],
    history_text
      "Wilfred (1273-). Entered 1290 from a scholarly family in Norwich. Elected
      prior 1310, serving until 1338 when he stepped down due to age. Now serves
      as librarian and master illuminator, though his hands tremble with the
      years. The oldest brother in living memory, he has seen the priory through
      plague, famine, and decline.

      ^^You note that this entry was written by Brother Wilfred himself, but in
      his way, he tried to maintain a scholarly and truthful tone.",
  has
     ;


Object FluffOrFur "Brother Wilfred's habit"
  class AdjObject,
  with
    adj_name 'Brother' 'Wilfred' 'Wilfred^s',
    noun_name 'habit' 'fluff' 'fur' 'robe',
    description [;
      print
        "Brother Wilfred's habit is a plain black robe, like yours";
      if (~~f_seen_pax)
        ". You're not sure what the orange fluff is.";
      print
        ". Looking more closely, the orange fluff appears to be ";
      if (Pax has moved) print "fur from ", (the) Pax;
      else print "animal fur";
      ".";
    ],
    before [;
      Take, Rub, Pull:
        "Tidying the fur from Brother Wilfred's habit is well-intended, but you
        refrain from it.";
      Receive:
        if (noun == Pax && location == Scriptorium && BrWilfred has awake)
          <<Give Pax BrWilfred>>;
    ],
  has clothing proper;


!======================================================================== Aldwin


Object BrAldwin "you"                                                ! >BrAldwin
  with
    name 'me' 'myself' 'self' 'aldwin',
    short_name  [;
      if(caps_mode) { print "You"; rtrue; }
      print "yourself";
      rtrue;
    ],
    description
      "You're a novice in your first year, younger than all of the professed
      monks. Your black habit marks you as Benedictine, though you haven't yet
      taken your final vows.",
    capacity MAX_CARRIED,
    react_before [;
      ! Putting these in react_before so they'll come before things like blocks
      ! during services
      Ask, Tell, Order:
        if (noun == self)
          "You shouldn't talk to yourself.";
      Give, Show:
        if (second == self)
          "You can't do this to yourself.";
      Confess:
        if (noun == self)
          "Alas, you cannot offer yourself absolution.";
    ],
    before [;
      Heal:
        "If you were ill, you would trust Brother Benedict to care for you.";
      WaveTo:
        "What madness has gripped you---waving to yourself?";
      Rub:
        "But you're already clean---bathing day was only a few days ago.";
    ],
    react_after [;
      Go:
        if (location == thedark) NowInDark();
    ],
    history_text
      "Aldwin (1326-). Joined us in 1346, coming from a family serving Lord
      Thornbury. Educated by that Lord. Mother died young. Interested in
      gardening, so he is being mentored by Brother Aelred.",
  has concealed animate proper transparent convo;


Object -> MyRobe "your robe"                                     ! >MyRobe
  class AdjObject,
  with
    adj_name 'my' 'aldwin' 'aldwin^s' 'mine' 'your',
    noun_name 'robe' 'habit' 'clothes',
    invent [ ;
      print "your robe (worn)";
      if (PrintContents(" (hidden in the hood: ", MyHood)) print ")";
      rtrue;
    ],
    ! add_to_scope MyHood,
    description
      "A simple black woollen cloth, marking you as a novice of this house. It
      doesn't have pockets, but a large hood hangs at your back.",
    before [;
      Receive: "Your robe has no pockets.";
      Disrobe: "You dare not. A monk must always be ready for office.";
      Take: "You're already wearing it.";
      Search:
        print "There's nothing in your robe";
        PrintContents(", but hidden in the hood ", self, ISARE_BIT);
        ".";
      Wear:
        "You're already wearing it. Outside of a weekly washing, you're always
        wearing it.";
      LookUnder: "Just you.";
      Smell: "It's been a few days since washing day.";
    ],
  ! has container clothing transparent worn ok_carry;
  ! has proper clothing container worn ok_carry ;
  has proper clothing worn transparent open container ok_carry ;


Object -> -> MyHood "hood"                                            ! >MyHood
  class AdjObject,
  with
    adj_name 'robe' 'my' 'aldwin' 'aldwin^s',
    noun_name 'hood',
    capacity 6,
    description [;
      print
        "A deep hood attached to your habit, large enough to pull over your head
        in foul weather";
        PrintContents(". In the hood ", self, ISARE_BIT);
        ".";
    ],
    before [;
      Pull, Raise:
        "It's neither cold nor raining. It would draw attention to have your
        hood up.";
      Insert:
        "The hood is attached to your robe. You cannot put it in ",
        (the) second, ".";
      Receive:
        if (noun has light)
          "Placing a lit item in your hood would surely catch it on fire.";
        if (noun == Basket)
          "The basket won't fit in the hood.";
      Wear, Take:
        "It's part of your robe, which you're already wearing.";
      Search:
        if (~~PrintContents("In the hood ", self, ISARE_BIT))
          print "There is nothing in the hood";
        ".";
    ],
    after [;
      Receive:
        if (noun hasnt ok_carry) f_hid_contraband = true;
    ],
  has concealed static container open ;


!=========================================================================== Pax

Object Pax                                                                ! >Pax
  with
    parse_name [ w1 ;
      w1 = NextWord();
      if (w1 == 'pax' or 'cat' or 'gatta') return 1;
      if (w1 == 'orange' && NextWord() == 'cat') return 2;
      if (w1 == 'bella' && NextWord() == 'gatta') return 2;
      return 0;
    ],
    article "an",
    short_name "orange cat",
    description [;
      print "She is small and lean";
      if (self has general) print ", and purrs when she sees you";
      else print " with hunger";
      ".";
    ],
    learn_name [;
      give self proper;
      self.short_name = "Pax";
    ],
    appears_count 0,
    each_turn [ ;
      if (location == Scriptorium || waittime_waiting) rfalse;
      if (self in player) {
        print "^", (The) self;
        if (location ~= Garth && ~~location ofclass Cloister) {
          remove Pax;
          " appears uncomfortable in unfamiliar indoor places, and wriggles out
          of your arms and escapes.";
        }
        switch (random(3)) {
          1: " purrs contentedly in your arms.";
          2: " trills happily while you hold her.";
          3: " continues to rest in your arms.";
        }
      }

      if (random(4) ~= 1) rfalse;

      print_ret "^", (The) self, (string) random(
        " rubs against the walls.",
        " twitches, sensing movement somewhere.",
        " wriggles.",
        " licks a paw contentedly."
      );
    ],
    life [;
      Give:
        if (ImplicitGrabIfNotHeld(noun)) rtrue;
        if (noun == Fish) {
          remove Fish;
          give self general;
          update_moved = true;
          print_ret
            (The) self,
              " eats the fish hungrily then rubs against you, purring.";
        }
        if (noun has toxic) {
          "Surely you don't want to poison this innocent creature of God?";
        }
        "She turns up her nose at your offer.";
      Show:
        if (ImplicitGrabIfNotHeld(noun)) rtrue;
        if (noun == Fish)
          "She cries loudly with excitement and hunger.";

      default: "She only mews in response.";
    ],
    before [ ;
      Confess:
        print_ret
          (The) Pax, " listens attentively, then mews sadly in response.";
      Attack, ThrownAt:
        remove self;
        "She flees into the Garth at your movement.";
      Kiss:
        if (self hasnt general)
          "Cats usually need to be bribed to let you touch them.";
        switch (random(3)) {
          1: "She allows a small head kiss.";
          2: "She pushes her nose affectionately against your hand.";
          3: "She mews with delight.";
        }
      Follow:
        print_ret (The) Pax, " is too nimble for you to follow.";
      LookUnder:
        if (self in BrWilfred)
          "The only thing you see under ", (the) self, " is Brother Wilfred.";
      Take:
        if (self hasnt general)
          "You dare not. She hisses as you start to try.";
      PutOn:
        if (second == BrWilfred) <<Give Pax BrWilfred>>;
      Smell:
        "Wool and wood smoke, with a faint undercurrent of mouse.";
      Insert: "She wouldn't find that very comfortable.";
    ],
    after [;
      Take:
        "She allows you to pick her up.";
      Drop:
        remove self;
        "She scampers away.";
    ],
    history_text
      "In the margin, you find a note: ~Pax: First spotted in 1342 by Remigio.
      She's an excellent ratter and conversationalist, though her Latin is
      poor.~",
  has
    female animate convo ok_carry;



!===============================================================================
!======================================================================== SCENES

! Kind of a scaled-down version of Inform7 scenes; these objects are in scope
! and have "active" when the scene is happening. Some scenes have a more strict
! definition of "happening" (like offices, when you want to find out if the
! actual services and singing has started); for this, check "on".
!
! Multiple scenes can be happening at the same time, but BE CAREFUL and test
! this to make sure there aren't weird interactions. Generally, it should be
! safe for a SceneService (an office) to be happening at the same time as a non-
! service.


Class Scene                                                             ! >Scene
  with
    time_left 0,
    parse_name [;
#IfDef DEBUG;
      if (action_to_be ~= ##StartScene or ##StopScenes) return 0;
      if (NextWord() == self.&name-->0) return 1;
#EndIf;
    ],
    scene_start [;
      self.time_left = 0;
      give self general;
      f_can_complex_wait = false;
      ! scenes are in the robe, which is a bit strange, but works fine --- it
      ! removes quirky things about having them use add_to_scope and making sure
      ! the can't be seen or referred to.
      move self to MyRobe;
      update_moved = true;
      ! scope_modified = true;
      StartDaemon(self);
      #IfDef FULL_DEBUG;
        print "*** SCENE START ", (the) self, " at ", (RealTime) the_time,  "^";
      #EndIf;
    ],
    scene_stop [;
      give self ~general ~on visited;
      remove self;
      f_can_complex_wait = true;
      StopDaemon(self);
      scope_modified = true;
      #IfDef FULL_DEBUG;
        print "*** SCENE STOP ", (the) self, " at ", (RealTime) the_time,  "^";
      #EndIf;
    ],
  has proper scenery concealed ;


! This is the period after lauds but before the players run into Remigio

Scene SceneWandering "SceneWandering"                          ! >SceneWandering
  with
    name 'wandering',
    time_left 0,
    react_after [ ;
      Go:
        if (location == CloisterSW or CloisterSE) {
          self.scene_stop();
          SceneFollowRemigio.scene_start();
        }
    ],
    daemon [;
      self.time_left++;
      switch(self.time_left) {
        10:
          "^You remember Brother Aelred's request to meet him this morning. You
          know he'll be in the gardens, south of the Cloister.";
        16:
          "^You know you should go to the gardens. You wouldn't want to keep
          your mentor waiting.";
        20:
          self.scene_stop();
          SceneFollowRemigio.scene_start();
      }
    ],
  has ;


Constant MSG_I_FIND_HIM
  "I find him---he very bad. His eyes---strano. Strange. Please, fastly!";


Scene SceneFollowRemigio "SceneFollowRemigio"              ! >SceneFollowRemigio
  with
    name 'follow',
    time_left 0,
    react_before [ dir ;
      Follow:
        if (noun == BrRemigio && BrRemigio in location) {
          dir = PropToDir(location.toward_slype);
          <<Go dir>>;
        }
      Go:
        if (selected_direction == location.toward_slype)
          print "You follow Brother Remigio ",
              (DirName) selected_direction, ".^";
      Tell, Ask, AskFor, Order:
        if (noun == BrRemigio) {
          if (second == BrAelred)
            print_ret (string) MSG_I_FIND_HIM;

          wn = consult_from;
          switch (NextWord()) {
            'aelred', 'slype', 'brother':
              print_ret (string) MSG_I_FIND_HIM;
          }
        }
        switch (random(3)) {
          1:
            "Brother Remigio practically shouts: ~La urgenza---uh, fastly~ and
            points ", (DirName) location.toward_slype, ".";
          2:
            "Brother Remigio tugs at his hair in frustration.";
          3:
            "Looking frantic, Remigio says something in his native tongue.";
        }
    ],
    react_after [ ;
      Go:
        MovePerson(BrRemigio, location, true);
        if (location == Slype) {
          self.scene_stop();
          SceneDeathInSlype.scene_start();
        }
      Look:
        if (self.time_left)  ! not 0
            "^Brother Remigio desperately signals you to follow him ",
            (DirName) location.toward_slype, " to the Slype.";
        ;
    ],
    daemon [;
      self.time_left++;
      if (self.time_left == 1) {
        MovePerson(BrRemigio, location, true);
        PronounNotice(BrRemigio);
        "^The lay monk, Brother Remigio, runs up to you, his face ashen. ~You!~
        he cries, grabbing your sleeve. ~Come---Frate Aelred, l'erborista, he
        is, the Slype---~ He cannot find the words. His eyes say everything. He
        urgently points ",
        (DirName) location.toward_slype, ".";
      }
      if (self.time_left == 14) {
        print
          "^Unfortunately, you arrive at the Slype too late. Brother Aelred had
          died by the time you got there, and you missed his final words. You'll
          never forgive yourself for not comforting him at his end.";
        deadflag = 3;
        return;
      }
      if (action ~= ##Go or ##Follow)
        "^Brother Remigio implores you to move quickly.";
    ],
  has ;


Scene SceneDeathInSlype "SceneDeath"                        ! >SceneDeathInSlype
  with
    name 'death',
    time_left 0,
    scene_start [;
      self.Scene::scene_start();
      ! the_time = time_time + 20;
      move BrAelredDying to Slype;
      move BrRemigio to Slype;
      #IfDef DEBUG;
        if (location ~= Slype) PlayerTo(Slype);
      #EndIf;
    ],
    scene_stop [;
      self.Scene::scene_stop();
      the_time = the_time + 20;
      remove BrAelredDying;
      move BrAelredHabit to BrAelredBody;
      move BrAelredEyes to BrAelredBody;
      move BrRemigio to Kitchen;
      move BrAelredOtherParts to BrAelredBody;
      move BrAelredHand to BrAelredBody;
      move BrAelredMouth to BrAelredBody;
    ],
    react_before [;
      Confess:
        if (noun == BrRemigio)
          "Brother Remigio looks too shocked by what he sees to do anything like
          that.";
      Go:
        "You wouldn't dare abandon Brother Aelred.";
      Pray:
        "You pray fervently for Brother Aelred.";
      Shout:
        "You yell, hoping a nearby brother will hear and bring aid.";
      Listen:
        if (noun ~= nothing or BrAelredDying) rfalse;
        switch (self.time_left) {
          0: "You hear Brother Aelred's labored breathing.";
          1, 2, 4: "You listen to Brother Aelred:";
          3: "You hear only Brother Aelred's convulsions.";
          5: "You hear only Brother Remigio weeping.";
        }
      Smell:
        if (noun == nothing)
          "There's something odd in the air, and it seems to be coming from
          Brother Aelred.";
      KneelAny, SitAny:
        if (BrAelredDying hasnt general)
          "You position yourself next to Brother Aelred for a minute, trying to
          comfort him. Then, you rise back up.";
        "You position yourself next to your former mentor for a moment, and
        then rise up.";
    ],
    daemon [;
      self.time_left++;
      switch (self.time_left) {
        1:
          PronounNotice(BrAelredDying);
          "^Brother Aelred is clearly unwell. His movements are frantic and his
          eyes look unusual.";
        2:
          "^Brother Aelred seems gripped with delirium. ~Gathering... he was
          always gathering... I wanted to know why...~";
        3:
          "^Brother Aelred's hand jerks, trembling, gesturing north toward the
          bushes lining the Slype and the Scriptorium behind. His lips move.
          ~The letter... the letter told me everything...~";
        4:
          "^Brother Aelred convulses wildly. The end of his earthly time cannot
          be far.";
        5:
          give BrAelredDying general;
          "^A strange peace crosses Brother Aelred's face. He finds your hand
          and holds it with surprising strength. ~One life for two, my friend.~
          He smiles, looking towards Heaven---and is gone.";
        6:
          self.scene_stop();
          StoryPause();
          print
            "^Having heard Remigio's cries, Prior Oswald arrives and, upon
            seeing the wide and still eyes of Brother Aelred, makes the sign of
            the cross and whispers a prayer. The other brothers assemble.
            Brother Benedict, the infirmarer, is called upon to determine if
            Aelred is dead, and does so.

            ^^You find yourself in the garden without quite knowing how you got
            there, standing among Brother Aelred's carefully tended beds. Your
            friend. Your mentor. The pangs of loneliness that have eaten at you
            on long nights return cruelly.

            ^^Brother Wilfred, the venerable librarian, finds you in the Garden
            and tries to offer consolation: ~My child~, he says, ~you will
            always have a friend in me. Brother Aelred lived a joyful life, and
            we can carry on in his spirit with your help.~ He gestures to the
            gardens that you have grown to love so much.

            ^^You are told by others that there is a meeting in the Chapter
            House. You dry your eyes and make your way there.^";
          StoryPause();
          new_line;
          SceneMeeting.scene_start();
      }
    ],
  has ;


Scene SceneMeeting "SceneMeeting"                                ! >SceneMeeting
  with
    name 'meeting',
    time_left 0,
    scene_start [ i ;
      self.Scene::scene_start();
      give self on;  ! oswald talking
      for (i = 1 : i < ALL_MONK_NUM : i++) {  ! skip aelred at 0
        move all_monks-->i to ChapterHouse;
      }
      PlayerTo(ChapterHouse);
    ],
    react_before [;
      Examine, Look, Think, Offices, Time, Sit, SitAny, Smell, Pray, Inv,
      WaitHours, WaitMinutes, WaitMoves, WaitUntil, Enter: ;
      Go:
        if (self has on)
          "You dare not leave during the meeting.";
        "You're too struck considering what Prior Oswald said to leave quite
        yet. Brother Aelred died of a heart attack? It didn't seem so to you.";
      Ask, Tell, Show:
        if (self has on)
          "Brother Martin, sitting beside you, rebukes you kindly: ~We should
          listen to what our prior tells us.~";
      WaveTo:
        if (self has on)
          "You dare not interrupt the meeting by waving.";
      Listen:
        if (noun ~= nothing or BrOswald) rfalse;
        if (self has on) "You listen intently to Brother Oswald.";
      Wait:
        if (self has on) <<Listen>>;
      default:
        if (self has on)
          "You dare not disturb the meeting with such an action.";
    ],
    daemon [ i ;
      self.time_left++;
      switch (self.time_left) {
        1:
          for (i = 1 : i < ALL_MONK_NUM : i++) {   ! skip aelred at 0
            move all_monks-->i to ChapterBenches;
          }
          "^The brothers gathered here begin to find seats, and Brother Oswald,
          the prior, begins to speak.";
        2:
          if (player notin ChapterBenches) {
            print "^You sit on a bench next to Brother Anselm.^";
            move player to ChapterBenches;
            ! update_moved = true;
          }
          "^~Brothers,~ starts Brother Prior Oswald, ~this is a terrible day for
          our community: the loss of our herbalist, Brother Aelred.~";
        3:
          "^Brother Oswald pauses. ~Brother Aelred's passing was... sudden. He
          did have a weak heart. Let us thank God that his passing was quick.~";
        4:
          "^Brother Oswald continues: ~We will observe a day of fasting today
          and break our fast after Matins tomorrow. Brother Benedict has placed
          our dear brother in the Infirmary Chapel. You may pay your final
          respects to him there.~";
        5:
          "^Brother Oswald continues: ~Our novice~---he gestures toward
          you---~is doing adequately in his role, and will spend today
          cataloguing the gardens. He and I will meet after the burial tomorrow
          to decide how to proceed without our herbalist.~";
        6:
          "^Brother Oswald continues: ~Of course, we will continue to hold the
          rest of our Divine Offices today---however, given the circumstances,
          some of you may be absent. To this, I give my blessing.~";
        7:
          for (i = 1 : i < ALL_MONK_NUM : i++) {   ! skip aelred at 0
             move all_monks-->i to location;
          }
          give self ~on;
          "^The meeting draws to a close and the brethren stand.

          ^^[You can always get a list of brothers with you with the command
          HERE.]";
        8:
          BrWilfred.yawn();
          move BrOswald to BrOswald.home;
          move BrBenedict to BrBenedict.home;
          move BrRemigio to BrRemigio.home;
          move BrCuthbert to BrCuthbert.home;
          move BrHugh to BrHugh.home;
          if (location == ChapterHouse)
            "^Brothers Oswald, Hugh, Benedict, Cuthbert and Remigio leave.";
        9:
          move BrWilfred to BrWilfred.home;
          move BrMartin to BrMartin.home;
          move BrAnselm to BrAnselm.home;
          if (location == ChapterHouse) {
            print
              "^Brothers Wilfred, Martin and Anselm depart, leaving you
              alone.^";
          }

          #IfDef HAS_HINTS;
            HintReady(Hint_Solving);
            HintReady(Hint_Evidence);
          #EndIf;

          self.scene_stop();
          the_time = 4 * 60;

          "^You feel a deep sense of obligation to Brother Aelred. Something
          about this death doesn't feel right or natural. You vow to discover
          what happened and why. You'll need to finish your investigation by the
          end of Compline tonight, since Brother Aelred will be buried tomorrow
          morning.

          ^^You're not sure where to begin, but examining his body in the
          Infirmary Chapel or searching his Herbarium might be good places to
          start.

          ^^Of course, such an investigation would be unsanctioned by the prior.
          You'll have to cover your tracks carefully.";
      }
    ],
  has ;


Constant MSG_AWAKE_WILFRED_LIB
  "~Ah, young son, you'll have to
  pardon an old man his weakness.~ He blinks sleepily at you.";
Constant MSG_WILFRED_ASLEEP
  "^Brother Wilfred seems deeply asleep.";

Scene SceneLibraryMandrake "SceneMandrake"               ! >SceneLibraryMandrake
  with
    name 'smoke',
      scene_start [;
        self.Scene::scene_start();
    #IfDef DEBUG;
        if (location ~= Scriptorium) PlayerTo(Scriptorium);
        move MandrakeRoot to ScriptoriumFireplace;
        update_moved = true;
        f_can_complex_wait = true;
    #EndIf;
      ],
    scene_stop [;
      self.Scene::scene_stop();
      give BrWilfred awake;
      BrWilfred.went_home();
      remove MandrakeRoot;
      BrWilfred.yawn_check = 0;
    ],
    react_before [;
      WakeOther:
        if (BrWilfred hasnt awake) {
          self.scene_stop();
          print_ret (string) MSG_AWAKE_WILFRED_LIB;
        }
      Shout:
        "You dare not---it would awaken Brother Wilfred.";
    ],
    daemon [;
      self.time_left++;
      switch (self.time_left) {
        1:
          if (player notin Scriptorium) return;
          "^An unpleasant, acrid stench starts to fill the room. To be cautious,
          you move to the other side of the room, far from the fireplace.";
        2:
          give BrWilfred ~awake;
          if (player notin Scriptorium) return;
          print
            "^Now under the influence of the burning mandrake, Brother Wilfred
            starts to snore.^";
          #IfDef HAS_QUOTES; QuoteBoxSimple(quote_sleep); #EndIf;
        3:
          if (player in Scriptorium && BrWilfred hasnt awake)
            print_ret (string) MSG_WILFRED_ASLEEP;
        5:
          remove MandrakeRoot;
          if (player notin Scriptorium) return;
            print "^The mandrake root has burned, and the air starts to clear.";
          if (BrWilfred hasnt awake)
            print " Wilfred is still deep in sleep, and will be for a while.";
          new_line;
        16:
          if (player in Library)
            "^You can hear stirring from the Scriptorium, suggesting Wilfred is
            starting to waken.";

          if (player in Scriptorium)
              "^Brother Wilfred starts to stir. He may awaken soon.";
        18:
          if (player in Scriptorium)
            print "^Brother Wilfred now is groggily awake.^";
          self.scene_stop();
      }
    ],
  has ;


Scene SceneLibraryCat "SceneCatnap"                           ! >SceneLibraryCat
  with
    name 'catnap',
    scene_start [;
      self.Scene::scene_start();
      #IfDef DEBUG;
        if (location ~= Scriptorium) PlayerTo(Scriptorium);
        move Pax to player;
      #EndIf;
      f_can_complex_wait = true;
      give BrWilfred transparent;
    ],
    scene_stop [;
      self.Scene::scene_stop();
      give BrWilfred awake ~transparent;
      BrWilfred.went_home();
      remove Pax;
      BrWilfred.yawn_check = 0;  ! dont yawn for a few turns
    ],
    react_before [ ;
      if (action ~= ##Examine or ##Listen && Pax == noun or second)
        if (BrWilfred hasnt awake) {
          print
            (The) Pax, " is startled by this, hops up and flees the room, waking
            Brother Wilfred with a start.^";
          self.scene_stop();
          rtrue;
        }
      Shout:
        "You dare not---it would awaken Brother Wilfred.";
      WakeOther:
        if (BrWilfred hasnt awake) {
          self.scene_stop();
          print
            "You shake Brother Wilfred, causing ", (the) Pax, " to flee from his
            lap and out of the room. ";
          print_ret (string) MSG_AWAKE_WILFRED_LIB;
        }
    ],
    daemon [;
      self.time_left++;
      switch (self.time_left) {
        1:
          move Pax to BrWilfred;
          if (player notin Scriptorium) return;
          BrWilfred.yawn_check = 0;
          "^A tender smile comes to Brother Wilfred's lined face. ~Ah~, he
          murmurs to ", (the) Pax, ", ~come to check on an old man?~ ",
          (The) Pax, " leaps onto his lap and settles there. His hand moves to
          stroke her, and his eyes grow heavier almost at once.";
        2:
          give BrWilfred ~awake;
          if (player notin Scriptorium) return;
          print
            "^As ", (the) Pax, " rests in his lap,
            Brother Wilfred begins to snore.^";
          #IfDef HAS_QUOTES; QuoteBoxSimple(quote_sleep); #EndIf;
        3:
          if (player in Scriptorium && BrWilfred hasnt awake)
              print_ret (string) MSG_WILFRED_ASLEEP;
        16:
          remove Pax;
          if (player in Library)
            "^You can hear noises from the Scriptorium, suggesting Brother
            Wilfred is starting to waken.";
          if (player in Scriptorium)
             "^", (The) Pax, " suddenly hops off of Brother Wilfred's lap and
             runs out to the Cloister, causing him to start to stir.";
        18:
          give BrWilfred awake;
          if (player in Scriptorium)
            print "^Brother Wilfred seems groggily awake now.^";
          self.scene_stop();
      }
    ],
  has ;


Scene SceneCrypt "SceneCrypt"                                      ! >SceneCrypt
  with
    name 'crypt',
    scene_stop [;
      self.Scene::scene_stop();
      give CryptBell ~general;
      give CryptGate locked ~open;
      if (g_current_service && g_current_service has general) {
        MovePerson(BrCuthbert, Stalls);
      }
    ],
    check [ ;
      ! check and kill off player
      if (BrCuthbert in Sanctuary && location == Sanctuary)
        print
          "^Brother Cuthbert looks at you with suspicion, given that you're just
          outside the crypt gate with no one else here. ~Brother Novice? Were
          you just in the crypt?~";
      else if (BrCuthbert in location
          && location == CryptVestry or Crypt or CryptStairs
          && TombEzra hasnt general)
        print
          "^Brother Cuthbert stops short. ~Brother Novice? What brings you to
          the crypt?~";
      else if (BrCuthbert in Crypt && FitzAlanPanel has open)
        print
          "^~The panel is open? Someone must have been robbing that old family
          crypt?~";
      else if (real_location == FitzAlanCrypt) rfalse;
      else if (BrCuthbert in Crypt or CryptVestry &&
            real_location == FitzAlanCrypt or Crypt or CryptVestry
            or CryptStairs && IsCarryingLit())
        print
          "^~Who's there?~ Brother Cuthbert calls out, spotting your light.
          ~Brother Novice? You shouldn't be down here alone.~";
      else rfalse;
      print
        "^^When this is reported to Brother Oswald, you are summoned before him.
        ~Why would you be wandering the crypt?~ he asks unkindly.";
      KillOff(7);
      rtrue;
  ],
  noises [ ;
    if (real_location ~= FitzAlanCrypt or Crypt or CryptVestry
        or CryptStairs or Sanctuary or Quire or Sacristy or LadyChapel)
        rfalse;  ! far away, can't hear
    if (action ~= ##Listen) new_line;
    if (real_location == FitzAlanCrypt) {
      if (FitzAlanPanel has open) print "Through the opening,";
      else print "Behind the panel,";
    }
    else if (real_location == parent(BrCuthbert)) print "Very close,";
    else if (real_location ==
            CryptStairs or Sanctuary or Quire or Sacristy or LadyChapel)
      print "Faintly,";
    else if (BrCuthbert in CryptStairs or Nave or Sanctuary)
      print "Above,";
    else if (BrCuthbert in Crypt) print "To the north,";
    else if (BrCuthbert in CryptVestry) print "To the south,";
    else print "*** noises: REPORT BUG";
    print " you hear ";
    rtrue;
  ],
  react_before [;
    Follow:
        "You dare not follow anyone right now.";
    WaveTo:
      if (BrCuthbert in location)
        "You dare not do this lest you be discovered.";
    Listen:
      if (self has on) {
        if (self.time_left >= 15) rfalse;   ! normal listen
        if (self.time_left == 3 or 4 or 7)
          " You hear movement and faint wheezing.";
        ! the daemon will make sound, so make that the response
        rtrue;
      }
    Shout:
      "You dare not draw attention to yourself like this.";
  ],
  react_after [;
    Go:
      if (location == Sanctuary && self has on) {
        give self ~on;
        print "You slip through the open gate.^";
      }
  ],
  daemon [ ;
    ! print "SCENE ", self.time_left, "^";
    self.time_left++;
    give self on;

    ! check for discovery (may also do again after moving cuthbert below)
    if (self.check()) return;

    if (self has on && location == Sacristy or LadyChapel or Quire
          && ~~task_done->TASK_ESCAPE_CRYPT) {
      TaskDone(TASK_ESCAPE_CRYPT);
      give self ~on;
      print "^You escaped the Crypt without being discovered.^";
    }

    switch (self.time_left) {
      1:
        BrCuthbert.attending = false;
      2:
        move BrCuthbert to CryptStairs;
        give CryptGate open;
        if (self.check()) return;
        if (action ~= ##Listen) new_line;
        "You can hear a key turning in the gate above. If you get caught here,
        you'll be in serious trouble.";
      3:
        if (self.check()) return;
        if (action ~= ##Listen) new_line;
        "You can hear footsteps coming down the crypt stairs.";
      4:
        give Crypt light;
        scope_modified = true;
        if (self.check()) return;
        if (real_location == Crypt or CryptVestry)
          "^The footsteps are closer, and you can see some light coming from the
          stairs.";
        "^The footsteps sound closer.";
      5:
        MovePerson(BrCuthbert, d_to, true);
        give CryptVestry light;
        if (self.check()) return;
        if (real_location == Crypt or CryptVestry)
          "^Someone has entered the crypt bearing a light.";
        "^You can hear someone in the crypt.";
      6:
        if (self.noises()) {
          "~Is someone down here?~ You recognise the voice as Brother
          Cuthbert's.";
        }
      7:
        if (self.noises())
          "~Helloooo?~";
      8:
        MovePerson(BrCuthbert, s_to, true);
        if (self.check()) return;
        if (real_location == Crypt) {
          print
            "^The light moves to the south and you sense Brother Cuthbert is now
            searching ";
          if (CryptVestry has visited) print "the Crypt Vestry";
          else print "the room south of the Crypt";
          ".";
        }
        if (self.noises())
          "footsteps going south, away from the crypt stairs.";
      9:
        if (self.noises()) "~Is someone in the Vestry?~";
      10:
        if (self.noises()) "~Helloooo?~";
      11:
        if (self.noises()) "rustling noises.";
      12:
        if (self.noises())
          "~Must have been a draft from the church above.~ (You hear him
          muttering a brief prayer.)";
      13:
        MovePerson(BrCuthbert, n_to, true);
        if (self.check()) return;
        if (real_location == Crypt) {
          if (action ~= ##Listen) new_line;
          "The light becomes stronger here and you hear footsteps walking back
          to the stairs.";
        }
        if (self.noises()) "the footsteps now walking back to the stairs.";
      14:
        give CryptVestry ~light;
        give Crypt ~light;
        scope_modified = true;
        MovePerson(BrCuthbert, u_to, true);
        if (self.check()) return;
        if (real_location == Crypt) {
          if (action ~= ##Listen) new_line;
          "The light dims as you hear footsteps on the stairs.";
        }
      15:
        give CryptBell ~general;
        give CryptGate locked ~open;
        MovePerson(BrCuthbert, Sanctuary);
        if (location == Sanctuary)
          print
            "^You see Brother Cuthbert at the gate and see him shut the gate.^";
        if (self.check()) return;
        if (self.noises()) "the gate being shut.";
      16:
        MovePerson(BrCuthbert, w_to);
        if (real_location == Crypt or FitzAlanCrypt or CryptVestry)
          "^You managed to avoid detection, but you're still stuck here. Now how
          will you get out?";
      17:
        if (g_current_service && g_current_service has general) {
          self.scene_stop();
          rtrue;
        }
        MovePerson(BrCuthbert, w_to);
      18:
        MovePerson(BrCuthbert, u_to);
      19:
        MovePerson(BrCuthbert, u_to);
        self.scene_stop();
    }
  ],
  has ;


! general = active (adds to scope, is equal to daemon-active)
! visited = has already happened
! on = service is underway (ie, PC should be sat and singing)

Scene SceneGoHome "SceneGoHome"                                   ! >SceneGoHome
  with
    name 'go_home',
    scene_start [ i ;
      self.Scene::scene_start();
      for (i = 1 : i < ALL_MONK_NUM : i++)   ! skip aelred
        (all_monks-->i).walk_index = 0;
      f_can_complex_wait = true;
    ],
      scene_stop [ i m ;
        self.Scene::scene_stop();
        i = i;
        m = m;
#IfDef DEBUG;
        for (i = 1 : i < ALL_MONK_NUM : i++) {  ! skip aelred
          m = all_monks-->i;
          move m to m.home;
        }
#EndIf;
      ],
    daemon [ _m num_moved i  ;
      self.time_left++;

      mm_needs_new_line = false;

      for (i = 1 : i < ALL_MONK_NUM : i++) {   ! skip aelred
        _m = all_monks-->i;
        if (_m.attending)
          ! num_moved = num_moved + MoveAMonk(walk_home, _m, waittime_waiting);
          num_moved = num_moved + MoveAMonk(walk_home, _m);
      }

      if (mm_needs_new_line) {
        new_line;
        f_movement_here = true;
      }

      if (num_moved == 0) {
        self.scene_stop();
      }
    ],
  has ;


!===============================================================================
!====================================================================== Services


Class SceneService                                               ! >SceneService
  class Scene,
  with
    ! Remigio and obviously Aelred don't attend most offices
    req_monks BrAnselm BrCuthbert BrHugh BrMartin BrOswald BrWilfred BrBenedict,
    time_left 0,
    number 0,          ! hour of this service (0 for non-aut-start first)
    has_sung false,    ! has player sung during the actual service?
    ! service_round 0,  ! what "round" of the active-singing is this?
    service_length 50, ! how many turns do they get?
    ! actual_start_time 0,
    aldwin_joining false,   ! is aldwin joining in?
    aldwin_round 0,
    req_monks_actual 0,
    walk_path_prop walk_office,
      ! if so, he has to do the right things
      ! he'll be auto-joined for the first one (Lauds), but not for the others

    scene_start [ i _monk ;
      ! start the daemon, set to general (active), simplify quire description.
      ! if this isn't the first service (the bell happens just pre-game),
      ! note that the hear the bell.
      self.Scene::scene_start();
      #IfDef DEBUG; the_time = self.time_start; #EndIf;

      for (i = 0 : i < ALL_MONK_NUM : i++) {
        _monk = all_monks-->i;
        _monk.attending = false;
        _monk.walk_index = 0;
      }

      ! Mark & count monks that will actually be attending
      for (i = 0: i < self.#req_monks / 2: i++) {
        _monk = self.&req_monks-->i;
        if (
          (_monk == BrWilfred &&
            (SceneLibraryCat has active || SceneLibraryMandrake has active)
          ) ||
          (_monk == BrCuthbert && BrCuthbert notin BrCuthbert.home) ) {
            self.&req_monks-->i = 0;
          } else {
            self.req_monks_actual++;
            _monk.attending = true;
            _monk.left_home();
          }
      }

      g_current_service = self;
      g_next_service = nothing;
      f_can_complex_wait = true;  ! will catch later and block during "on"

      ! Ring bell
      if (self.number) {
        print "^~";

        style bold;
        for (i = 1: i <= self.number : i++) {
          print "RING!";
          if (i ~= self.number) print " ";
        }
        style roman;

        print
          "~ You hear the bell ring ", (LanguageNumber) self.number,
          " times to call the brothers to ", (the) self, ".";
      }
      if (self.aldwin_joining == 0)
        print
          " Prior Oswald excused you from offices today, but you know the choir
          monks will be in the Quire for the next forty-five minutes or so.";
      new_line;

      f_offered_shout = false;
    ],

    scene_stop [ i ;
      self.Scene::scene_stop();
      g_current_service = 0;
      ! Only say this if Aldwin in the quire
      if (location == Quire) {
        StoryPause();
        print "^The office ends.^";
      }

      if (self.number > 0) {
        ! normal service: they wander home
        SceneGoHome.scene_start();
      } else {
        ! first service: they jump home, since aldwin hangs out in quire
        for (i = 1 : i < ALL_MONK_NUM : i++) {  ! skip aelred
          move all_monks-->i to (all_monks-->i).home;
          (all_monks-->i).went_home();
        }
        remove BrAelred;
      }

      g_current_service = 0;
      g_next_service = self.next_service;
      ! but don't change the "moves", this wasn't a player choice
      the_time = self.time_start + self.service_length;
    ],

    react_before [ t ; ! dir ;
      if (action == ##Listen && self has on &&
          location ==
                Crypt or CryptStairs or LadyChapel or StJudeChapel or CloisterN
                or FitzAlanChantry or NightStairs or Nave or Sanctuary
      ) rtrue;

      ! if aldwin isn't joining this service, he skips the consequences
      if (self.aldwin_joining == false && location ~= Quire) rfalse;

      WaveTo:
        if (self has on)
          "You dare not wave during the service.";
      Sing:
        if (location ~= Quire) rfalse;
        if (player notin Stalls)
          "You should sing from the stalls. Seat yourself.";
        if (self hasnt on)
          "You open your mouth to begin singing, but realise the service hasn't
          started yet. You should follow Brother Anselm's lead as the cantor.";
        if (self.has_sung) {
          ! Reset this so it doesn't tell us "we continue to sing", which will
          ! duplicate this msg
          self.has_sung = 1;
          "You continue singing.

          ^^[You can continue interacting during the service; as a reminder, if
          you'd like to skip to the end, just WAIT.]";
        }
        if (self.number == 0) {
          #IfDef HAS_QUOTES; QuoteBoxSimple(quote_song); #EndIf;
          TaskDone(TASK_COMPLETED_OFFICE);
        }
        self.has_sung = 1;
        "You join the others in song.
        ^^[You'll automatically continue singing throughout the office. You may
        perform other allowed actions. When you'd like to skip to the end of the
        service, just WAIT.]";
      Shout:
        if (f_enough_evidence) {
          if (self hasnt on)
            "Wait until all the Brothers are here.";
          print
            "You shout loudly. Every face turns to you---shocked, confused, some
            afraid.

            ^^Slowly, you begin to speak.";
          PresentEvidence();
          print
            "^^Brother Hugh's face goes very still.

            ^^~Brother Aldwin,~ says Prior Oswald carefully, ~what are you
            saying?~

            ^^~I am saying,~ you answer, ~that Brother Aelred did not die of a
            weak heart.~ You summon your courage. ~He was murdered by Brother
            Hugh.~^";
          Ending(DEAD_JUSTICE);
          rtrue;
        }
        "You dare not interrupt the office.";

      Go:
        if (self has on) {
          if (player in Stalls) "Surely, you wouldn't leave your stall now.";
          if (location == Quire)
            "Surely, you wouldn't leave the office at this point.";
        }
        ! Service hasn't started, But Aldwin required to stay
        if (self.aldwin_joining && location == Quire)
          "Knowing the service will be starting, you decide to stay where you
          are.";
        g_previous_location = location;

      Listen:
        if (self has on)
          "You hear the brothers singing.";

      Exit:
        if (noun == Stalls && (self.number == 1 || self has on))
        "Surely, you wouldn't rise from the stalls during office.";

      Ask, Tell:
        if (self.number == 0) {
          ! During first office, no one will talk
          ! This is important, bc their responses will assume Aelred is dead
          ! Aelred will, but not during actual service
          if (self has on || noun ~= BrAelred)
            print_ret (string) MSG_ABSOLUTE_SILENCE;
        } else {
          if (self has on)
            print_ret (string) MSG_ABSOLUTE_SILENCE;
        }

      Show, Give, Jump, Hide, Attack, Burn, Cut, Consult, ThrowAt, Disrobe,
      Kiss, Drink, Eat, Climb, Mild, Strong, Touch, Take, Wave, WaveHands,
      WakeOther, Confess, Dig, Knock, Lock, Unlock, Lower, Prune, Pull,
      Rub, LieOn, LieOnAny:
        if (location == Quire)
          "You wouldn't dare do such a thing during a Divine Office.";

      Pray:
        if (self.has_sung) "Your song is your prayer.";
        "Your song will be your prayer.";

      Enter, Sit, SitAny:
        if (parent(player) == Stalls)
          "You are already seated in the stalls, and there you must remain
          during the service.";

      Wait:
        if (self.has_sung) {
          if (~~f_check_wait_during_service) {
            f_check_wait_during_service = true;
            print
              "Using WAIT during a service skips to the end of the service.

              ^^Is this what you want (y/n)? ";
            if (~~YesOrNo()) {
              new_line;
              rfalse;
            }
            new_line;
          }
          t = ((self.time_start + self.service_length) - the_time) / 5 * 5;
          ! t = ((self.service_length - self.service_round - 1) / 5) * 5;
          ! self.service_round = 100;  ! they're bored, end service
          the_time = self.time_start + self.service_length;
          "(skipping about ", (LanguageNumber) t, " minutes to end of service)";
        }

      WaitHours, WaitMinutes, WaitMoves, WaitUntil:
        if (self has on) "[Instead, to wait for end of service, just WAIT.]";
    ],
    react_after [;
      Go:
        if (self hasnt on && g_previous_location == Quire )
          print "You manage to slip out before ", (the) self, " starts.^";
    ],
    move_to_service [ _m _num_ready i ;
      mm_needs_new_line = false;
      ! Service hasn't started yet; move monks to sitting in quire

      for (i = 0 : i < ALL_MONK_NUM : i++) {
        _m = all_monks-->i;

        if (_m.attending) {
          _num_ready = _num_ready + ~~MoveAMonk(self.walk_path_prop, _m);
        }
      }

      if (mm_needs_new_line) {
        new_line;
        f_movement_here = true;
      }
      if (_num_ready == self.req_monks_actual) {
        ! give self on;  ! all the monks are in the right place now
        rtrue;
      }
      ! Don't check singing until service starts
      rfalse;
    ],

    daemon [  distant ;
      self.time_left++;
      ! don't do anything until everyone has moved
      if (self hasnt on && ~~self.move_to_service()) rfalse;

      ! service is underway

      if (location == Quire && f_enough_evidence && ~~f_offered_shout) {
        f_offered_shout = true;
        f_offer_shout = true;
      }

      distant = (location ==
            Crypt or CryptStairs or LadyChapel or StJudeChapel or CloisterN
            or FitzAlanChantry or NightStairs or Nave or Sanctuary);

      f_singing_mentioned = false;

      if (self hasnt on) {
        ! print "*** SERVICE STARTED AT ", (RealTime) the_time, "^";
        ! self.actual_start_time = the_time;

        if (location == Quire) {
          print "^Brother Anselm lifts his voice---clear, unwavering---and the
          office begins, with the other brothers joining in.^";
        }
        else if (distant) {
          f_singing_mentioned = true;
          print "^In the distance, you can hear your brothers start to sing.^";
        }
      }

      give self on;
      ! if (SceneCrypt has active) SceneCrypt.scene_stop();

      if (self.aldwin_joining && location ~= Quire) {
        print
          "^Brother Oswald finds you, exasperated. ~Why aren't you with the
          others in the Quire? This is no time to dawdle.~

          ^^He brings you down to the Quire and you find a seat.^^";
        PlayerTo(Stalls);
        new_line;
        <<Listen>>;
      }

      if (location == Quire) {
        if (~~self.aldwin_joining) {
          self.aldwin_joining = true;
          if (~~f_enough_evidence) {
            print (bd) "^Office! ";
            print
              "Entering the Quire when a service is underway means you'll be
              obligated to participate in it.^";
          }
        }

        self.aldwin_round++;

        if (player notin Stalls) {
          switch (self.aldwin_round) {
            1, 2:
              print
                "^The brothers look at you, puzzled. Why aren't you seated?^";
            3:
              self.failed_office();
              return;
          }
        }

        if (self.has_sung == false) {
          switch(self.aldwin_round) {
            3, 4:
              print
                "^Brother Anselm looks at you. Why aren't you joining the others
                in song?^";
            5:
              self.failed_office();
              return;
          }
        }
      }

      if (the_time >= self.time_start + self.service_length) {
        if (distant) {
          f_singing_mentioned = true;
          print "^The singing from the Quire stops.^";
        }
        self.scene_stop();
        rtrue;
      }

      if (self.has_sung && self.has_sung++ ~= 1 && ~~waittime_waiting)
          print "^You continue to sing with the others.^";

      if (distant && (~~f_singing_mentioned) && ~~waittime_waiting) {
          if (action ~= ##Listen) new_line;
          print "From a distance, you can hear your brothers singing.^";
      }
    ],

    failed_office [;
      StoryPause();
      print
        "^After the office, Brother Oswald confronts you. ~Where was your mind,
        Brother Novice? Part of your duty is participating in offices.~";
      KillOff(3);
      return;
    ],
  has ~proper concealed;


SceneService SceneMatins "Matins office"                          ! >SceneMatins
  with
    name 'matins',
    number 0,
    time_start 2 * 60,
    next_service SceneLauds,
    aldwin_joining true,
    req_monks
      ! override to add remigio and aelred
      BrAnselm BrCuthbert BrHugh BrMartin BrOswald BrWilfred
      BrAelred BrRemigio BrBenedict,
    walk_path_prop walk_matins,
    scene_start [;
      self.SceneService::scene_start();
      ! Block player from trying WAIT 90 for now
      f_can_complex_wait = false;
    ],
    scene_stop [;
      self.SceneService::scene_stop();
      SceneWandering.scene_start();
      print
        "^Brother Aelred touches your shoulder. ~The hour is early, my son, but
        our herbs call for our care. First, though, I must conclude a
        conversation with another brother. Seek me out in the gardens when you
        are ready. The air is pleasant this morning, is it not?~

        ^^All of the brethren head out, leaving you alone in the Quire.

        ^^You spend several long minutes reflecting on your life now: ritual,
        timing, prayer, silence. It feels both comforting and confining. You're
        not sure which feeling prevails.^^";
      Banner();
    ],
  has ;


SceneService SceneLauds "Lauds office"                           ! >SceneLauds
  with
    name 'lauds',
    number 2,
    time_start 5 * 60,
    next_service ScenePrime,
  has ;


SceneService ScenePrime "Prime office"                           ! >ScenePrime
  with
    name 'prime',
    number 3,
    time_start 7 * 60,
    next_service SceneTerce,
  has ;


SceneService SceneTerce "Terce office"                             ! >SceneTerce
  with
    name 'terce',
    number 4,
    time_start 9 * 60,
    next_service SceneSext,
  has ;


SceneService SceneSext "Sext office"                                ! >SceneSext
  with
    name 'sext',
    number 5,
    time_start 12 * 60,
    next_service SceneNone,
  has ;


SceneService SceneNone "None office"                                ! >SceneNone
  with
    name 'none',
    number 6,
    time_start 15 * 60,
    next_service SceneVespers,
  has ;


SceneService SceneVespers "Vespers office"                       ! >SceneVespers
  with
    name 'vespers',
    number 7,
    time_start 17 * 60,
    next_service SceneCompline,
  has ;


SceneService SceneCompline "Compline office"                    ! >SceneCompline
  with
    name 'compline',
    number 8,
    time_start 19 * 60,
    next_service nothing,
    scene_stop [;
      self.SceneService::scene_stop();
      StoryPause();
      print
        "^With the end of Compline, it is the end of the day for the priory.^";
        if (f_ever_offered_confession) Ending(DEAD_INACTION);
        else Ending(DEAD_UNSOLVED);
    ]
  has ;


!===============================================================================
!===================================================================== Locations

! Give these cheap_scenery items permanent IDs, so can refer to them elsewhere.
Constant CSP_ALL_MONKS 100;
Constant CSP_CEILING 101;
Constant CSP_FLOOR 102;
Constant CSP_TOMBS 103;

! This object is never in-scope; it exists just as a place to put a bunch of
! stuff for cheap_scenery.
!
! Often include one of these first:

! cs_church : while inside the church
! cs_cloister : while on the cloister
!
! Always include one of these second:
!
! cs_outdoor : gardens, garth
! cs_exposed : cloisters, passage, day stairs
! cs_indoor: in a building (which could be the church)
!
! These latter three themselves include:
!
! cs_all : stuff that can be referred to anywhere
!          this powers light examination, x monks, etc

Object Core
  with

    cs_all
      3 'god' 'jesus' 'christ' [;
        "While you feel He is omnipresent, you can't see Him right now.";
      ]
      'devil' 'satan' [;
        "While you constantly fear him, you cannot see him right now.";
      ]
      4 'grue' 'grues' 'demon' 'demons' [;
        "You have heard that Satan takes many forms---but fortunately you cannot
        see any evidence of him now.";
      ]
      'heaven' 'hell' [;
        "You may see this one day, but not now.";
      ]
      1 'air' [;
        Smell:
          <Smell>;
          "^[To smell the area you're in, you can also just SMELL.]";
        default: "The air is insubstantial, and you can do nothing with it.";
      ]
      CSP_ALL_MONKS 3 'monks//p' 'brothers//p' 'brethren//p' [;
        Examine:
          <<Here>>;
        default:
          print_ret (string) MSG_PARSER_NOT_MULTIPLE_VERB;
      ]
      CS_PARSE_NAME [ time w n ;
        if (location hasnt light) return 0;

        w = NextWord();
        if (w == 'light' or 'sky') return 1;
        time = RoughTime();
        if (time == CLOCK_NIGHT) {
          if (w == 'pale') { w = NextWord(); n++; }
          if (w == 'light' or 'moonlight' or 'moon') { n++; }
          return n;
        }
        if (time == CLOCK_MORNING) {
          if (w == 'cool') { w = NextWord(); n++; }
          if (w == 'morning') { w = NextWord(); n++; }
          if (w == 'light') { n++; }
          return n;
        }
        if (time == CLOCK_AFTERNOON) {
          if (w == 'bright') { w = NextWord(); n++; }
          if (w == 'afternoon') { w = NextWord(); n++; }
          if (w == 'light') { n++; }
          return n;
        }
        if (time == CLOCK_EVENING) {
          if (w == 'slanted') { w = NextWord(); n++; }
          if (w == 'afternoon') { w = NextWord(); n++; }
          if (w == 'light') { n++; }
          return n;
        }
      ] [;
        "It's merely the @(DS_LIGHT) that you see.";
      ]
      CS_ADD_LIST Core (cs_all2)
    ,

    cs_all2
      ! Very low-priority and generic: there's stone almost anywhere
      1 'stone' [;
        Examine: "There's nothing remarkable about the stone.";
        LookUnder: "You cannot look under this.";
      ]
      1 'brass' [;
        "[You'll need to refer more specifically to the brass thing you mean.]";
      ]
      3 'channel' 'sea' 'coast' [;
        "You can't see the water from here.";
      ]
    ,

    cs_candles
      'candle' 'candles' [;
        print "You can see no candles here now---";
        if (the_time < 360) print "the light from the full moon";
        else print "the autumn light";
        " provides enough illumination that candles wouldn't be needed.";
      ]
    ,

    cs_church
      1 'church' [;
        Exit: "To leave the church, go out an exit.";
        LookUnder: "You cannot look under the church.";
        default: "The entire building you're in is the church.";
      ]
      'cloister' 'cloisters' [;
        "The Cloister is the covered outdoor walkway south of the church. You
        cannot see it from here.";
      ]
      CS_MAYBE_ADD_LIST
        [; return location ~= Sacristy or NightStairs; ] Core (cs_candles)
    ,

    cs_indoor
      CSP_FLOOR 12 'stone' 'floor' 'ground' [;
        Examine: "You see nothing special about the floor.";
        Touch: "The floor feels solid.";
        LieOn: "This is no respectful place to lie.";
        Enter, Sit: "You sit on the floor for a moment, and then rise up.";
        Kneel: "You kneel on the floor for a minute and then rise up.";
        LookUnder: "You cannot look under the floor.";
        Receive: <<Drop noun>>;
      ]
      81 'north' 'south' 'east' 'west' 'n//' 's//' 'e//' 'w//' 'wall' [;
        Search, Examine: "You see nothing special about that wall.";
        Touch, Push, Pull: "It seems quite solid. Nothing happens.";
        LookUnder: "You cannot look under a wall.";
        Climb: "You cannot climb the wall.";
      ]
      21 'stone' 'wood' 'walls//p' [;
        Search, Examine: "You examine each wall, but see nothing unexpected.";
        LookUnder: "You cannot look under a wall.";
        default: print_ret (string) MSG_PARSER_NOT_MULTIPLE_VERB;
      ]
      CSP_CEILING 'ceiling' 'roof' [;
        Examine, Search:
          "You gaze up at the ceiling, but see nothing unexpected.";
        default: "The ceiling is too far above you to do this.";
      ]
      1 'church' [; "You cannot see the church from here."; ]
      CS_ADD_LIST Core (cs_all)
    ,

    cs_cloister
      1 'church' [;
        "You can only see the church to the north.";
      ]
      'path' 'cloister' [;
        Examine: "You can see the entire Cloister from here.";
        default: "This area is the Cloister---you cannot do this to the area.";
      ]
      CS_THEM 5 'arched' 'openings' 'garth' 'yard' 'arches' [;
        "Through the openings, you can see the Garth, the central yard.";
      ]
      CS_THEM 12 'high' 'church' 'walls' [;
        Examine: "There's nothing special about the church walls.";
        LookUnder: "This is not something you can look under.";
        Climb: "You cannot climb the walls.";
      ]
    ,

    cs_outdoor
      1 'church' [;
        "You can only make out the outline of the church from here.";
      ]
      CSP_FLOOR 4 'grass' 'dirt' 'turf' 'ground' [;
        Examine: "You see nothing special about the ground.";
        Touch: "You touch the ground, but feel nothing unexpected.";
        LieOn: "This is no respectful place to lie.";
        Enter, Sit: "You sit on the ground for a minute and then rise up.";
        Kneel: "You kneel on the ground for a minute and then rise up.";
        Receive: <<Drop noun>>;
        LookUnder: "You cannot look under the ground.";
      ]
      CS_ADD_LIST Core (cs_all)
    ,

    cs_exposed
      CSP_FLOOR 12 'stone' 'floor' 'ground' [;
        Examine: "You see nothing special about the ground.";
        Touch: "The ground feels solid.";
        Sit, Enter:
          "You sit for a minute on the exposed floor and then rise up.";
        LieOn: "This is no respectful place to lie.";
        Kneel: "You kneel for a minute on the exposed floor and then rise up.";
        LookUnder: "You cannot look under the floor.";
        Receive: <<Drop noun>>;
      ]
      81 'north' 'south' 'east' 'west' 'n//' 's//' 'e//' 'w//' 'wall' [;
        Search, Examine: "You see nothing special about it.";
        Touch, Push, Pull: "Nothing happens.";
        LookUnder: "You cannot look under a wall.";
        Climb: "You cannot climb the wall.";
      ]
      21 'stone' 'wood' 'walls//p' [;
        Search, Examine: "You examine each wall, but see nothing unexpected.";
        LookUnder: "You cannot look under a wall.";
        default: print_ret (string) MSG_PARSER_NOT_MULTIPLE_VERB;
      ]
      'ceiling' 'roof' [;
        Examine, Search:
          "You gaze up at the covering, but see nothing unexpected.";
        default: "The ceiling is too far above you to do this.";
      ]
      1 'church' [;
        "You can only make out the outline of the church from here.";
      ]
      CS_ADD_LIST Core (cs_all)

    has scenery ;


! ======================================================== 2.0 CHURCH
! 2.0.1 Entrance
! 2.0.2 Nave
! 2.0.3 Tower
! 2.0.4 Quire
! 2.0.5 Sanctuary
! 2.0.6 Sacristy
! 2.0.7 FitzAlan chantry
! 2.0.8 Lady Chapel
! 2.0.9 St Jude Chapel


! --------------------------------------------------- 2.0.1 Entrance
! Porch, door


Room Passage "The Passage (North)"                                    ! >Passage
  with
    name 'passage',
    description [;
      print
        "A covered walkway that runs along the west edge of the priory. The
        stones underfoot are set carefully to make this a clear path.

        ^^You can go north to the Porch or south to the southern end of the
        Passage. The West Gate, allowing entrance into the Cloister, is here
        and ";
      if (WestGate has open) "open."; "closed.";
    ],
    n_to Porch,
    e_to WestGate,
    s_to PassageSouth,
    in_to WestGate,
    out_to MSG_CANT_LEAVE,
    w_to MSG_CANT_LEAVE,
    toward_slype n_to,
    before [;
      Smell: if (noun == nothing)
        "The air smells of salt wind and turned earth, and the faint herbal
        ghost of the priory gardens.";
    ],
    cheap_scenery
      'roof' 'covering' "Simple wooden beams supporting a slanted roof."
      CS_THEM 1 'stones' "Worn smooth by much travel."
      12 'covered' 'path' 'walkway'
        "It's the sheltered path for the brothers."
      CS_ADD_LIST Core (cs_exposed)
    ,
  has proper ;


Constant UNDERCROFT_DOOR_BLOCKS "The door blocks the way.";

Room PassageSouth "The Passage (South)"                          ! >PassageSouth
  with
    name 'passage',
    description
      "The narrow walkway ends here. This part seems less travelled, with weeds
      growing from between the stones underfoot. To the east, the ground slopes
      down to a wide closed door.",
    n_to Passage,
    e_to UNDERCROFT_DOOR_BLOCKS,
    in_to UNDERCROFT_DOOR_BLOCKS,
    s_to MSG_CANT_LEAVE,
    w_to MSG_CANT_LEAVE,
    out_to MSG_CANT_LEAVE,
    toward_slype n_to,
    before [;
      Smell: if (noun == nothing) <<Smell Passage>>;
    ],
    after [;
      Go:
        if (selected_direction == w_to)
          print
            "You push the door open and head west, emerging at the Passage. The
            door closes behind you.^";
    ],
    cheap_scenery
      CS_ADD_LIST Passage (cheap_scenery)
      CS_THEM 1 'weeds' [;
        Examine: "Just small weeds.";
        Dig, Pull, Prune: "No need to pick these---they'll just grow back.";
      ]
      21 'wide' 'closed' 'door' [;
        Close:
          "It is already closed.";
        Examine:
          "It's a large wooden door. You've seen Brothers Hugh and Remigio roll
          barrels out of the Undercroft through it. You can't open it---in fact,
          there isn't even a handle on this side.";
        Take: "You can't take the door.";
        Unlock: "There's no apparent way to unlock this.";
        Knock: "You rap, but there is no reply.";
        LookUnder:
          "You cannot see below the door.";
        Enter, Turn, Pull, Push, Open:
          "You try to pull it open, but have no success.";
      ]
      CS_ADD_LIST Core (cs_exposed)
    ,
  has proper ;


Room Porch "Porch"                                         ! >Porch
  with
    name  'porch' 'entrance',
    description
      "This covered entrance protects the great door from the winds that come
      across the sea from the east. Villagers used to gather here before
      services, but the number who do so has been declining for years.

      ^^You can go south out to the covered walkway the brothers call ~The
      Passage~, or you can go east into the church.",
    e_to GreatDoor,
    in_to GreatDoor,
    s_to Passage,
    n_to MSG_CANT_LEAVE,
    w_to MSG_CANT_LEAVE,
    out_to Passage,
    toward_slype e_to,
    cheap_scenery
      CS_THEM 1 'villagers' [; "You certainly don't see any here now."; ]
      1 'nave' [; "The Nave is to the east, inside the church."; ]
      13 'covered' 'path' 'passage' 'walkway'
        [; "It's a covered passage leading south."; ]
      3 'church' 'wall' 'walls' [;
        Examine: "The exterior of the church is stone and solidly built.";
        Climb: "You are not athletic enough to scale the building.";
        LookUnder: "You cannot look under the church walls.";
      ]
    ,
  has ;


! PUZZLE: one way to find the founding date is on the door

Object GreatDoor "great door"                                    ! >GreatDoor
  class AdjObject,
  with
    adj_name 'great',
    noun_name 'door' 'carving',
    found_in Porch Nave,
    door_dir (e_to) (w_to),
    when_closed [;
      print "The great door ";
      if (location == Nave) print "out to the west";
      else print "in to the east";
      " is closed.";
    ],
    when_open [;
      print "The great door is open, revealing the ";
      if (location == Porch) "Nave to the east."; "Porch to the west.";
    ],
    description [;
      print
        "A great oaken door. Carved deeply into its face: ";
      if (self has open || location == Nave) {
        print "EGRESSUS FRUCTUM FERT (~Going out bears fruit~)";
      } else {
        TaskDone(TASK_LEARNED_FOUNDING_DATE);
        print
          "^^  NOSTRA DOMINA SPINARUM (~Our Lady of Thorns~)
          ^  FUNDATUM ANNO DOMINI MCLII^^
          Almost two hundred years of wind and rain have worn the letters down";
      }
      print ". The door is " ;
      if (self has open) print "open"; else print "closed";
      ".";
    ],
    react_before [;
      Go:
        if (self hasnt open && (
          (location == Porch && selected_direction == e_to)
          || (location == Nave && selected_direction == w_to)
        )) {
          print "(first opening the great door)^";
          give self open;
        }
    ],
    after [;
      Close:
        print "You close the west door";
        if (location == Porch) print ", revealing the carving on this face";
        ".";
    ],
  has
    static door openable ~open;

! --------------------------------------------------- 2.0.2 Nave
! Nave and rood screen and cross

! PUZZLE: stained glass reveal one of the Gordian's themes for the solar door


Room Nave "Nave"                                                         ! >Nave
  with
    name 'nave',
    description
      "The public space, where villagers stand for Mass weekly. The stone floor
      is worn smooth by centuries of feet. Detailed stained glass admits
      @(DS_LIGHT). The Quire lies to the east, separated by a screen. A doorway
      in the north wall leads up to the Tower Stairs.",
    e_to Quire,
    w_to GreatDoor,
    out_to GreatDoor,
    u_to TowerStairs,
    n_to TowerStairs,
    toward_slype e_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_Nave);
#EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "You can smell the faint sweetness of incense that has soaked into the
          walls over centuries.";
    ],
    cheap_scenery
      1 'quire' [; "The Quire is to the east, behind the screen."; ]
      1 'nave' LookInstead
      3 'doorway' 'tower' 'stairs'
        "The Tower Stairs lead up from here to the Bell Tower."
      'outside' 'porch' [; "The Porch is to the west, beyond the door."; ]
      CS_THEM 4 'stained' 'glass' 'window' 'windows' [;
        Examine:
          "You remember the first time you saw this glass, on the second day of
          your novitiate. Unlike some other things in the priory that show signs
          of decay, these still shine brightly on sunny days. The centre pane,
          the largest, has a golden hammer labelled ~II: LABOR OMNIA VINCIT~
          (~Work Conquers All~), a reminder of the mission of monks.";
        Search:
          "Beyond the search for meaning in monastic work, you find nothing.";
        Attack:
          "You dare not break this, nor could you even reach it.";
        ThrownAt:
          "You dare not break this. It's much too beautiful.";
        default:
          "The windows are well out of your reach.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Object RoodScreen "rood screen"                                  ! >RoodScreen
  class AdjObject,
  with
    adj_name 'wooden' 'candle',
    noun_name 'wood' 'rood' 'screen' 'smoke',
    found_in Nave Quire,
    description
      "A wooden rood screen separates the Nave from the Quire, dividing the
      public space from the sacred. A simple carved cross tops the screen---the
      ~rood~ that gives the screen its name. The wood is dark with candle
      smoke.",
    react_before [;
      Go, Exit, Enter, Jump, Climb:
        if (self has general) {
          give self ~general;
          print "(coming out from hiding behind the screen)^";
        }
    ],
    before [;
      Climb, Enter: "It's far too narrow to climb on.";
      Hide:
        give self general;   ! hidden
        "You hide behind the screen.";
    ],
  has
    transparent  ! so can see cross "contained" in it
    scenery;


Object -> RoodCross "rood cross"                                  ! >RoodCross
  class AdjObject,
  with
    adj_name 'rood' 'carved',
    noun_name 'cross',
    description "Simply carved and without ornamentation.",
    before [;
      LookUnder: "Underneath the cross is the rood screen.";
      Take, Pull, Push, Turn:
        "The cross is too high up to reach---and besides, it's attached to the
        screen.";
    ]
  has
    static;


!---------------------------------------------------- 2.0.3 Tower
! Tower stairs, tower, bell, and views


Room TowerStairs "Tower Stairs"                                   ! >TowerStairs
  with
    name 'tower' 'stairs',
    description
      "A spiral staircase winds up and down from here. The stone steps are
      narrow and treacherously steep. Cool air and @(DS_LIGHT) flows down from
      above.",
    d_to Nave,
    s_to Nave,
    u_to BellTower,
    toward_slype d_to,
    cheap_scenery
      CS_THEM 14 'stone' 'steps' 'stairs' 'spiral' 'staircase' [;
        Examine: "You notice nothing unusual about the stairs.";
        LookUnder: "You cannot look below the stairs.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
      ,
    before [;
      Smell:
        if (noun == nothing) "The air is a bit fresher here.";
    ]
  has ;


Room BellTower "Bell Tower"                                         ! >BellTower
  with
    name 'bell' 'tower',
    description
      "The bell chamber. Wind whistles through the open arches on all four
      sides. Dead leaves have drifted into the corners and along the walls,
      blown in through the open arches.

      ^^The great bell hangs overhead. A rope from it hangs to within your
      reach.

      ^^From here, you have clear views in all four directions---such fine views
      that the priory allows outsiders into this space.",
    d_to TowerStairs,
    toward_slype d_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_belltower);
#EndIf;
    ],
    before [;
      Going:
        if (SceneWandering has general)
          return ShouldNotGoNow(self, BrCuthbert);
      Listen:
        if (noun == nothing) "You can hear the wind.";
      Smell:
        if (noun == nothing) "The air is fresh here.";
      Climb:
        "It's much too perilous to try to climb up or down from here.";
      Jump:
        "Surely, you don't wish to commit the sin of self-murder.";
      Examine:
        switch (selected_direction) {
          n_to:
            "To the north, you can see rough coast and cliffs, dotted with
            small farms.";
          s_to:
            "South of here, you see the Cloister surrounding the Garth, the
            priory's roofs, and the Garden. How you've learned to love that
            garden.";
          w_to:
            "You can see a small path from the west door to the gate for the
            priory and, beyond that, the village in the dale.";
          e_to:
            "East, you can see the Infirmary and its chapel and, beyond that,
            the cliffs and the sea.";
          u_to:
            "The great bell hangs above you, dark against the @(DS_LIGHT).";
          d_to:
            "You see the stone floor of the Bell Tower, and through the
            opening, the stairs descending.";
        }
    ],
    cs_faraway
      'church' 'roof' [;
        Examine: "You can see the roof of the church below.";
        Climb, Enter: "You cannot get to the church roof from here.";
        LookUnder: "You cannot look under the church from here.";
      ]
      'view' 'views' "There are excellent views in all directions."
      8 'village' 'coast' 'path' 'gate' 'sea' 'infirmary' 'chapel' 'dale'
        "You can only just make that out in the distance."
      13 'rough' 'cliffs' 'farms' 'roofs'
        "You can only just make these out in the distance."
      2 'cloister' 'garth'
        "You can see the Cloister and the Garth it surrounds."
      'garden' 'gardens'
        "You can clearly see the Garden and the accompanying smaller
        Restricted Garden, both very familiar to you."
      1 'priory' "This gives you a great view of the entire priory and grounds."
    ,
    cheap_scenery
      CS_THEM 12 'open' 'corners' 'arches'
        [; "These are just scenic terms, and not relevant." ;]
      21 'great' 'bronze' 'bell' [;
        Examine:
          "A bronze bell, green with age. Cast nearly two centuries ago, you
          recall Brother Oswald once telling you it was cast by the priory
          founder, Brother Gordian. It bears the inscription ~I: FIDES~---a
          reminder that our primary task is faith.";
        LookUnder: "One thing below the bell is you.";
        default:
          "The bell is far above you. You can only reach the rope.";
      ]
      CS_THEM 11 'dead' 'leaves' [;
        Examine, Search:
          "The leaves that settled across the floor are less prominent
          immediately around the chest, as though it was moved more recently.";
        Rub, LookUnder, Pull, Push, Turn:
          "As you start to gather the leaves, you notice that the leaves
          settled across the floor are less prominent immediately around the
          chest (as though it was moved more recently?) You realize that
          gathering the leaves is fruitless---there are too many and more will
          blow in with every storm.";
        Take:
          "There would be no point trying to gather the leaves---there are too
          many, and more will blow in with every storm.";
      ]
      CS_ADD_LIST BellTower (cs_faraway)
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Object -> BellRope "bell rope"                                       ! >BellRope
  class AdjObject,
  with
    adj_name 'bell',
    noun_name 'rope' 'cord',
    describe 0,
    description
      "The cord reaches up to the bell, far above. Ringing the bell yourself
      would earn severe punishment. That duty does not belong to novices.",
    time_left,
    time_out [;
      if ((location == BellTower or TowerStairs)
            || (location == Nave && RoodScreen hasnt general)) {
        print
          "^Brother Cuthbert finds you here, his face dark with anger.

          ^^~What madness is this? Ringing the bells without cause? The entire
          village will think we're under attack!~";
        KillOff(3);
        return;
      }
      "^You can hear footsteps in the Nave, going up to the Bell Tower, and then
      returning. It seems very fortunate that you have avoided the wrath of
      Brother Cuthbert.";
    ],
    before [;
      Take:
        "It's tied far above you, so you can't take it.";
      Tie, Pull, Turn:
        if (BrCuthbert in location)
          print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
        StartTimer(self, 4);
        "Grabbing the cord causes the bell to toll, echoing across the priory.
        Instinctively you let go of the cord. You know you shouldn't have done
        that.";
    ],
  has static ;


Object -> BellTowerChest "wooden chest"                        ! >BellTowerChest
  class AdjObject,
  with
    adj_name 'wooden' 'old' 'weathered',
    noun_name 'chest' 'box' 'lid',
    description [;
      print
        "An old wooden chest, about one foot long on each side, weathered by
        years of wind and rain blowing through the open tower. The lid bears an
        engraved inscription: ~VOCA POPULUM AD PRECES~ (~Call the people to
        prayer~)";
      if (self has open)
        PrintContents(". The chest stands open, revealing ", self);
      ".";
    ],
    before [;
      Open:
        if (BrCuthbert in location)
          print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
      Push, Pull, LookUnder, Search:
        if (BrCuthbert in location)
          print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
        if (ScribbledNote hasnt moved) {
          move ScribbledNote to location;
          ! update_moved = true;
          PronounNotice(ScribbledNote);
          "Moving the chest reveals a note that was hidden under it.";
        }
        "Nothing else is found under it.";
      Take:
        "The chest is much too large to carry.";
    ],
  has
    container openable ~open static;


Object -> -> BellTools "bell-repairing tools"                       ! >BellTools
  class AdjObject,
  with
    article "some",
    noun_name 'tools' 'oil' 'wedges' 'items' 'vial',
    description
        "Some maintenance items: a small vial of oil and some wooden wedges. All
        the practical things needed to keep the great bell ringing true.",
    before [;
      Examine: ;
      Take, Remove, Insert:
        "Leave them be---you have no need of bell-repairing tools, and Brother
        Cuthbert will want these left here.";
      Smell: "They smell, naturally, of oil and wood.";
      Search, LookUnder:
        "You find nothing else among the tools.";
      default:
        "Leave the tools be, Brother.";
    ],
  has pluralname;


Object ScribbledNote                                            ! >ScribbledNote
  class AdjObject,
  with
    short_name "note",
    adj_name 'treacherous',
    noun_name 'note' 'paper' 'wax',
    before [;
      Smell:
        "There is the barest scent of perfume.";
      Examine, Open:
        if (ImplicitGrabIfNotHeld(noun)) rtrue;
        ev_note = true;
        self.short_name = "treacherous note";
        give self moved;
        if (self hasnt general)
          print
            "The note is folded and sealed with wax. You tear it open and unfold
            it.^^";
        give self general;
        "It is written in an educated hand on fine paper. It reads: ~The
        manuscript was exquisite---the illumination work exceptional.

        ^^Should other such works become available, I remain most interested.
        Leave word at our usual place.~ It is unsigned.";
    ],
  has
    evidence convo ;


!---------------------------------------------------- 2.0.4 Quire
! Quire, lectern, and stalls


! Object to manage logic of the first-service and other ones
!
! PUZZLE: need to perform first service
! PUZZLE: if wander through area during service, will get sucked into it


Room Quire "Quire"                                                      ! >Quire
  with
    ! name 'quire',
    description [;
      print
        "The Quire is the heart of monastic worship and the centre of the
        church. Two stalls face each other across a narrow gap, where the
        brothers gather to chant the Divine Offices. The high altar rises to the
        east. The Nave lies west, beyond the rood screen. The Night Stairs
        ascend to the Dorter, and a path leads south, out to the Cloister.^";
      HereSub(true);
    ],
    out_to CloisterN,
    s_to CloisterN,
    e_to Sanctuary,
    w_to Nave,
    u_to NightStairs,
    toward_slype s_to,
    before [;
      SitAny: <<Enter Stalls>>;
      Sing:
        "But there's no office going on at the moment.";
      Smell:
        if (noun == nothing)
          "Centuries of incense have worked themselves into the very stone here.
          The smell is deep and resinous, threaded with beeswax. It is a smell
          that seems to belong to God rather than to men.";
    ],
    cheap_scenery
      1 'gap' [;
          Examine:
            "A two yard wide space between the two stalls facing each other.";
            default: "This is just a gap; you cannot do anything to it.";
      ]
      1 'quire' LookInstead
      'high' 'altar' [; "You can only see the altar from here, but you should head east for a
        closer look.";
      ]
      1 'nave' [;
        "The nave is to the west. You can go there for a closer look.";
      ]
      1 'dorter' [;
        "The Dorter is far above, up the stairs.";
      ]
      11 'night' 'stairs' [;
        Examine: "These are the stairs leading to the Dorter.";
        LookUnder: "You cannot look under the stairs.";
      ]
      1 'sanctuary' [;
        "The Sanctuary is the area east of here.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Chair -> Stalls "stalls"                                              ! >Stalls
  class AdjObject,
  with
    article "two",
    noun_name 'stalls' 'stall' 'bench' 'benches',
    description [ num ;
      print
        "You've sat on these for months now during offices. While sacred to you,
        the carpentry is plain";
      num = children(self);
      if (player in self) num--;
      if (num > 0) {
        print ". On them ";
        if (num == 1) print "is"; else print "are";
        PrintContents(" ", self);
      }
      ".";
    ],
    before [;
      Kneel: "You should sit on these instead.";
    ],
    after [;
      Enter:
        if (BrAelred in self)
          "You sit on a stall next to your mentor, the herbalist Brother
          Aelred.";
        "You sit on a stall with a certain sense of familiarity.";
    ],
  has
     pluralname scenery;


!----------------------------------------------------- 2.0.5 Sanctuary
! HighAltar, crypt stairs


Room Sanctuary "Sanctuary"                                  ! >Sanctuary
  with
    description [;
      print
        "A domed ceiling rises above this, the area where Prior Oswald leads
        public Mass. The Quire is to the west and a chapel is to the east. The
        Sacristy is through a doorway to the south. ";
        if (CryptGate hasnt open)
          "A closed gate bars the path descending to the Crypt.";
        "The crypt gate is open.";
    ],
    w_to Quire,
    e_to LadyChapel,
    d_to CryptGate,
    s_to SacristyDoor,
    toward_slype w_to,
    before [;
      Smell:
        if (noun == nothing)
          "There's a faint lingering scent of incense, used during masses.";
      Pray:
        "In this great room, it's easy to feel small. However, praying has
        always filled you with hope, and it does not fail to do so now.";
    ],
    cheap_scenery
      1 'sanctuary' LookInstead
      1 'doorway' [;
        Enter: <<Enter SacristyDoor>>;
        default: "The doorway south leads to the Sacristy.";
      ]
      1 'quire' [; "The Quire is the area west of here."; ]
      1 'chapel' [;
        "From here, you can see an altar and a statue. You can go east to
         explore it.";
      ]
      'domed' 'ceiling'
        "It's lovely---and also far above you."
      1 'lock' [;
        Examine: "The lock is the opening for a key in the crypt gate.";
        Lock: <<Lock CryptGate>>;
        Unlock: <<Unlock CryptGate>>;
      ]
      1 'crypt' [;
        Enter: <<Enter CryptGate>>;
        default:
          "You can't see the crypt from here, only the gated stairs down to
          it.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has;


Altar -> HighAltar                                                  ! >HighAltar
  with
    short_name "high altar",
    article "the",
    adj_name 'high',
    add_to_scope AltarCross,   ! don't want them to be listed on
    description
      "The austerity of the priory is evident in the simplicity of this altar, a
      stone structure supporting a cross.",
    before [;
      Smell: "It smells like dust and faint incense.";
      Take, Push, Pull, Turn: "It's much too heavy for that.";
    ],
  has ~supporter ~enterable ;


Object AltarCross "altar cross"                              ! >AltarCross
  class AdjObject
  with
    article "the",
    adj_name 'simple' 'wooden' 'altar',
    noun_name 'cross',
    description
      "A simple wooden cross---no gold, no jewels---firmly attached to the
      altar.",
    before [;
      Examine, Touch: ;
      Smell: <<Smell HighAltar>>;
      Attack: "Heaven forfend.";
      Push, Turn, Pull, Search, Rub : ;
      LookUnder: "This is firmly attached to the altar.";
      default:
        "Thinking of how outraged Brother Cuthbert would be, you think better
        of this act.";
    ],
  has scenery;


! -------------------------------------------------------------

! PUZZLE: how to get into the crypt?
!  It isn't the key; that's a red herring and player will never get it.
!  It can be entered through the secret FitzAlanCrypt
! PUZZLE: how to leave the crypt?
!  - can pray to st jude for impossible help
!  - can ring the bell, hide, wait for cuthbert to search, then run
!    upstairs when he goes to crypt vestry

Object CryptGate "crypt gate"                                       ! >CryptGate
  class AdjObject,
  with
    adj_name 'crypt',
    noun_name 'gate' 'door',
    description [;
      #ifDef HAS_HINTS; HintReady(Hint_gate); #EndIf;
      print
        "The gate is made of sturdy iron and has a heavy lock built into it";
      if (self has open) print ". It is open"; else print ". It is closed";
      ".";
    ],
    found_in Sanctuary CryptStairs,
    door_dir (d_to) (u_to),
    before [;
      Open, Unlock:
        #ifDef HAS_HINTS; HintReady(Hint_gate); #EndIf;
      Close:
        if (self has open && BrCuthbert in Crypt or CryptStairs or CryptVestry)
          "Surely, you wouldn't want to trap Brother Cuthbert.";
    ],
    after [;
      Close:
        give self locked;
        "As the gate closes, you hear it lock.";
    ]
  has
    scenery door locked lockable ~open openable;


Room CryptStairs "Crypt Stairs"                                   ! >CryptStairs
  with
    name 'crypt' 'stairs',
    description
      "At the midpoint of these stairs, you can sense the damp below. A thin
      veil of @(DS_LIGHT) comes from the area above, but the path down descends
      into darkness.",
    u_to CryptGate,
    d_to Crypt,
    before [;
      Smell: if (noun == nothing) "Musty and damp.";
      Shout: Crypt.crypt_shout(); rtrue;
      Go:
        if (selected_direction == u_to) {
          if (PrayerMat has general && CryptGate hasnt open)
           "The gate is locked. This situation seems desperate.";
        }
      Pray:
        if (PrayerMat has general && CryptGate hasnt open) {
          give CryptGate ~locked;
          give PrayerMat ~general;
          TaskDone(TASK_ESCAPE_CRYPT);
          "As you pray again to St Jude, you hear the soft click of an unseen
          bolt sliding back. Your prayer on the mat has been answered.";
        }
    ],
    after [;
      Going:
        if (location == Sanctuary && IsCarryingLit())
          print
            "^Now that you don't need it, you should extinguish your candle.
            Being caught with it would be a severe violation.^";
    ],
    cheap_scenery
      1 'crypt' [; "You can't see it from here, but it's below."; ]
      CS_THEM 'stairs' 'steps' [;
        Examine, Search: "There is nothing remarkable about the stairs.";
        LookUnder: "You cannot look under the stairs.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


! --------------------------------------------------- 2.0.6 Sacristy


Object SacristyDoor "sacristy door"                              ! >SacristyDoor
  class AdjObject,
  with
    adj_name 'sacristy' 'narrow',
    noun_name 'door' 'doorway',
    description "The Sacristy door is narrow and without any lock.",
    found_in Sanctuary Sacristy,
    door_dir (s_to) (n_to),
    react_before [;
      Go:
        if (SacristyDoor hasnt open && (
          (location == Sanctuary && selected_direction == s_to)
          || (location == Sacristy && selected_direction == n_to)
        )) {
          if (SceneWandering has active) <<Open SacristyDoor>>;
          print "(first opening the door)^";
          give self open;
          give Sacristy light;
        }
      Rub:
        if (noun hasnt moved or animate)
          "You needn't bother. Brother Cuthbert keeps things here spotless.";
    ],
    before [;
      Examine:
        if (location == thedark)
          "Have faith, Brother. You can't see it, but you know it's there.";
      Open:
        if (SceneWandering has active) {
          "You shouldn't be exploring the Sacristy now. Perhaps later, when
          Brother Cuthbert is occupied.";
        }
    ],
    after [;
        Open:
          give Sacristy light;
          print "You open the door";
          if (location == Sacristy)
            print ", revealing the @(DS_LIGHT) from the Sanctuary";
          ".";
        Close:
          give Sacristy ~light;
    ],
  has
    static scenery door openable ~open;

! PUZZLE: can only get the candle if has proven it's needed
! PUZZLE: has to hide candle as its contraband

Room Sacristy "Sacristy"                                             ! >Sacristy
  with
    name 'sacristy',
    description [;
      print
        "A small room where items used during services are kept. Shelves hold
        neatly folded linens, precious chalices, and other miscellaneous vestry
        items. The smell of beeswax and old incense lingers. Brother Cuthbert
        maintains this space with meticulous care";
      if (SacristyDoor has open) {
        print
          ".^^Through the open door, @(DS_LIGHT) spills in from the Sanctuary";
      }
      ".";
    ],
    out_to SacristyDoor,
    n_to SacristyDoor,
    toward_slype n_to,
    before [;
      Smell:
        if (noun) rfalse;
        if (location == thedark)
          "You smell wax and old incense in the darkness.";

        "Dusty and fragrant with wax and wood.";
      Go:
        if (location == thedark)
          "You shouldn't stumble around in the dark. You might damage
          something.";
    ],
    cs_shelves
      CS_THEM 'shelf' 'shelves' [;
        Search, Examine:
          "You find linens, chalices, a pewter platter, and other smaller vestry
          items useful for services.";
        Receive:
          "Brother Cuthbert keeps this very organised. Don't add things to these
          shelves.";
        Empty:
          "You dare not.";
        Take:
          "The shelves are built into the wall.";
        Smell:
          "The scent of beeswax is stronger here.";
      ]
      CS_THEM 12 'folded' 'linen' 'linens' [;
        Examine: "The linens are worn but clean.";
        Search, LookUnder: "You find nothing among the linens.";
        Take: "You dare not. These are precious sacred items.";
        default: "Leave the linens alone.";
      ]
      CS_THEM 'chalice' 'chalices' [;
        Examine: "The chalices are used for sacred purpose during Mass.";
        Take: "You dare not. These are precious and would be missed.";
        default: "Leave the chalices alone.";
      ]
      CS_THEM 12 'smaller' 'vestry' 'items' [;
        Examine, Search, LookUnder:
          if (MyCandle hasnt moved)
            "Among the miscellany: a beeswax candle and a brush.";
          "The only thing you particularly notice now is the brush.";
        default: "You should address these items individually.";
      ]
      1 'brush' [;
        Examine: "A simple brush to clean the linens and chalices.";
        Take: "Brother Cuthbert will need this.";
        default: "Leave the brush alone---Brother Cuthbert will need this.";
      ]
      'pewter' 'platter' [;
        Examine: "The platter is used to hold items during Mass.";
        Take: "Brother Cuthbert would be outraged if you take this.";
        default: "Brother Cuthbert would be outraged if you disturbed this.";
      ]
    ,
    cheap_scenery
      1 'incense' [;
        Examine, Take: "You can smell it faintly, but can't find any here.";
        Smell: "It's a lingering aroma of sage.";
        default: "It's merely a lingering aroma, that's all.";
      ]
      CS_ADD_LIST Sacristy (cs_shelves)
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Candle -> MyCandle "beeswax candle"                                     ! >MyCandle
  with
    name 'wax' 'candle',
    ! noun_name 'beeswax' 'wax' 'candle' 'light',
    description [;
      print
        "It's of good quality, made from beeswax from the priory's own bees";
      if (self has light) print ". It is lit";
      ".";
    ],
    before [;
      Smell: "Waxy and slightly sweet.";
      Taste: "Gingerly, you taste it. Waxy.";
      Take:
        if (location ~= Sacristy) rfalse;
        ! if this returns false, proceed with taking candle
        return MyCandle.dont_need();
    ],
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ]
  has
    concealed ;


! --------------------------------------------------- 2.0.7 FitzAlan Chantry

! PUZZLE: find hidden ladder to FA Crypt
! PUZZLE: how to get out of that area, since ladder is one-way

Room FitzAlanChantry "FitzAlan Chantry"                       ! >FitzAlanChantry
  with
    name 'chantry',
    description
      "The FitzAlan family chantry, endowed long ago for masses. But the
      FitzAlans are gone now---their line ended in the pestilence---and no
      masses are said here anymore. You can return out to the Lady Chapel
      through the south.",
    s_to LadyChapel,
    out_to LadyChapel,
    d_to [;
      if (FitzAlanAltar has open) return FitzAlanCrypt;
    ],
    toward_slype s_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_chantry);
#EndIf;
    ],
    before [;
      Examine:
        if (noun == CheapScenery && cs_match_id == CSP_FLOOR)
          "The scrapes on the floor almost look like the altar had been moved.";
    ],
    cs_opening
      1 'opening' [;
        Examine, Search, LookUnder: <<Examine Ladder>>;
      ]
    ,
    cheap_scenery
      CS_THEM 4 'gouge' 'gouges//p' 'tracks' 'grooves'
        "You're not sure what caused them. Perhaps the altar was moved?"
      2 'fitzalan' 'fitzalans'
        "The FitzAlans died out, and you certainly don't see any here."
      'lady' 'chapel' "The Lady Chapel is the chapel south of here."
      1 'motto' [;
          Examine, Search:
            if (player notin FitzAlanAltar)
              print "It's high above the altar, but you can make it out: ";
            "~LEO VIAM DUCIT~. They certainly thought highly of themselves.";
          LookUnder: "Under the motto is the altar itself.";
          Push, Pull, Turn:
            "This is merely a carving in the wall, and does not move.";
          Take: "This is a carving on the wall; you cannot remove it.";
      ]
      CS_MAYBE_ADD_LIST
        [; return FitzAlanAltar has open; ] FitzAlanChantry (cs_opening)
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


! open = open, can climb down
! moved = ever been opened

Altar -> FitzAlanAltar                                          ! >FitzAlanAltar
  class AdjObject,
  with
    adj_name 'fitzalan' 'stone',
    describe [;
      print "^A stone altar is ";
      if (self has open)
        print
          "swung open from the wall (revealing a ladder leading down into
          darkness)";
      else print "set against a wall";
      PrintContents(". On it ", self, ISARE_BIT);
      ".";
    ],
    description [;
      print "A heavy-looking block of stone";
      if (self has open) {
        print
          " that has been pushed away from the wall, revealing a ladder
          descending into darkness";
      } else {
       print
          " on the floor. Gouges in the floor by the altar testify to its
          weight. Above the altar, carved into the wall, are the FitzAlan arms
          and motto";
        PrintContents(". On the altar ", self, ISARE_BIT);
      }
      ".";
    ],
    before [;
      Take:
        if (FitzAlanLion hasnt moved) rfalse;
        "Even trying, you can't lift it.";
      Search:
        if (self hasnt open)
          "You find nothing hidden about the altar itself, but those gouges in
          the floor are intriguing.";

        "The altar is swung open, revealing a ladder downwards.";
      LookUnder:
        if (self hasnt open)
          "You cannot move the altar to look under it or behind it.";
        <<Examine Ladder>>;
      Push, Turn, Pull:
        if (player in self)
          "You can't move the altar while standing on it.";
        if (self has open) {
          give self ~open;
          give FitzAlanLion ~moved;
          MoveFloatingObjects();
          "You push the altar back against the wall and hear a solid click as it
          settles against the wall.";
        }
        if (FitzAlanLion has moved) {
          print
            "You push against the altar and it swings away from the wall,
            revealing an opening in the floor. ";
          if (self hasnt moved) {
            #IfDef HAS_QUOTES; QuoteBoxSimple(quote_stone); #EndIf;
            TaskDone(TASK_FA_CRYPT);
          }
          give self open;  ! now open
          give self moved; ! ever opened
          MoveFloatingObjects();
          "The opening reveals a ladder descending into darkness.";
        }
        if (self has moved)
          "It seems you can no longer push it.";

        "While it seems that the altar isn't built into the floor, it also
        doesn't budge when you try to move it.";
    ],
    after [;
      Enter:
        print "You climb onto the altar";
        if (FitzAlanLion hasnt moved)
          ". From here you can better see the arms above.";
        ".";
    ],
  has ;


! moved = lion is pushed in now
! general = lion has ever been pushed in

Object -> FitzAlanLion "FitzAlan arms"                           ! >FitzAlanLion
  class AdjObject,
  with
    describe 0,
    adj_name 'fitzalan' 'family' 'brass' 'rampant',
    noun_name 'lion' 'arms',
    description [;
      if (player notin FitzAlanAltar)
        "A lion? It's a bit too far up to see clearly.";
      if (self has moved) "The lion is now flush against the stone.";
      "A finely-detailed brass rampant lion standing out from the stone.";
    ],
    before [;
      if (player notin FitzAlanAltar && action ~= ##Examine)
        "The arms are set high in the wall, well above you.";
      Pull:
        "You can't get a grip on the brass lion to pull on it.";
      Push, Turn:
        if (self has moved) "Nothing new happens.";
        f_found_darkness = true;
        give self moved;
        if (self has general)
          "Again, you push against the lion, and hear the same deep click.";
        give self general;
        "You push against the lion and, surprisingly, it moves inward slightly.
        A deep click is heard in the wall.";
      Touch:
        "The arms are smooth to the touch and, curiously, the lion feels like it
        could move.";
      LookUnder: "Underneath the arms is the motto of the FitzAlans.";
    ],
  has
    ~moved static pluralname concealed;


!---------------------------------------------------- 2.0.8 Lady Chapel
! Chapel and statue

Room LadyChapel "Lady Chapel"                                      ! >LadyChapel
  with
    name 'sanctuary',
    description
      "The largest of the three chapels, dedicated to the Blessed Virgin. This
      chapel sees more use than the others: the brothers pray here for the
      priory's patroness, Our Lady of Thorns. To the west is the Sanctuary.
      Small doorways lead north and south to smaller chapels.

      ^^A statue of Mary stands in a niche and a stone altar is next to her.",
    w_to Sanctuary,
    n_to FitzAlanChantry,
    s_to StJudeChapel,
    toward_slype w_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_Mary);
#EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "It smells faintly of the incense that is sometimes burned here.";
      Going:
        if (SceneWandering has general)
          return ShouldNotGoNow(self, BrBenedict);
    ],
    cheap_scenery
      CS_THEM 4 'chapel' 'chapels' 'doorways' 'doorway' [;
        Examine:
          "You're in one chapel, and there are smaller ones to the north and
          south.";
        Enter:
          meta = 1;
          "[There are two doorways; to enter one, GO NORTH or GO SOUTH.]";
      ]
      1 'niche' "It's only a spot for the statue, with nothing else in it."
      'lady' 'chapel' "The ~Lady~ here refers to the Blessed Virgin."
      11 'carved' 'face'
        "While beautiful, you notice nothing unusual in the face."
      CS_THEM 11 'stone' 'hands'
        "The hands are merely a well-carved feature of the statue."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Statue -> MaryStatue "statue of Mary"                              ! >MaryStatue
  with
    name 'mary' 'virgin' 'blessed' 'mother' 'base',
    describe 0,
    description
      "A stone statue of the Blessed Virgin Mary. Her hands are open in a
      gesture of welcome and mercy. Her carved face is serene.

      ^^Carved on the base:^
      ^  BEATAE MARIAE MATRIS DEI
      ^  (Blessed Mary, Mother of God)",
    react_before [;
      Pray: "You make the sign of the cross and murmur an Ave Maria.";
    ],
  has
    female;


Altar -> MaryAltar                                                  ! >MaryAltar
  with
    adj_name 'mary',
  has scenery;


! --------------------------------------------------- 2.0.9 St Jude Chapel
! Chapel, mat, statue, altar, rosehips

! PUZZLE: can pray to st jude for later help in crypt
! PUZZLE: identify the rosehips

Room StJudeChapel "St Jude Chapel"                               ! >StJudeChapel
  with
    description
      "A small chapel dedicated to St Jude, patron of desperate causes. The
      stone floor is worn down---many souls have visited here over the
      generations, praying for urgent escape from terrible situations. A
      doorway leads north, out to the Lady Chapel.

      ^^A statue of the saint is in a corner. Near it is a stone altar with a
      prayer mat laid before it.",
    n_to LadyChapel,
    out_to LadyChapel,
    toward_slype n_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(hint_jude);
#EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "If raw desperation had an odour, you'd smell it here.";
      Pray:
        if (player notin PrayerMat) "You murmur a brief prayer to St Jude.";
        if (PrayerMat hasnt moved) {
          give PrayerMat moved;   ! ever got a prayer
          give PrayerMat general;
          "You feel a powerful sense of hope that St Jude will help you in
          desperate situations.";
        }
        "You feel that the Saint has already heard your plea.";
    ],
    cheap_scenery
      1 'staff'
        "The staff, while artistically painted as a curved branch of white
        pine, is merely a detail on the statue."
      CS_THEM 1 'eyes'
          "While evocative, the eyes of the statue are merely paint."
      1 'chapel' [; "This room is the chapel."; ]
      1 'doorway' [;
        Enter: <<Go FAKE_N_OBJ>>;
        Examine: "It leads back to the Lady Chapel.";
        default:
          "This is just an opening in the wall; you cannot do anything to it.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


! general = has a prayer
! moved = ever had a prayer (can't get a second)

Chair -> PrayerMat "prayer mat"                                     ! >PrayerMat
  class AdjObject,
  with
    adj_name 'prayer',
    noun_name 'mat',
    describe 0,
    description
      "A rough flax mat before the altar, worn thin by countless hours of
      kneeling. Someone has been using it recently---very recently.",
    before [;
      Take: "You are deeply certain it belongs here and dare not take it.";
      Search, LookUnder: "Nothing is under it but the floor.";
      Receive: "It feels sacrilegious to put anything on this sacred mat.";
      Kneel: <<Enter self>>;
      Sit:
        "You shouldn't sit or stand on this---those aren't the appropriate
        gestures.";
    ],
    after [;
      Enter: "You kneel on the mat, as many others have done before.";
    ],
  has
    static supporter enterable;


Altar -> JudeAltar                                                  ! >JudeAltar
  with
    describe 0,
    description [;
      print "A simple stone altar";
      if (RoseHips hasnt moved) {
        give RoseHips ~concealed;
        print ". Someone has left an offering of ";
        if (RoseHips has general) print "rosehips";
        else print "small red berries";
        " on it.";
      } else {
        PrintContents(". On it ", self, ISARE_BIT);
      }
      ".";
    ],
  has ;


! The berries are initially known only as "berries", but they become known
! as rosehips after smell/tasting them. They're initially concealed, but are
! revealed after examining the altar (otherwise, they'd get listed in the
! initial room description, and I want people to have to look at the altar
! to notice them).

Object -> -> RoseHips  ! "berries" or "rosehips"                     ! >RoseHips
  with
    short_name "berries",
    invent [;
      print "some offering ", (name) self; rtrue;
    ],
    parse_name [ w wn ;
      while (true) {
        w = NextWord();
        if (w == 'red' or 'offering' or 'berry' or 'berries' or 'seed'
              or 'pods') wn++;
        else if (self has general &&
              w == 'offering' or 'rose' or 'hip' or 'hips' or 'rosehip'
              or 'rosehips' or 'seed' or 'pods') wn++;
        else return wn;
      }
    ],
    description [;
      #IfDef HAS_HINTS; HintReady(Hint_Berries); #EndIf;
      if (self hasnt general)
        print "Small seed pods. You don't know them by sight, though.^^";
      "Someone carefully gathered these as an offering. They're fresh and
      fragrant, picked within the last day or two.";
    ],
    before [;
      Eat:
        "You shouldn't eat an offering left to a saint. If you just want to
        taste them, say so.";
      Taste, Smell:
        if (action == ##Taste)
          print "You nibble at one: a sweet, tangy flavour";
        if (action == ##Smell)
          print "A faint, floral scent, but clearly of a rosehip";
        if (self hasnt general) {
          print ".";
          give self general;
          self.short_name = "rosehips";
          if (ev_rosehips == false) {
            ev_rosehips = true;
            #IfDef HAS_QUOTES; QuoteBoxSimple(quote_rose); #EndIf;
            print_ret (ital) "This action brings back a memory from summer:
            Aelred in the Garden, showing you a rose in full bloom. ~Beautiful
            now, Brother, but its true gift comes later. These petals fall, and
            by autumn the hip swells with seed, tart and rich. We gather them
            after the first frost for winter cordials.~ He'd smiled. ~The rose
            serves us twice: beauty in summer, medicine in autumn.~ He pauses,
            then continues: ~For some, though, they portend painful loss.~";
          }
        }
        ", reminiscent of roses and of loss.";
      Touch:
        print "Firm.";
        if (self hasnt general) print " Perhaps you should check their scent?";
        "";
    ],
  has
    pluralname edible concealed convo ok_carry;


Statue -> JudeStatue "statue of St Jude"                          ! >JudeStatue
  with
    name 'saint' 'st' 'jude',
    description
      "A wooden statue of St Jude, simply carved and painted. The saint holds a
      staff in one hand. His painted eyes seem to gaze down with deep concern
      at those who kneel before him in desperation."
    has scenery convo ;


! ======================================================== 2.1 CLOISTER
! NW N NE W E SW S SE Garth


! ----------------------------------------------------------------- Cloister NW


Cloister CloisterNW "Cloister Northwest"                           ! >CloisterNW
  with
    cloister_detail
      "The high walls of the church rise imposingly to the north, and a curious
      door lies to the west.",
    s_to CloisterW,
    e_to CloisterN,
    w_to PriorDoor,
    in_to PriorDoor,
    toward_slype e_to,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_SolarDoor);
      HintReady(Hint_WhatIsSolar);
#EndIf;
    ],
    cheap_scenery
      11 'brass' 'plate' [;
        Examine: <<Examine PriorDoor>>;
        Push, Pull, Turn, Take: "The plate is firmly attached to the door.";
        LookUnder: "You cannot look under the plate.";
      ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


DoorButton -> CompassButton "compass button"                   ! >CompassButton
  with
    name 'compass' 'ratio',
    simple_name "a compass, labelled ~RATIO~";

DoorButton -> HammerButton "hammer button"                      ! >HammerButton
  with
    name 'hammer' 'labor',
    simple_name "a hammer, labelled ~LABOR~";

DoorButton -> ScrollButton "scroll button"                       ! >ScrollButton
  with
    name 'scroll' 'sapientia',
    simple_name "an unfurled scroll, labelled ~SAPIENTIA~";

DoorButton -> CrossButton "cross button"                          ! >CrossButton
  with
    name 'cross' 'fides',
    simple_name "a cross, labelled ~FIDES~";

DoorButton -> KeyButton "key button"                                ! >KeyButton
  with
    name 'key' 'custodia',
    simple_name "a key, labelled ~CUSTODIA~";

DoorButton -> LampButton "lamp button"                             ! >LampButton
  with
    name 'lamp' 'lux',
    simple_name "a lamp, labelled ~LUX~";

DoorButton -> WheatButton "wheat button"                          ! >WheatButton
  with
    name 'wheat' 'providentia',
    simple_name "a sheaf of wheat, labelled ~PROVIDENTIA~";


Cloister CloisterN "Cloister North"                                 ! >CloisterN
  with
    cloister_detail
      "The wall of the Nave rises imposingly to the north. A passageway into it
      leads to the Quire. You can also go west to the northwest corner, east to
      the northeastern corner, or south into the Garth.",
    in_to Quire,
    w_to CloisterNW,
    s_to Garth,
    n_to Quire,
    e_to CloisterNE,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_cloister);
#EndIf;
    ],
    toward_slype e_to,
    cheap_scenery
      1 'passageway' [;
          Examine: "It's the entrance to the Quire in the church.";
          Enter: <<Go FAKE_N_OBJ>>;
          LookUnder: "You cannot look under the passageway.";
      ]
      1 'nave' [; "You can only see the outside of the building."; ]
      1 'quire' [; "The Quire is the church room to the north."; ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Cloister CloisterNE "Cloister Northeast"                           ! >CloisterNE
  with
    cloister_detail
      "The Chapter House is in to the east, and the Day Stairs to the upper floor
      head upward from here. You can also go west to the northern end of the
      Cloister or south to the eastern end.",
    e_to ChapterHouse,
    in_to ChapterHouse,
    w_to CloisterN,
    u_to DayStairs,
    s_to CloisterE,
    toward_slype (s_to),
    cheap_scenery
      'chapter' 'house' [; "The Chapter House is the building to the east."; ]
      11 'day' 'stairs' "The Day Stairs are a stone staircase leading upward."
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Cloister CloisterW "Cloister West"                                  ! >CloisterW
  with
    cloister_detail
      "The Locutory lies in to the west. You can also go north to the
      northwestern corner of the Cloister, south to the southwestern corner,
      or east into the Garth.",
    w_to Locutory,
    in_to Locutory,
    s_to CloisterSW,
    e_to Garth,
    n_to CloisterNW,
    toward_slype e_to,
    cheap_scenery
      1 'locutory' [; "The Locutory is the building to the west."; ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Cloister CloisterE "Cloister East"                                  ! >CloisterE
  with
    cloister_detail
      "To the east is the entrance to the Scriptorium. You can also go north to
      the northeastern corner, south to the southeastern corner, or west into
      the Garth.",
    n_to CloisterNE,
    e_to Scriptorium,
    in_to Scriptorium,
    w_to Garth,
    s_to CloisterSE,
    toward_slype (s_to),
    cheap_scenery
      1 'scriptorium' [; "The Scriptorium is the building to the east."; ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  ;


Constant MSG_LOCKING_THE_GATE "locking the gate";

Object WestGate "West Gate"                                          ! >WestGate
  class AdjObject,
  with
    adj_name 'west',
    noun_name 'gate' 'door',
    describe 0,
    description [;
      print
        "The West Gate is the gate for the entrance into the Cloister";
      if (location == CloisterSW) {
        print ". The bar is ";
        if (self has locked) print "lowered, ", (string) MSG_LOCKING_THE_GATE;
        else print "raised, un", (string) MSG_LOCKING_THE_GATE;
      }
      print ". The gate is ";
      if (self has open) "open."; "closed.";
    ],
    before [;
      Pull, Push:
        "To operate the gate, use OPEN/CLOSE/LOCK/UNLOCK.";

      Climb:
        "You cannot climb the gate---it is too tall and the top is part of the
        wall around the Cloister.";
      Turn:
        if (self has locked) <<Unlock self>>; <<Lock self>>;

      Unlock:
        if (location ~= CloisterSW) rfalse;
        if (self hasnt locked) "The bar is already raised.";
        give self ~locked;
        "You raise the bar, un", (string) MSG_LOCKING_THE_GATE, ".";

      Open:
        if (self has locked) {
          if (location == CloisterSW) {
            <Unlock self>; new_line;
          } else {
            "You pull, but without success. The bar must be lowered on the other
            side.";
          }
        }

      Lock:
        if (location ~= CloisterSW) "You can't lock the gate from this side.";
        if (self has locked)
          "The bar is already lowered, ", (string) MSG_LOCKING_THE_GATE, ".";
        if (self has open) print "You close the gate and";
        else print "You";
        give self locked ~open;
        " lower the bar, ", (string) MSG_LOCKING_THE_GATE, ".";
    ],
    found_in Passage CloisterSW,
    door_dir (e_to) (w_to),
  has
    static door locked openable ~open;


Cloister CloisterSW "Cloister Southwest"                           ! >CloisterSW
  with
    cloister_detail [;
      print
        "A small alcove, the Lavatorium, is to the south. You can go north to
        the western edge, or east to the southern edge. The West Gate,
        allowing outsiders to enter the Cloister, is to the west and ";
      if (WestGate has open) "open."; "closed.";
    ],
    s_to Lavatorium,
    w_to WestGate,
    n_to CloisterW,
    e_to CloisterS,
    out_to WestGate,
    toward_slype e_to,
    before [;
      Go:
        if (selected_direction == w_to && WestGate hasnt open) {
          if (WestGate has locked)
            print "(first raising the bar and opening the gate)^";
          else
            print "(first opening the gate)^";
          give WestGate ~locked open;
        }
    ],
    cheap_scenery
      1 'lavatorium' [; "The Lavatorium is the alcove south of here."; ]
      1 'lock' [;
        Examine:
          "The lock is a thick wooden bar that can be raised or lowered.";
        Raise, LookUnder: <<Unlock WestGate>>;
        Lower: <<Lock WestGate>>;
        default:
          "To lock or unlock the gate: LOWER BAR or RAISE BAR.";
      ]
      1 'bar' [;
        Examine:
          print "The bar is currently ";
          if (WestGate hasnt locked) print "raised, un";
          else print "lowered, ";
          "locking the gate.";
        Raise, LookUnder:
          <<Unlock WestGate>>;
        Lower:
          <<Lock WestGate>>;
        default:
          "To lock or unlock the gate: LOWER BAR or RAISE BAR.";
      ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Cloister CloisterS "Cloister South"                                 ! >CloisterS
  with
    cloister_detail
      "The Refectory lies in to the south. You can also go west to the
      southwestern corner of the Cloister, east to the southeastern corner,
      or north to the Garth.",
    n_to Garth,
    w_to CloisterSW,
    e_to CloisterSE,
    s_to Refectory,
    in_to Refectory,
    toward_slype e_to,
    cheap_scenery
      1 'refectory' [;
        "The Refectory is the dining hall, and is south of here.";
      ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Cloister CloisterSE "Cloister Southeast"                           ! >CloisterSE
  with
    cloister_detail
      "The long Slype, leading to the Infirmary and the Herbarium, lies to the
      east. You can also go north to the eastern end of the Cloister, and west
      to the southern end.",
    n_to CloisterE,
    e_to Slype,
    w_to CloisterS,
    toward_slype (e_to),
    each_turn [;
      if (InfirmaryChapel hasnt visited) rfalse;

      if (f_gave_hint_about_body_search == false && ~~ev_symptoms) {
        f_gave_hint_about_body_search = true;
        print_ret
          (bd) "^Hint: ", "You may want to do a more thorough examination of
          Brother Aelred's body to see if you can find any symptoms of what
          killed him.";
      }
      if (f_gave_hint_about_key_search == false && Garden has visited
          && GardenGateKey hasnt moved) {
        f_gave_hint_about_key_search = true;
        print_ret
          (bd) "^Hint: ", "You may want to search the body and Herbarium more
          closely to see if there's anything you've missed---you'd dearly like
          to get into the Restricted Garden to explore.";
      }
      if (f_suggested_next_step == false && RestrictedGarden has visited) {
        f_suggested_next_step = true;
        print_ret
          (bd) "^Hint: ", "Now that you've searched both gardens and examined
          the body in the Infirmary Chapel, your next step could be to search
          all the Priory locations looking for evidence.";
      }
    ],
    cheap_scenery
      2 'long' 'slype' [; "The Slype is a covered passageway to the east."; ]
      CS_ADD_LIST Core (cs_cloister)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Room Garth "Garth"                                                      ! >Garth
  with
    name 'garth' 'square',
    description
      "The Garth is the small grass courtyard at the heart of the Cloister.
      The covered Cloister walk surrounds it on all sides, its arches framing
      the sky above with its @(DS_LIGHT).

      ^^In the centre is a sundial and a stone well.",
    n_to CloisterN,
    w_to CloisterW,
    s_to CloisterS,
    e_to CloisterE,
    u_to
      "The Cloister walk is raised only a single step. You're already at ground
      level. Just walk in the direction you want to enter it.",
    in_to "Which direction do you want to go?",
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_garth);
#EndIf;
    ],
    toward_slype e_to,
    before [;
      SitAny:
        "You sit on the grass and try to clear your head. However, given the
        events so far, you cannot bear to spend time doing this. You get back
        up.";
      Listen:
        if (noun == nothing)
          "You can hear only the quiet peace of the Garth.";
      Smell: if (noun == nothing)
        "You can smell the grass and the nearby herbs.";
    ],
    cheap_scenery
      1 'cloister' [; "The Cloister is all around in every direction."; ]
      'grass' 'courtyard' [;
        Examine:
          "Sparse grass and a few stubborn herbs. The Garth was probably
          more carefully tended in better times.";
        Sit:
          <<SitAny>>;
        default: "There is nothing you can do with the grass.";
      ]
      CS_THEM 1 'herbs' [;
        Examine: "Poorly cared for. This wasn't Brother Aelred's domain.";
        LookUnder, Dig, Prune, Pull:
          "You dare not dig up plants outside of your management.";
      ]
      1 'water' [;
        "The water is far below and out of reach.";
      ]
      1 'bucket' [; "Alas, there is no bucket here."; ]
      14 'sun' 'sundial' 'dial' 'clock' 'gnomon' [;
        Examine:
          if (the_time < 300 || the_time > 1260)
            "The sundial isn't casting a discernible shadow without sunlight.";
          g_last_accurate_time = turns;
          "The sundial casts a shadow showing the time as ",
          (SundialTime) the_time, ".";
        Take: "It's much too heavy.";
        Turn: "The gnomon is attached to the sundial. You can't turn it.";
      ]
      CS_ADD_LIST Core (cs_outdoor)
    ,
  has ;


Object -> GarthWell "well"                                          ! >GarthWell
  class AdjObject,
  with
    adj_name 'stone' 'old',
    noun_name 'well',
    description [;
      print
        "An old stone well, its edges worn down by centuries of drawing
        water.^";
      if (self hasnt general) {
        give self general;
        print_ret
          (ital) "^You can recall a story Aelred told about this: ~The summer
          of... thirty-one, I think it was. Perhaps thirty-two. The well ran so
          low you could hear the bucket scrape the bottom, and Brother Oswald,
          then our cellarer, was rationing water like a miser counts farthings.
          We processed around the garth singing the litany, 'Ora pro nobis'.~

          ^^~Nothing happened, of course. Not that day. We went to bed parched
          and unconvinced. But in the morning the level had risen a foot. Prior
          Wilfred wept for joy. Brother Oswald said it was condensation.~";
      }
    ],
    before [;
      LookUnder:
        "You cannot look under the well; it extends deep into the ground.";
      Enter, Climb:
        "The well is deep and dark. You're not that desperate.";
      Search:
        if (Stick in player)
          "You put the stick into the well and fish around, but it seems the
          water is too far for the stick to reach.";
        "It's too dark to see the bottom.";
      Receive:
        if (NarcInRoom())
          "You dare not, since a brother on the Cloister walk would witness this
          act.";
        remove noun;
        print_ret
          (The) noun, " lands with a splash. You hope you didn't need that.";
    ],
  has
    scenery container open;


! ======================================================== 2.2 WEST WING
! 2.2.1 Prior's Solar
! 2.2.2 Locutory
! 2.2.3 Lavatorium

! --------------------------------------------------- 2.2.1 Prior's Solar


Object PriorDoor "prior door"                                       ! >PriorDoor
  class AdjObject,
  with
    adj_name 'prior' 'solar' 'solar^s' 'curious',
    noun_name 'door',
    description [;
      print "A heavy door made of fine cedar";
      if (location == CloisterNW)
        print
          ", upon which a large brass plate is set. There are seven buttons on
          it, each bearing a symbol: a compass, a hammer, a scroll, a cross, a
          key, a lamp, and a sheaf of wheat. Below them, an inscription in
          elegant script:

          ^^  HIS TRIBUS FUNDATA EST DOMUS MEA
            ^       --- GORDIAN, PRIMUS PRIOR

          ^^You read that as ~On these three my house is founded ---
          Gordian, First Prior~";
      print ". The door is currently ";
      if (self hasnt open) "closed."; "open.";
    ],
    door_dir (w_to) (e_to),
    found_in CloisterNW PriorsSolar,
    pressed_count 0,
    pressed 0 0 0,
    check_combo [ obj;
      ! Check if three buttons pressed
      if (self.pressed_count ~= 3) rfalse;

      objectloop (obj ofclass DoorButton)
        give obj ~on;

      self.pressed_count = 0;

      ! Check combination: Cross (FIDES), Hammer (LABOR), Book (SAPIENTIA)
      if (self.&pressed-->0 == CrossButton
          && self.&pressed-->1 == HammerButton
          && self.&pressed-->2 == ScrollButton) {
        give self ~locked;
        TaskDone(TASK_SOLAR_DOOR);
        itobj = PriorDoor;
        "^You hear a satisfying series of clicks from within the door. The lock
        disengages.";
      } else {
        ! Wrong combination - reset all buttons
        "^You hear a dull click from within the door. All the buttons spring
        back out. Perhaps you pressed the wrong combination?";
      }
    ],
    before [;
      Open:
        if (location == PriorsSolar) {
          give self open ~locked;
          "You open the door.";
        }
      Knock:
        if (BrOswald in PriorsSolar && g_current_service == nothing)
          "Prior Oswald opens the door. ~Ah, Brother Novice. I'm busy. We can
          talk tomorrow.~ He closes the door firmly.";
    ],
    after [;
      Open:
        print "You open the door";
        if (BrOswald in PriorsSolar) {
          if (self has general) { ! already tried once
            print
              ". Brother Oswald stands up in the room, visibly angered. ~How
              dare you defy me?~ he bellows.";
            KillOff(7);
            rtrue;
          }
          give self general locked ~open;
          #IfDef HAS_HINTS; HintReady(Hint_PriorGone); #EndIf;
          print
            ". Brother Oswald looks shocked from inside. ~Brother Novice, what
            are you doing, trying to gain entrance to my private quarters?~ He
            closes the door on you and you hear the lock click";
        }
        ".";
      Close:
        give self locked;
        "You close the door and hear clicks from inside the mechanism. The door
        must have locked itself.";
    ]
  has
    scenery door openable ~open locked;


Room PriorsSolar "Prior's Solar"                                  ! >PriorsSolar
  with
    description
      "Prior Oswald's private chamber. A narrow bed stands against one wall. A
      writing desk sits next to it. A chest sits at the foot of the bed. The
      room is austere but private---a privilege of rank in a community that
      otherwise shares everything.

      ^^The only exit is out to the east.",
    e_to PriorDoor,
    out_to PriorDoor,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_InSolar);
#EndIf;
    ],
    before [;
      Sleep:
        "If the prior were to catch you in his bed, you'd be expelled. You
        think better of it.";
    ],
    cheap_scenery
      31 'prior' 'priors' 'prior^s' 'solar' [;
        "'Solar' is the name for this kind of private chamber.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Cot -> BrOswaldCot "Brother Oswald's bed"
  with
    adj_name 'brother' 'oswald' 'oswald^s' 'oswalds' 'prior' 'prior^s' 'priors',
    description
      "A simple bed, better than your straw pallet in the Dorter, but hardly
      luxurious.",
    before [;
      Search: "There is nothing on or below the cot.";
      LookUnder, Push, Pull, Turn: "Under it is nothing but dust.";
      Enter: <<Sleep>>;
    ]
  has ;


Object -> PriorsDesk "desk"                                        ! >PriorsDesk
  class AdjObject,
  with
    adj_name 'writing',
    noun_name 'desk' 'table',
    description [;
      print "A well-crafted desk with a single drawer";
      if (PriorDrawer has open) print " (which is open)";
      PrintContents(". On it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      Receive: <<Insert noun PriorDrawer>>;
      Enter, Climb:
        "You dare not climb on the prior's desk.";
      Open: <<Open PriorDrawer>>;
      Unlock: <<Unlock PriorDrawer>>;
      Close: <<Close PriorDrawer>>;
      Search:
        PrintContents("On it ", self, ISARE_BIT);
        if (PriorDrawer has open) ". The drawer for it is open";
        ".";
    ],
  has
    scenery static supporter;


Object -> -> PriorCross "cross"                                    ! >PriorCross
  class AdjObject,
  with
    adj_name 'small' 'brass' 'wood',
    noun_name 'cross' 'base' 'inscription',
    description
      "A finely detailed cross in dark wood. The brass base bears a small
      inscription: ~CONVERTIMINI~. You recognise this from the prophet Joel, a
      call to repentance and turning to God.",
    before [;
      Take, LookUnder: "The cross seems affixed to the desk.";
      Pull: "Tugging on the cross does nothing.";
      Push: "Pushing down on the cross does nothing.";
      Turn:
        give PriorDrawer open;
        print
          "Turning the cross on its base, you hear a click within. The drawer
          opens";
        if (Chronicle in PriorDrawer) print ", revealing a book";
        ". The cross snaps back to its original place.";
    ],
  has static;


Object -> PriorDrawer "desk drawer"                               ! >PriorDrawer
  class AdjObject,
  with
    describe 0,
    adj_name 'desk',
    noun_name 'drawer',
    description [;
      print "A simple drawer. It is ";
      if (self has open) {
        print "open";
        PrintContents(", revealing ", self);
      }
      else print "closed";
      ".";
    ],
    before [;
      Open:
        #IfDef HAS_HINTS;
          HintReady(Hint_Drawer);
        #EndIf;

        if (self hasnt open)
          "Though you don't see a lock on the drawer, it won't open.";
      Unlock:
        "You don't see any lock on it.";
      Take:
        "You can't remove the drawer from the desk.";
    ],
    after [;
      Close:
        "As you close it, you hear a click inside, locking it again.";
    ],
  has
    static openable container;


! general = read

Object -> -> Chronicle "chronicle"                                  ! >Chronicle
  with
    article "the",
    name 'chronicle' 'book',
    description
      "It is the chronicle, a record of the prior's daily business.",
    before [;
      Insert:
        if (second == PriorsDesk) <<Insert self PriorDrawer>>;
      Examine:
        if (verb_word == 'read') {
          ev_chronicle = true;

          print_ret
            "The chronicle contains the prior's notes on daily affairs. The
            recent entries:^^",

          (bd) "15 June 1346:",
          (ital)
            " Brother Martin reports the grain stores are adequate for winter,
            though we had to purchase an additional barrel of flour from the
            village due to poor harvest. The cost continues to strain our
            resources.^^",

          (bd) "6 July 1346:",
          (ital)
           " Brother Hugh informs me that the sale of our honey and beeswax
           brought less income than anticipated. Several benefactors who once
           supported us have redirected their charity elsewhere. Our revenues
           have declined steadily these past three years.^^",

          (bd) "28 July 1346:",
          (ital)
            " Brother Wilfred has misplaced his latest work---a small psalter
            with illuminations of remarkable quality. He recalls completing the
            opening of Beatus vir with azure and gold, but cannot remember where
            he shelved it. At his age, such lapses are not uncommon---this is
            the second time in this season he has lost a work. This is causing a
            significant loss of income for us.^^",

          (bd) "3 August 1346:",
          (ital)
            " The roof above the Refectory shows signs of damage from the autumn
            storms. Brother Benedict inspected it and says it will require
            material and builders to repair---funds we can ill afford. I have
            written to the Bishop requesting assistance, but hold little hope of reply.";
        }
    ],
    after [;
      Take:
        if (self hasnt moved)
          "You're uncertain if taking the prior's property is the right thing to
          do---but, under the circumstances, you do so.";
    ],
  has evidence convo ;



Chest -> BrOswaldChest "Brother Oswald's chest"                   ! >PriorsChest
  with
    adj_name 'brother' 'wooden' 'oswald' 'oswalds' 'oswald^s',
    before [;
      Turn, Push, Pull, LookUnder:
        "You move it enough to establish that there's nothing under it, and
        return it to its original location.";
    ]
  has ;

! ---------------------------------------------------  2.2.2 Locutory


Room Locutory "Locutory"                                             ! >Locutory
  with
    name 'locutory',
    description
      "A sparse rectangular room. A plain table is in the centre, surrounded by
      two benches. This is the Locutory, where the prior meets with merchants,
      where brothers discuss monastery business, where the silence of the Rule
      may be broken for practical needs.

      ^^The only exit is out the way you came.",
    e_to CloisterW,
    out_to CloisterW,
    on_first_entry [;
      #IfDef HAS_QUOTES; QuoteBoxSimple(quote_locutory); #EndIf;
    ],
    before [;
        Going:
          if (SceneWandering has general)
            return ShouldNotGoNow(self, BrAnselm);
        SitAny: <<Sit LocutoryBenches>>;
    ],
    cheap_scenery
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Object -> LocutoryTable "table"                                 ! >LocutoryTable
  with
    name 'plain' 'table',
    description
      "This is the table where necessary business is conducted.",
    before [;
      Climb, Enter: "You dare not. Anyone on the Cloister could see you.";
    ],
  has
    scenery supporter;


Chair -> LocutoryBenches "benches"                            ! >LocutoryBenches
  with
    adj_name 'wooden',
    noun_name 'bench' 'benches',
    description
      "Simple wooden benches flanking the table.",
  has
    scenery pluralname;


! --------------------------------------------------- 2.2.3 Lavatorium


Room Lavatorium "Lavatorium"                                       ! >Lavatorium
  with
    name 'lavatorium',
    description
      "A small alcove off the Cloister where the brothers wash before entering
      the Refectory. A basin is built into the wall. You can only return the way
      you came.",
    n_to CloisterSW,
    cant_go "You can only go north.",
    toward_slype n_to,
    cheap_scenery
      1 'peg' "It's a simple peg for the towel."
      1 'alcove' [; "This space is the alcove."; ]
    ,
  has ;


Object -> Basin "basin"                                                 ! >Basin
  with
    name 'basin',
    capacity 5,
    initial
      "A large stone basin is built into the south wall.",
    description
      "The basin normally contains water for washing but, perhaps given the
      events today, someone has failed to fill it.",
    before [;
      Take: "The basin is built into the wall.";
      Fill: "You have no water to fill it with.";
      LookUnder:
        "The basin is built into the wall, so you cannot look below it.";
    ],
  has
    scenery container open transparent;


Object -> Towel "towel"                                                 ! >Towel
  with
    name 'threadbare' 'towel',
    initial "A threadbare towel hangs on a peg by the basin.",
    description
      "It's a simple linen towel, well-worn by use.",
    before [;
      Attack, Cut:
        "Destroying communal property is a violation of the Rules.";
      Take:
        "Leave this here. The other brothers will want to use it.";
      Touch:
        "Rough linen and damp.";
      Smell:
        "It smells damp and musty.";
    ],
  has
    ok_carry;


! ============================================= East Wing

!---------------------------------------------------------- Chapter House

Room ChapterHouse "Chapter House"                                ! >ChapterHouse
  with
    description
      "The Chapter House is a modest hall where the brothers gather each morning
      to discuss priory business. A painted panel on the wall depicts the hours
      of the Divine Offices. In one corner stands a wooden statue. The only exit
      is west, out to the Cloister.",
    w_to CloisterNE,
    out_to CloisterNE,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_ChapterHouse);
#EndIf;
    ],
    before [;
      SitAny: <<Sit ChapterBenches>>;
      Smell:
        if (noun) rfalse;
        if (BrWilfred in self)
          "You smell the familiar closeness of many men in a stone room.";
    ],
    cheap_scenery
      1 'scroll'
        "It's a painted part of the statue, and ~III: SAPIENTIA~ is all that is
        on it."
      3 'chapter' 'house' 'hall' [; "This room is the Chapter House."; ]
      1 'corner' [;
        Search, LookUnder, Examine:
          "The statue is the only thing in the corner.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Chair -> ChapterBenches "benches"                              ! >ChapterBenches
  with
    article "two",
    noun_name 'bench' 'benches',
    description [;
      print "The benches are simple and made of wood";
      PrintContents(". On them are ", self);
      ".";
    ],
    initial [;
      print "Two benches are in the centre of the room";
      PrintContents(". On them are ", self);
      ".";
    ],
  has static pluralname;


Object -> ChapterTable "table"                                   ! >ChapterTable
  with
    name 'broad' 'table',
    description "A large wooden table.",
    initial [;
      print "A broad table lies between the benches";
      PrintContents(". On it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      Push, Pull, Turn:
        "It's much too heavy to move.";
      Take:
        "Leave the table be, Brother. This is much too heavy.";
      Climb, Enter:
        "You dare not get on the table---anyone on the Cloister could see you.";
    ],
  has static supporter;


Statue -> GordianStatue "statue"                                ! >GordianStatue
  with
    name 'wooden' 'gordian' 'gordianus',
    description
      "It's a wooden statue, worn and with the paint flaking in places. You know
      it to be Brother Gordian, the founder of the priory. His face is filled
      with reverence and curiosity, and he is depicted holding a scroll reading
      ~III: SAPIENTIA~, reflecting one of his three creeds, wisdom.",
    before [;
      Kiss: "That would only give you a splinter.";
      Order: "The statue doesn't respond, naturally.";
    ],
  has
    scenery ~proper;


Object -> OfficeHours "painted panel"                             ! >OfficeHours
  class AdjObject,
  with
    adj_name 'painted' 'divine',
    noun_name 'office' 'offices' 'panel' 'hours',
    description [;
      print "It shows the offices:^";
      <Offices>;
      "^(Since you know these by heart, you can see this list at any time with
      the command OFFICES).";
    ],
    before [;
      Take: "It's much too large to carry.";
      LookUnder, Search, Turn, Push, Pull:
        "It's panel on the wall and firmly affixed.";
    ],
  has
    scenery;


! --------------------------------------------------------- Scriptorium

Room Scriptorium "Scriptorium"                                    ! >Scriptorium
  with
    name 'scriptorium',
    description [;
      print
        "The Scriptorium---where brothers create the illuminated manuscripts
        that are a primary source of priory income---smells of ink, manuscripts,
        and woodsmoke. High windows admit the @(DS_LIGHT) that the season
        allows, and a modest fire burns in the fireplace, keeping the
        manuscripts dry despite the sea air.

        ^^The large central table is covered with the materials of the
        illuminator's art as well as a sample of their work.

        ^^The Cloister is out to west; the Library is east, through the ";
      if (LibraryDoor has open) print "open"; else print "closed";
      " door.";
    ],
    e_to LibraryDoor,
    w_to CloisterE,
    out_to CloisterE,
    in_to LibraryDoor,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_Scriptorium); #EndIf;
    ],
    each_turn [;
      if (Pax in player && BrWilfred has awake && BrWilfred in self
          && ~~f_wilfred_sees_aldwin_with_pax) {
        f_wilfred_sees_aldwin_with_pax = true;
        "^Brother Wilfred notices ", (the) Pax, " in your arms. ~Hello~, he
        says to her. ~Making new friends, are we?~";
      }

      if (~~f_ever_offered_confession) self.offer_confession();
    ],
    offer_confession [;
      if (BrWilfred in self && BrWilfred has awake && f_enough_evidence
            && f_ever_offered_confession == false) {
        f_offer_confession = true;
        f_ever_offered_confession = true;
      }
    ],
    before [;
      Smell:
        if (noun == nothing)
          "A comfortable mix of ink and burning wood from the fire.";
      Going:
        if (SceneWandering has general)
          return ShouldNotGoNow(self, BrWilfred);
    ],
    after [;
      Go:
        self.offer_confession();
    ],
    cs_here
      CS_THEM 15 'writing' 'implements' 'brushes' 'brush' 'ink' 'inks' [;
        Examine:
          "The table is covered by brushes and inks needed for the work.";
        Search, LookUnder:
          "There is nothing hidden among the implements.";
        Smell:
          "The implements smell of the pigments used in copying.";
        default: "You shouldn't disturb these implements.";
      ]
      1 'library' [;
        Unlock: <<Unlock LibraryDoor>>;
        Enter: <<Go FAKE_E_OBJ>>;
        default: "That is the room to the east.";
      ]
      17 'decorated' 'initial' 'initials' 'pages' 'vellum' 'text' 'gothic'
            'script' [;
        Examine: "Brother Wilfred's work is always masterful.";
        Turn, Search: "Leave the breviary open to where it already is.";
        Smell: ;
        default: "You shouldn't disturb this work.";
      ]
      3 'silver' 'lock' 'plate'
          "It's just the part of the door where a key would fit."
      CS_THEM 1 'materials' [;
        Examine, Search: <<Examine ScriptoriumTable>>;
      ]
    ,
    cheap_scenery
      'high' 'windows'
        [; "Mere openings in the wall, these are high above your head."; ]
      CS_ADD_LIST Scriptorium (cs_here)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has convo ;


Object -> ScriptoriumTable "table"                           ! >ScriptoriumTable
  with
    name 'large' 'table' 'desk',
    description [ ;
      print
        "Large enough for four monks to work here, the table is laden with
        implements for producing illuminated manuscripts. A breviary, presumably
        a current work, is open on the table";
      if (LibraryKey in ScriptoriumTable)
          print ", along with a silver key";
      ".";
    ],
    before [;
      Search:
        PrintContents("On the table ", self, ISARE_BIT);
        ".";
      Receive:
        if (noun ~= LibraryKey)
          "There are the implements and the breviary on the table already. Don't
          clutter it with your stuff.";
      LookUnder: "Just the floor.";
      Climb, Enter:
        "You dare not. This is the workplace of several of your brethren.";
    ],
    after [;
      Receive:
        if (noun == LibraryKey)
          "You place the key on the table, hoping that it's in the same place it
          was before.";
    ]
  has
    scenery supporter;


Object -> -> Breviary "breviary"                                 ! >Breviary
  class AdjObject,
  with
    adj_name 'illuminated',
    noun_name 'breviary' 'manuscript' 'book' 'books' 'work' 'sample' ,
    description
      "Brother Wilfred's current work: an unfinished breviary for the office.
      The Latin text flows in careful Gothic script across vellum pages.
      Several decorated initials have been illuminated with silver leaf and
      vermilion, their intricate patterns revealing the master's eye even as
      the slightly wavering lines betray his trembling hands. Many pages still
      await illumination.",
    before [;
      Examine:
        if (verb_word == 'read')
          "The breviary lies open to Psalm 23. The Latin reads: ~Dominus regit
          me, et nihil mihi deerit; in loco pascuae ibi me collocavit...~ (The
          Lord is my shepherd, I shall not want; He maketh me to lie down in
          green pastures...)";
      Search: "You discover nothing but the text itself.";
      LookUnder: "You lift it gingerly. There is nothing beneath the breviary.";
      Smell: ;
      Take:
        "You wouldn't dare. These illuminated works are one of the main sources
        of the priory's income, and a loss of one would be a disaster.";
      default: "You shouldn't disturb the breviary.";
    ]
  has convo  ;


Fireplace -> ScriptoriumFireplace "fireplace"            ! >ScriptoriumFireplace
  with
    name 'recess',
    description
      "The fireplace is a stone recess in the wall with a fire going.",
    before [;
      Smell:
        if (MandrakeRoot in ScriptoriumFireplace) {
          print
            "Foolishly, you deeply inhale the mandrake yourself, and wake to
            shaking from Brother Oswald.

            ^^~What madness, Brother Novice? What were you thinking?~";
          KillOff(7);
          rtrue;
        }
      Receive, ThrownAt:
        if(ImplicitGrabIfNotHeld(noun)) rtrue;

        if (BrWilfred in Scriptorium && BrWilfred has awake) {
          if (noun == MandrakeRoot) {
            SceneLibraryMandrake.scene_start();
            "You throw ", (the) noun, " into the fireplace.";
          }
          if (noun == rosemary) {
            remove noun;
            "Brother Wilfred smells the burning rosemary. ~Ah, my favorite.~";
          }
        }
    ],
  has
    static container open;

! ----------------------------------------------------------------------------


Object LibraryKey "silver key" BrWilfred                           ! >LibraryKey
  class AdjObject,
  with
    adj_name 'library',
    noun_name 'silver' 'key' 'keys//p',
    description
      "A silver key, tarnished with age. Brother Wilfred guards it jealously:
      it's his responsibility as librarian to control access to the priory's
      precious books.",
    before [;
      Take:
        HintReady(Hint_LibraryKey);
        if (self in ScriptoriumTable && BrWilfred has awake) {
          BrWilfred.yawn_check = 0;
          if (SceneLibraryCat has active || SceneLibraryMandrake has active) {
            "Brother Wilfred's eyes lift as your hand reaches for the key. He's
            still awake enough to place his hand over the key, preventing you
            from taking it---for now.";
          }
          "Brother Wilfred's eyes snap up just as your hand reaches for it.
          ~Ah-ah,~ he says kindly but firmly, stifling a yawn. ~Not without
          the prior's leave, young Brother.~";
        }
        if (self in ScriptoriumTable) {
          if (TryToTakeNoun(self) ~= 1) {
            ! move self to player;
            "Being as quiet as you can be, you take the key from the table.";
          }
          rtrue;
        }
    ],
  has convo ;


Object -> LibraryDoor "library door"                              ! >LibraryDoor
  class AdjObject
  with
    adj_name 'library' 'silver',
    noun_name 'door',
    description [;
      print "A heavy wooden door with a lock plate in silver. It is ";
      if (self has open) print "open"; else print "closed";
      ".";
    ],
    found_in Scriptorium Library,
    door_dir (e_to) (w_to),
    with_key LibraryKey,
    react_before [;
      Go:
        if (self hasnt open && (
          (location == Scriptorium && selected_direction == e_to)
          || (location == Library && selected_direction == w_to)
        )) {
          if (BrWilfred in location && BrWilfred has awake) {
            "You wouldn't dare try to enter the Library with Brother Wilfred
            watching you. Access to the Library is restricted to him.";
          }
          if (self has locked) print_ret (The) self, " is locked.";

          print "(first opening ", (the) self, ")^";
          give self open;
        }
    ],
    before [;
      if (BrWilfred in location && BrWilfred has awake) {
        if (action == ##Open or ##Unlock)
          "You wouldn't dare try to enter the Library with Brother Wilfred
          watching you. Access to the Library is restricted to him.";

      }

      if (location == Library) {
        if (action == ##Lock or ##Unlock)
          "The lock plate on this side of the door doesn't have an opening for
          a key. It appears to be lockable only from the Scriptorium.";
      }
    ],
  has
    scenery door openable ~open lockable locked;


Room Library "Library"                                                ! >Library
  with
    description
      "This is a small private room. There is a bookshelf on one wall and a
      large map of the priory on the other. The only exit is out to the west.",
    name 'library',
    w_to LibraryDoor,
    out_to LibraryDoor,
    on_first_entry [;
      TaskDone(TASK_LIBRARY);
      #IfDef HAS_HINTS; HintReady(Hint_Library); #EndIf;
    ],
    before [;
      Smell: if (noun == nothing)
        "Ah, the smell of dusty books. You remember this well from your
        childhood, the hours reading in the library of Lord Thornbury between
        chores.";
    ],
    cheap_scenery
      3 'silver' 'lock' 'plate'
        "It's just the part of the door where a key would fit."
      CS_THEM 'manuscript' 'manuscripts'
        "There are many, but none seem significant to you."
      CS_THEM 11 'two' 'crypts' [;
        print
          "Two crypts: a larger one, simply labelled ~Crypt~ and another,
          ~FitzAlan Crypt~.^";
        if (FitzAlanCrypt hasnt visited)
          "^Now that you think of it, while you've been in the crypt once for a
          service, you've never even heard of the other one.";
        return true;
      ]
      11 'missing' 'psalter' [;
        Examine, Search:
          if (Chronicle has moved)
            "Alas, you don't see anything that looks like the missing psalter.";
          print_ret (string) MSG_PARSER_NOSUCHTHING;
      ]
      12 'upper' 'dorters' 'floor'
        "One dorter for the choir monks and one for the lay brothers, naturally."
      11 'brass' 'map'
        "Finely etched into brass and signed ~Prior Gordian~. It shows both the
        indoor and outdoor areas, from the two dorters on the upper floor all
        the way down to two crypts below ground."
      CS_ADD_LIST Core (cs_indoor)
    ,
  has
   convo ;


Object -> Bookshelf "bookshelf"                                     ! >Bookshelf
  class AdjObject,
  with
    adj_name 'book',
    noun_name 'shelf' 'bookshelf' 'books' 'items',
    description [;
      print
        "The bookshelf has about fifty items, most of which are manuscripts,
        used for the work in the Scriptorium";
      self.notice_fratrum();
      ".";
    ],
    notice_fratrum [ ;
      if (MonkGuide hasnt moved) {
        itobj = MonkGuide;
        print
          ". One that draws your attention because of its thin size and small
          format is titled ~Registrum Fratrum~";
      }
      PrintContents(". Also on it ", self, ISARE_BIT);
    ],
    before [;
      Search:
        print "There are many items on the bookshelf";
        self.notice_fratrum();
        ".";
      LookUnder:
        "You cannot look under this.";
    ],
  has scenery supporter;


Object -> -> MonkGuide "Registrum Fratrum"                          ! >MonkGuide
  class AdjObject,
  with
    article "the",
    noun_name 'registry' 'register' 'registrum' 'fratrum' 'book',
    description
      "The ~Registrum Fratrum~ (~Register of the Brothers~). A small
      leather-bound registry that Brother Wilfred has been keeping for decades,
      back to when he was prior. It has notes on brothers who have served in the
      priory, even including some historical ones.",
    before [ ;
      Examine:
        if (verb_word == 'read')
          "It's too long to read through, but you can look up particular entries
          by name.";
      Consult:
        if (location == thedark) { PrintMsg(MSG_EXAMINE_DARK); rtrue; }
        if (ImplicitGrabIfNotHeld(noun)) return;
        if (second == nothing)
          "You find no entry for that in ", (the) self, ".";
        TaskDone(TASK_USED_REGISTRUM);
        second.history_text();
        rtrue;
    ],
    after [;
      Take:
        if (self hasnt moved) {
          print
            "You carefully remove the Registrum Fratrum from the shelf.
            Brother Wilfred would be furious if he knew.^";
          if (action ~= input_action) new_line;
          rtrue;
        }
    ],
  has
    concealed ;


! ------------------------------------------------------------------------------

Room Slype "Slype"                                                      ! >Slype
  with
    name 'corridor' 'passage' 'slype',
    description
      "The Slype is a long east-west corridor lined with decorative bushes. West
      is the Cloister, east is the Infirmary. A small passage heads south to the
      Herbarium and the gardens.",
    s_to Herbarium,
    e_to Infirmary,
    w_to CloisterSE,
    n_to
      "There is an open area between here and the Scriptorium, but you can't get
      to it.",
    in_to
      "It's unclear what you're trying to enter---the Herbarium or the
      Infirmary? Use GO SOUTH or GO EAST.",
    before [;
      Smell:
        if (noun == nothing)
          "A faint sweetness lingers from the bushes, though the flowers are
          mostly gone now.";
      Examine:
        if (noun == Directions && selected_direction == n_to)
          "To the north are some bushes and beyond those, the walls of the
          Scriptorium.";
    ],
    cheap_scenery
      1 'herbarium' [;
          Enter: <<Go FAKE_S_OBJ>>;
          default: "The Herbarium is a wood cottage to the south.";
      ]
      1 'infirmary' [;
          Enter: <<Go FAKE_E_OBJ>>;
          default: "The Infirmary is the building to the east.";
      ]
      CS_THEM 1 'gardens' [;
        "You can't see them from here, but you know they are beyond the
        Herbarium.";
      ]
      1 'scriptorium' [;
        "It's the stone wall of the Scriptorium. You don't see anything
        remarkable about it.";
      ]
      CS_THEM 12 'decorative' 'bush' 'bushes' [;
        Examine:
          "These bushes were a point of pride for Aelred, given how hard it can
          be to grow roses in this climate. Given the season, the flowers are
          largely gone, replaced by only rosehips and their scent.";
        Smell: "Faint but still sweet and floral.";
        Search, LookUnder: "You see nothing in the bushes.";
        Dig, Take: "You wouldn't dare dig up one of these.";
        default: "Leave the bushes be.";
      ]
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;


Object -> RoseOrHips "roses"                                       ! >RoseOrHips
  class AdjObject
  with
    noun_name
      'rose' 'roses' 'rosehip' 'rosehips' 'hip' 'hips' 'flower' 'flowers',
    description
      "The flowers are largely shrivelled and dead, and rosehips replace them.",
    before [;
      Examine, Touch: ;
      Smell: "Still lovely.";
      Search, LookUnder: "There is nothing in the bushes.";
      Take:
        "You dare not take any of the flowers or berries. It would feel wrong to
        take anything of Aelred's pride.";
      default: "Leave the rose plants be.";
    ],
  has convo scenery pluralname;


! --------------------------------------------------------------

! PUZZLE: opening the cabinet
! PUZZLE: identifying the poison

Room Infirmary "Infirmary"                                          ! >Infirmary
  with
    name 'infirmary',
    description [;
      if (self hasnt visited)
        print
          "The Infirmary serves both the brothers and visiting villagers who
          seek healing. ";

      "Several narrow beds line the western wall. A workbench holds mortars and
      bowls for preparing remedies. The air has a sharp tang.

      ^^The Infirmary Chapel is to the south, and the Slype is out to the
      west.";
    ],
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_Infirmary); #EndIf;
    ],
    s_to InfirmaryChapel,
    out_to Slype,
    w_to Slype,
    before [;
      Smell: if (noun == nothing)
        "The air smells of herbs, vinegar, and illness.";
      Grind:
        if (noun == MandrakeRoot || noun ofclass Herb or Plant)
          "You dare not use Brother Benedict's mortars to grind ", (the) noun,
          ". These mortars need to be kept immaculate for his use.";

        "That isn't something you'd grind in a mortar.";
    ],
    cheap_scenery
      CS_THEM 'beds' 'cots' [;
        Examine, Search: "They're simple cots, with nothing on or under them.";
        LookUnder: "There is nothing below the cots.";
      ]
      CS_THEM 4 'mortars' 'mortar' 'bowls' 'bowl' [;
        Examine: "The mortars and bowls are used for grinding medicine.";
        Smell, Taste:
          "They neither smell nor taste of anything. Perhaps they haven't been
          used recently?";
        Search, Empty, Rub: "There's nothing in them.";
        Take, Insert: "Don't mess with Brother Benedict's work tools.";
      ]
      13 'work' 'workbench' 'bench' 'table' [;
        Examine: "A plain wood table holding the mortars and bowls.";
        Receive: "Don't add things to Brother Benedict's work space.";
        LookUnder: "There is nothing below the table.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Object -> Hook "hook"
  class AdjObject,
  with
    adj_name 'wall',
    noun_name 'hook',
    initial [;
      if (children(self) == 0)
        "An empty hook hangs on the wall.";
      "A polished metal mirror hangs from a hook on the wall.";
    ],
    description [;
      print "A simple bent nail driven into the wall, meant to hold the mirror";
      if (Mirror in self) " (which it currently does.)";
      ".";
    ],
    before [;
      Pull, Take:
        "Don't remove the hook---Brother Benedict will want this to hang the
        mirror on.";
      Receive:
        if (children(self) ~= 0)
          "There is something already hanging from the hook.";
        if (noun ~= Mirror)
          "You feel certain that the only thing you should hang here is the
          mirror. Don't confuse Brother Benedict; he has important work here.";
    ],
    after [;
      Receive: "You place the mirror back in its original place on the wall.";
    ],
    has supporter;


Object -> -> Mirror "mirror"                                       ! >Mirror
  class AdjObject,
  with
    adj_name 'reflective' 'polished' 'metal',
    noun_name 'mirror' 'plate',
    describe 0,
    react_before [;
      Examine:
        if (noun == player) {
          print "(in the mirror)^";
          <<Examine Mirror>>;
        }
    ],
    before [;
      Examine, Search:
        "A young face, barely requiring shaving, stares back at you. Your black
        Benedictine habit hangs loose on your thin frame. No tonsure marks your
        crown---you're still a novice, not yet bound by final vows. Brother
        Aelred used to say you had honest eyes. You hope he was right.";
      Attack:
        "Next, you'd want to cross a black cat's path?";
      Take:
        if (self hasnt moved && BrBenedict in location)
          "You dare not steal this in front of the brother.";
    ],
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ],
  has
    convo ;


Object -> InfirmaryCabinet "medicine cabinet"                ! >InfirmaryCabinet
  class AdjObject,
  with
    adj_name 'medicine' 'curious',
    noun_name 'cabinet',
    when_closed [;
      if (self hasnt general)
        "A curious cabinet, perhaps for medicines, sits against a wall.";
      "The medicine cabinet sits against a wall, closed.";
    ],
    when_open [;
      print (The) self, " is open";
      PrintContents(", revealing ", self);
      ".";
    ],
    description [;
      #IfDef HAS_HINTS; HintReady(Hint_Cabinet); #EndIf;
      print
        "A wooden cabinet secured with a brass lock mechanism. Four brass
        wheels, each engraved with digits ~0~ through ~9~, can be rotated
        independently. Carved into the wood above the lock: ~Historia nostra,
        fides nostra~. ";
      if (self hasnt general && self hasnt open)
        print
          "^^You remember Brother Aelred mentioning this cabinet: ~A clever
          device, this. The secret is something any brother would know---I
          myself guessed it years ago. At least it should protect the villagers
          from getting to our medicines.~^^";
      give self general;
      <<Examine Wheels>>;
    ],
    check_combo [;
      ! 1152 = founding date
      if (Wheel1.setting == 1 && Wheel2.setting == 1
          && Wheel3.setting == 5 && Wheel4.setting == 2) {
        give self ~locked;
        TaskDone(TASK_OPENED_MEDICINE_CABINET);
        "^You hear a satisfying click as the lock disengages.";
      } else {
        give self locked;
      }
    ],
    before [;
      if (BrBenedict in Infirmary && action ~= ##Examine or ##Take)
        "You dare not with Brother Benedict here.";

      Search:
        if (self hasnt open) <<Open self>>;
      Examine:
        if (self has open) {
          print (The) self, " is open";
          PrintContents(", and contains ", self);
          ".";
        }
      Lock:
        if (self hasnt locked) <<SetTo Wheels 0>>;
      Unlock:
        if (self hasnt general)
          "[This isn't something you can just unlock. It might help to examine
          it.]";
        <<Set Wheels>>;
      SetTo: <<SetTo Wheels second>>;
      LookUnder:
        "The cabinet reaches down to the floor and is much too heavy to lift.";
    ],
  has
    static convo container openable ~open lockable locked ;


Decoction -> -> FoxgloveDecoction "foxglove decoction"      ! >FoxgloveDecoction
  with
    name 'foxglove',
    description
      "A small bottle filled with a concentrated murky yellow-brown liquid,
      labelled ~Foxglove~. You know from Brother Aelred that this can be
      miraculous for the heart in small quantities, but in greater quantities,
      it can be deadly.",
    before [;
      Smell: "It smells like grass.";
      Taste:
        "You try a small amount. It's unpleasantly bitter, with a strong grassy
        taste.";
    ],
  has ;


Decoction -> -> HenbaneDecoction "henbane decoction"         ! >HenbaneDecoction
  with
    name 'henbane',
    description
      "A small bottle of a concentrated greenish-brown liquid, labelled
      ~Henbane~. You know from Brother Aelred that this is used for sedative
      purposes, though it does have disturbing side-effects. If used in excess,
      it can be fatal.

      ^^This bottle is almost entirely empty, with only a few drops remaining.",
    before [;
        Smell:
          ev_hen_symptoms = true;
          "Like stale urine.";
        Taste:
          ev_hen_symptoms = true;
          "You try a drop: unpleasant, like licking an old chamber pot.";
    ],
    after [;
      Take, Examine:
        ev_took_poison = 1;
    ],
  has evidence ;


Decoction -> -> FeverFewDecoction "feverfew decoction"      ! >FeverfewDecoction
  with
    name 'feverfew',
    description
      "A small bottle filled with a concentrated dark yellow-green liquid,
      labelled ~Feverfew~. You know from Brother Aelred that this is often used
      to treat fevers and ague.",
    before [;
      Smell:
        "It's pungent, similar to but not exactly like strong chamomile tea.";
      Taste:
        "You try a small amount: it's overwhelmingly bitter, with a strong
        chamomile-like flavour.";
    ],
  has ;


Constant MSG_WHEELS_CANT_BE_TURNED
  "The wheels can't be turned while the cabinet is open.";
Constant MSG_DARE_NOT_WHEELS
  "You dare not do this in front of a brother.";

Object -> Wheels "wheels"                                             ! >Wheels
  class AdjObject,
  with
    adj_name 'brass',
    noun_name 'wheels' 'dials' 'lock',
    describe 0,
    description [;
      print
        "The four wheels currently show: ",
          Wheel1.setting, "-",
          Wheel2.setting, "-",
          Wheel3.setting, "-",
          Wheel4.setting;
        ".";
    ],
    before [ s ;
      if (BrBenedict in Infirmary && action ~= ##Examine or ##Search or ##Smell)
        print_ret (string) MSG_DARE_NOT_WHEELS;

      SetTo:
        if (InfirmaryCabinet has open)
          print_ret (string) MSG_WHEELS_CANT_BE_TURNED;

        if (second == -1)
          "You can only set it to a four digit combination.";

        ! Extract individual digits
        s = second;
        Wheel1.setting = s / 1000;
        s = s - (Wheel1.setting * 1000);
        Wheel2.setting = s / 100;
        s = s - (Wheel2.setting * 100);
        Wheel3.setting = s / 10;
        Wheel4.setting = s - (Wheel3.setting * 10);

        print "You set the wheels to ",
          Wheel1.setting, "-",
          Wheel2.setting, "-",
          Wheel3.setting, "-",
          Wheel4.setting, ".^";

        InfirmaryCabinet.check_combo();
        rtrue;
      Turn, Push, Pull, Set:
        "To change the wheels: SET WHEELS TO (number).";
      LookUnder: "There is nothing under the wheels.";
    ],
  has concealed static pluralname;


Wheel -> Wheel1 "first wheel"                                          ! >Wheel1
  with noun_name 'first' '1st' 'one' 'wheel' 'dial';

Wheel -> Wheel2 "second wheel"                                         ! >Wheel2
  with noun_name 'second' '2nd' 'two' 'wheel' 'dial';

Wheel -> Wheel3 "third wheel"                                          ! >Wheel3
  with noun_name 'third' '3rd' 'three' 'wheel' 'dial';

Wheel -> Wheel4 "fourth wheel"                                         ! >Wheel4
  with noun_name 'fourth' '4th' 'four' 'wheel' 'dial';


! ----------------------------------------------------------- Infirmary Chapel
! The player can only enter here after the death, so we can
! write this knowing there will be a body in it, etc.

Room InfirmaryChapel "Infirmary Chapel"                       ! >InfirmaryChapel
  with
    description [;
      print
        "This is a tiny chapel attached to the Infirmary, barely large enough
        for a priest and one or two others. A simple stone altar stands against
        a wall, and a statue stands in a corner, worn smooth by many hands.";
      if (self hasnt visited)
        print
          "^^This chapel is where the dying receive extreme unction, where the
          desperately ill make their final prayers. The air is heavy with the
          memory of fear and hope.";
      "^^The only exit, for the living, is out to the north.";
    ],
    n_to Infirmary,
    out_to Infirmary,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_InfirmaryChapel); #EndIf;
    ],
    cheap_scenery
      11 'infirmary' 'chapel' [; "The Infirmary Chapel is this room."; ]
      CS_THEM 17
        'plague' 'sore' 'sores' 'bubo' 'bubos' 'buboes' 'leg' 'legs'
        "The artist was clearly aiming for realism with these. You recall
        Brother Aelred telling you vivid stories of illness he saw on his
        travels."
      1 'heaven' [;
        Examine: "You glance upward and make the sign of the cross.";
        default:
          "There is nothing you can do with Heaven---at least, not in this
          life.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Altar -> InfirmaryAltar                                        ! >InfirmaryAltar
  with
    invent
      "an altar (with Brother Aelred's body on it)",
    before [;
      Search:
        "Other than your mentor, there is nothing on the altar.";
    ],
  has ~enterable ~supporter transparent ;


! PUZZLE: find the key for the restricted garden
! PUZZLE: identify the poison

Object -> -> BrAelredBody "Brother Aelred's body"                ! >BrAelredBody
  class AdjObject,
  with
    adj_name 'brother' 'aelred^s' 'earthly',
    noun_name 'body' 'corpse' 'remains' 'aelred' 'mentor' 'herbalist',
    show_quote true,
    initial "On the altar are Brother Aelred's earthly remains.",
    description [;
      if (self.show_quote) {
        #IfDef HAS_QUOTES; QuoteBoxSimple(quote_body); #EndIf;
        self.show_quote = false;
      }
      print
        "Your beloved mentor lies still on the altar, still dressed. His face is
        peaceful now, though you remember his agony earlier. His eyes are wide
        open---staring upward as if fixed on Heaven---and his hands are folded
        across his chest";
      if (self hasnt general)
        print
          ". Something seems odd about him, though you can't quite place it";
      else if (task_done->TASK_MATCH_SYMPTOMS)
        print
          ". Now you notice: even in death, his pupils remain enormously
          dilated---a telltale sign of henbane poisoning.";
      ".";
    ],
    react_before [;
      Smell:
        if (noun == nothing)
          "There is an odd faint odour in the air.";
      Pray:
        "You whisper a small sad prayer to your dear mentor. You fervently hope
        he can hear you.";
    ],
    before [;
      Follow:
        "Brother Aelred only journey is to Heaven.";
      Heal:
        "Brother Aelred is in God's hands now, and needs not mortal healing.";
      Smell:
        if (self hasnt general) {
          ev_symptoms = true;
          give self general;
          "There's an odd smell about his remains, something like alcohol and
          urine in his mouth. Unusual.";
        }
        "That same odd smell lingers.";
      Touch: "Already cold.";
      Follow:
        "You followed him faithfully in life---now, you can only treasure his
        memory.";
      Confess:
        "You cannot confess to him now. He is beyond helping.";
      Search:
        if (GardenGateKey hasnt moved) {
          move GardenGateKey to player;
          update_moved = true;
          PronounNotice(GardenGateKey);
          TaskDone(TASK_GARDEN_KEY);
          "In an inner pocket of his robe, you find ", (a) GardenGateKey, ".
          You take it.";
        }
      Kiss:
        print "You reverently kiss him on the forehead";
        if (self hasnt general) print
          "---and then notice an odd odour about his remains";
        ".";
      Attack, Cut, Burn, Eat, Taste: "Absolute blasphemy!";
      LookUnder:
        "Shifting the body slightly, you find nothing underneath.";
      Turn, Push, Pull:
        "You dare not disturb the dead---particularly one who was so dear to
        you.";
      Take:
        "Moving him would be deeply inappropriate. Plus, he's much too heavy to
        carry.";
    ],
    life [;
      Give:
        "He is beyond earthly needs.";
      WakeOther:
        "You've been studying Lazarus too much.";
      default:
        "While in life, he overflowed with energy. Alas, no more.";
    ],
  has animate proper transparent;


Statue -> RochStatue "statue of St Roch"                            ! >RochStatue
  with
    name 'st' 'roch',
    description
      "It depicts St Roch, patron saint of the plague-stricken and the sick.
      He's depicted as a pilgrim, with a hand pointing to a sore on his leg.",
  has ;


! ------------------------------------------------------------------- Herbarium

! PUZZLE: hints more about basil; it's the only thing not hanging here,
!   so it might help them decide to look at it in garden

Room Herbarium "Herbarium"                                          ! >Herbarium
  with
    name 'herbarium',
    description
      "This room still carries Brother Aelred's presence in every corner.
      Bundles of dried herbs hang from the rafters. The worktable in the centre,
      laden with materials above and below, bears the marks of much use. A large
      terracotta pot in the corner was used often to transfer plants. Without
      him here, the room feels hollow.

      ^^The Slype lies north, and the Garden---his garden---waits to the
      south.",
    n_to Slype,
    s_to Garden,
    on_first_entry [;
#IfDef HAS_HINTS;
      HintReady(Hint_HangingHerbs);
      HintReady(Hint_Herbarium);
#EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "Dried herbs and dust, with the faint ghost of everything Aelred ever
          handled here.";
      Listen: "It's unnaturally quiet here. Aelred was always laughing.";
    ],
    cheap_scenery
      'garden' 'gardens' [;
          Enter: <<Go FAKE_S_OBJ>>;
          default: "The Garden is out to the south of here.";
      ]
      1 'materials' [;
        Examine: <<Examine HerbTable>>;
      ]
      3 'thyme' 'rosemary' 'feverfew' [;
        Examine:
          "You can just see them to recognise them, but can't reach them.";
        default:
          "They're too far out of your reach to do anything with.";
      ]
      CS_THEM 5 'bundles' 'dried' 'rafters' 'bunches' 'herbs' [;
        Examine:
          if (parent(player) ~= HerbTable)
            "The different bunches of herbs hang from the rafters. From here,
            you can't make out what they are.";

          "Three different bunches hang from the rafters. They're still out of
          your grasp---Brother Aelred was much taller than you---but you
          recognise them as thyme, rosemary, and feverfew.";
        default:
          "The rafters and the herbs on them are too far up to do anything
          with.";
      ]
      CS_ADD_LIST Core (cs_indoor)
   has ;


! PUZZLE: another way to get the restricted garden key

Object -> Pot "plant pot"                                                 ! >Pot
  class AdjObject,
  with
    adj_name 'large' 'terracotta' 'plant',
    noun_name 'pot',
    describe 0,
    description [;
      print "A substantial container, perfect for repotting a large plant. ";
      if (child(self) == nothing) "It is empty.";
      PrintContents("In it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      if (action ~= ##Examine && player in HerbTable)
        "You can't reach the pot from the table.";

      Attack:
        "You could break this pot---but to what purpose? It is the property of
        the community, and useful besides.";
      Smell: "It smells richly of soil.";
      Take: "It's too large to carry about easily.";
      Turn, Pull, Push, LookUnder, Search:
        if (self has moved || GardenGateKey has moved)
          "Nothing is under the pot.";
        give self moved;
        "You've learned that Brother Aelred would store the key to the
        Restricted Garden under the pot, but it's not there now. Perhaps he used
        it this morning, and he was carrying it?";
    ],
  has
    static container open;


Object -> HerbTable "worktable"                                     ! >HerbTable
  class AdjObject,
  with
    adj_name 'work',
    noun_name 'worktable' 'table',
    description [;
      print
        "The table is the one where you and Brother Aelred did your daily work";
      PrintContents(". On top of it are ", self);
      ".";
    ],
    react_before [;
      Go:
        if (player in self) {
          if (selected_direction == d_to) <<Exit self>>;
          "You'd have to climb down from ", (the) self, " first.";
        };
      Jump:
        "You jump, but you still can't reach the rafters or herbs.";
    ],
    before [;
      Search:
        print
          "It's a large table, with things both on top and under it.";
        PrintContents(" On top of it are ", self);
        ".";
      LookUnder:
        if (Basket hasnt moved) {
          give Basket ~concealed;
          "Looking below the table, you find Brother Aelred's basket, which he
          used for gathering and carrying herbs.";
        }
        "There is nothing else under the table.";
      Climb: <<Enter self>>;
    ],
    after [;
      Enter: "You climb up onto the worktable.";
      Exit: "You climb down from the worktable.";
    ],
  has
    scenery supporter enterable;


Object -> -> Jars "jars"                                                 ! >Jars
  with
    name 'jars',
    description
      "There are almost two dozen of them, each carefully labelled. You know
      these well---managing these has been your daily labour for the past few
      months. You don't see anything missing or unusual about them.",
    before [;
      if (action ~= ##Examine && player in HerbTable)
        "You can't do anything with the jars while standing on the table.";

      Smell:
        "Many jars have a scent, all familiar to you and expected.";
      Search:
        "All the usual ones are present and you see nothing unusual about
        them.";
      Examine, Touch: ;
      default:
        "Leave them be. You have more important tasks today.";
    ],
  has static pluralname;


! PUZZLE: need to handle dangerous plants

Object -> -> Gloves "gloves"                                           ! >Gloves
  with
    name 'gloves',
    description "These are rough gloves, used by Aelred in the gardens.",
    before [;
      Smell: "They smell like dirt and herbs from the gardens.";
      Taste: "For some reason, you lick them. They taste like dirt.";
    ],
    after [;
      Wear:
        if (self hasnt general) {
          give self general;
          print
            "You pause for a second. His gloves, and now they'll pass to you.
            You hope you can honour his work in the garden.^^";
        }
        "You put on Aelred's gloves.";
    ],
  has
    clothing ok_carry pluralname;


! PUZZLE: need to identify poison

Object -> -> Herbal "Aelred's Herbal"                                  ! >Herbal
  class AdjObject,
  with
    adj_name 'aelred' 'aelred^s' 'aelreds',
    noun_name 'herbal' 'book',
    description
      "A thin volume, but very handy: it lists many herbs and other plants,
      along with descriptions of them and their uses.",
    before [  w ;
      Examine:
        if (verb_word == 'read')
          "It's much too dense to read the entire thing. (You can consult it by
          looking up a plant by name, like CONSULT HERBAL ABOUT YARROW.)";
      Consult:
        if (location == thedark) { PrintMsg(MSG_EXAMINE_DARK); rtrue; }
        wn = consult_from;
        w = NextWord();
        ! print "CONSULT ", w, " ", (address) w, "^";
        switch (w) {
          'berries', 'red':
            print
              "The Herbal is indexed by plant names---try using a different
              sense to identify them";

          'rosemary':
            print (ital)
              "Rosemary: one of God's most beneficial gifts, useful for the
              digestion and for nerves. Can be made into a decoction or served
              as a tea.";

          'thyme':
            print (ital)
              "Thyme: powerful for cleaning the blood and warding off the
              plague. Can be made into a decoction or served in a tea.";

          'feverfew', 'featherfoil', 'featherfew':
            print (ital)
              "Feverfew: also known as ~featherfoil~ or ~featherfew~. A
              sovereign remedy for headaches and the agues that bring fever.
              Women take it for monthly afflictions. Chew the fresh leaves or
              make a tea, though the bitterness is formidable. Some claim it
              prevents the megrim when taken daily.";

          'basil':
            print (ital)
              "Basil: difficult to grow in these northern climes, but common in
              warmer lands like southern France and especially Tuscany, where it
              is prized as both culinary herb and remedy. Effective for
              digestive troubles and inflammation of the eyes.";

          'monkshood', 'aconite', 'wolfsbane':
            print (ital)
              "Aconite: called also ~wolfsbane~ and, in the common tongue,
              ~monkshood~, for the shape of its flower. When used with caution,
              can reduce inflammation or problems with breathing. When used
              without care, can result in a death that looks like rabies: with
              frothy saliva, slurred speech, and impaired vision. Used as a
              liniment or decoction.";

          'foxglove':
            print (ital)
              "Foxglove: some claim it strengthens a weak heart, though its use
              is controversial and dangerous. Even small amounts can cause the
              heart to beat irregularly. Handle with great caution, as the plant
              irritates the skin terribly.";

          'mandrake', 'root', 'mandragora':
            print (ital)
              "Mandrake: called also Mandragora, and by some the sleeping root
              or gallows root. In small doses brings drowsiness and eases pain.
              The smoke of the root, carefully breathed, brings a deep and
              restful sleep---useful before surgery or for the gravely restless.
              The root itself should not be eaten in quantity, but it is not
              dangerous to handle.";

          'mustard':
            print (ital)
              "Mustard: the ground seed, mixed with water or vinegar to make a
              paste, draws blood to the skin and gives great relief to aching
              joints and the pains of rheumatism. A mustard plaster applied to
              the chest loosens phlegm and eases the breathing in cases of
              catarrh or lung fever.";

          'valerian', 'setwall':
            print (ital)
              "Valerian: called setwall by the country folk. The dried root,
              taken as a decoction or a tea, can help with the trembling of
              the nerves. Safe to handle and to consume in moderate amounts.";

          'belladonna':
            print (ital)
              "Belladonna: the Italian name for what the English call deadly
              nightshade---look under that name.";

          'hemlock':
            print (ital)
              "Hemlock: common ~poison parsley~ by the common folk. A deadly
              poison, to be kept only for its limited medicinal uses in
              treating spasm and pain. Death comes slowly, as a creeping
              paralysis from the feet upward, while the mind remains clear
              until the end. Socrates himself is said to have died thus. The
              smell of the crushed leaves is foul, like mice.";

          'nightshade', 'deadly':
            print (ital)
              "Deadly Nightshade: a most dangerous plant, to be handled only
              with great care. The berries are tempting but lethal, especially
              to children. In small careful doses, can relieve pain and spasm,
              and ease a troubled stomach. The eyes of one poisoned grow very
              wide and staring, much like henbane, and death follows from even a
              moderate dose. Some physicians call it belladonna, as ladies of
              Italy are said to use drops of it to enlarge the pupils for
              beauty.";

          'atropine':
            print
              "The Herbal contains no entry for that---perhaps try the plant's
              name instead.";

          'yarrow':
            print (ital)
              "Yarrow: called also ~woundwort~ and ~nosebleed plant~, for its
              chief virtues. Applied as a poultice to a fresh wound, it stanches
              bleeding with remarkable speed---the ancients said Achilles
              himself used it on the battlefield. A tea of the dried flowers
              will bring down a fever by encouraging sweat. One of the most
              useful herbs in the infirmarer's store.";

          'chamomile':
            print (ital)
              "Chamomile: a gentle herb, safe for the young and the elderly
              alike. A tea of the dried flowers soothes the stomach, eases
              griping and wind, and calms a restless or anxious mind. The
              infirmarer keeps it always to hand, for it offends no constitution
              and helps many.";

          'elderflower':
            print (ital)
              "Elder (Sambucus nigra): the flowers, dried and taken as a tea,
              are sovereign against catarrh and the chills of winter. A wash of
              elderflower water soothes sore and tired eyes. The country folk
              hold the elder tree in some superstitious regard, and will not
              burn its wood, but the Church finds no harm in its medicinal
              virtues.";

          'sage':
            print (ital)
              "Sage: its very name speaks to its virtue, from the Latin salvare,
              to save or to heal. A tea of the leaves eases sore throats and
              settles the stomach. Rubbed on the teeth and gums it prevents
              decay. Some physicians commend it for strengthening the memory in
              the elderly.";

          'henbane':
            ev_hen_symptoms = true;
            print (ital)
              "Henbane: of great virtue against toothache and the pains of
              rheumatism when taken in very small amounts as a decoction. Yet
              henbane is treacherous in larger quantity. The dying man's eyes
              grow wide and strange, the pupils swallowed up by darkness, as
              though he looks upon things unseen. Visions come upon him---some
              report them as blessed, others as torments. Let the infirmarer
              dispense this herb with great caution, for the difference between
              remedy and poison is a matter of mere drops.";

          'rose', 'roses':
            print (ital)
              "Rose: can treat headaches and eye inflammation. Flowers can be
              beaten to a paste to treat melancholy.";

          'rosehip', 'rosehips', 'hips', 'hip':
            print (ital)
              "Rosehips: as a tea, useful for warding off colds and chest
              pain.";

          default: "You find no entry for that in ", (the) self, ".";
        }

        TaskDone(TASK_USED_HERBAL);
        "";
    ],
    after [;
      Take:
        if (self hasnt moved)
          "You take the Herbal, aware that this was among his most prized
          possessions. You can only hope you'll make as good use of it as he
          did.";
    ],
  has proper ok_carry;


! PUZZLE: need for carrying contraband

Object -> Basket "basket"                                              ! >Basket
  with
    name 'basket',
    capacity 20,
    description [;
      print
        "A flax basket with high sides, useful when harvesting herbs and
        carrying them to the Infirmary";
      PrintContents(". In it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      Receive:
        if (noun has light)
          "Placing a lit item in the basket would surely catch it on fire.";
      Insert:
        "The basket won't fit in ", (the) second, ".";
    ],
    after [;
      if (noun hasnt ok_carry) f_hid_contraband = true;
    ],
  has
    concealed container open ok_carry;


! --------------------------------------------------------------------- Garden


Room Garden "Garden"                                                   ! >Garden
  with
    description [;
      print
        "Aelred's garden. You can still see where his hands touched everything:
        the carefully weeded beds, the path worn by his daily rounds.

        ^^You can enter the Herbarium to the north. A";
      if (GardenGate has open) print "n open"; else print " closed";
      " gate west guards plants too dangerous for common use.";
    ],
    n_to Herbarium,
    w_to GardenGate,
    in_to Herbarium,
    time_left 0,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_Garden); #EndIf;
    ],
    each_turn [;
      self.time_left++;
      if (self.time_left == 5) {
        @set_text_style 4;
        print
          "^Spending time here reminds you of a conversation from spring, when
          Brother Aelred was tending part of the garden. ~This one's a
          challenge, my son,~ he said, gesturing at a new";
        if (BasilPlant has general || Basil has moved)
          print " basil"; else print ", small";
        print
          " plant. ~It wants warmth and sun we can barely give it here. But
          there's a brother of ours---he came from sunnier lands, seeking
          refuge. He never complains, but I see the homesickness in his eyes.~
          Aelred touched the leaves gently. ~If I can coax this to grow, it will
          remind him of home. A small kindness, perhaps, but sometimes those
          matter most.~ You will miss Aelred so much.^";
        style roman;
      }
    ],
    before [;
      Smell:
        if (noun == nothing)
          "The air carries the last of the season's herbs and, beneath that,
          turned earth.";
      Dig:
        "You dare not dig or plant in his garden. Not today.";
    ],
    cheap_scenery
      1 'herbarium' [; "You can see the walls of the Herbarium here."; ]
      1 'path' [; "The path is merely the space between the beds."; ]
      CS_ADD_LIST Core (cs_outdoor)
    ,
  has ;


Object -> Beds "beds"                                                    ! >Beds
  class AdjObject,
  with
    adj_name 'weeded',
    noun_name 'garden' 'beds' 'bed' 'plants',
    description
      "Neat rows of raised beds, carefully tended and weeded. Woody rosemary
      grows tall in one corner, its leaves green against the autumn sky.
      Low-growing thyme spreads in silvery-green mats, while feverfew's white
      daisy-flowers still bloom despite the season. In the most sheltered spot,
      a tiny basil plant catches what little sun reaches this northern garden.
      It's a small miracle that Aelred coaxed it to survive this long.",
    before [;
      Receive, Empty, Take:
        "Soon, it will be your daily labour to manage these plants---but not
        today.";
      Search:
        PrintContents("In the beds are ", self);
        ".";
    ]
  has
    pluralname scenery transparent;


Plant -> -> RosemaryPlant "rosemary plant"                      ! >RosemaryPlant
  with
    name 'rosemary',
    description
      "Several feet tall and woody-stemmed, with needle-like leaves of deep
      green.",
    before [;
      Smell: <<Smell Rosemary>>;
      Taste: <<Taste Rosemary>>;
    ],
  has ;


Herb -> -> -> Rosemary "rosemary sprig"                              ! >Rosemary
  with
    name 'rosemary',
    description "A stalk of needle-like leaves.",
    before [;
      Smell: "It smells of pine sap and wood.";
      Taste:
        "You try a single needle: it tastes strongly of pine and wood.";
    ]
  has ;


Plant -> -> ThymePlant "thyme plant"                               ! >ThymePlant
  with
    name 'thyme',
    description
      "A low, creeping plant with tiny grey-green leaves forming dense mats.
      Even brushing against it releases its scent.",
    before [;
      Smell: <<Smell Thyme>>;
      Taste: <<Taste Thyme>>;
    ],
  has ;


Herb -> -> -> Thyme "thyme sprig"                                       ! >Thyme
  with
    name 'thyme',
    description
      "A miniature forest in a sprig, with many tiny leaves shooting off in
      different directions.",
    before [;
      Smell: "Strongly earthy with a note of mint.";
      Taste: "You try a few leaves. It's warm and earthy.";
    ],
  has ;


Plant -> -> FeverfewPlant "feverfew plant"                      ! >FeverfewPlant
  with
    name 'feverfew',
    description
      "A bushy plant about two feet tall, covered with small white flowers like
      tiny daisies. The leaves are deeply divided and yellow-green.",
    before [;
      Smell: <<Smell Feverfew>>;
      Taste: <<Taste Feverfew>>;
    ],
  has ;


Herb -> -> -> Feverfew "feverfew sprig"                              ! >Feverfew
  with
    name 'feverfew',
    description
      "A cluster of stems bearing small daisy-like flowers with white petals and
      yellow centres. The leaves are feathery and aromatic.",
    before [;
      Smell:
        "Strong and bitter, almost medicinal. Like chamomile but sharper.";
      Taste:
        "You try a single leaf: intensely bitter, leaving your mouth tingling
        unpleasantly.";
    ],
  has ;


! general = player has observed this; the flashback about basil use the right
!   name

Plant -> -> BasilPlant "basil plant"                               ! >BasilPlant
  with
    name 'basil',
    description [;
      give self general;  ! observed
      "Less than half a foot tall, with oval leaves of tender green. It appears
      to be in its first season.";
    ],
    before [;
      Smell: <<Smell Basil>>;
      Taste: <<Taste Basil>>;
    ],
    has ;


Herb -> -> -> Basil "basil sprig"                                       ! >Basil
  with
    name 'basil',
    description "A cluster of large green leaves with pointed tips.",
    before [;
      Smell: "It's strong and peppery, with notes of anise.";
      Taste:
        "You try a single leaf: it's sharp at first, then peppery and a bit like
        liquorice.";
    ],
  has
    convo ;


! -------------------------------------------------------- Restricted Garden

Object -> GardenGate "restricted garden gate"                      ! >GardenGate
  class AdjObject,
  with
    adj_name 'restricted' 'garden',
    noun_name 'gate' 'lock' 'fence',
    description [;
      #IfDef HAS_HINTS; HintReady(Hint_GardenGate); #EndIf;
      print "This wooden fence protects access to the dangerous plants. It is ";
      if (self has open) "open."; "closed.";
    ],
    found_in RestrictedGarden Garden,
    door_dir (e_to) (w_to),
    with_key GardenGateKey,
    before [;
      #IfDef HAS_HINTS; HintReady(Hint_GardenGate); #EndIf;

      Climb:
        "The fence is covered with sharp brambles, making it impossible to climb
        without serious injury. Brother Aelred no doubt encouraged these to grow
        here to restrict access to the dangerous herbs.";
    ],
  has
    scenery door openable locked lockable;


Object GardenGateKey "iron key"                                 ! >GardenGateKey
  class AdjObject,
  with
    article "an",
    adj_name 'iron' 'garden' 'restricted' 'pitted' 'rusty',
    noun_name 'key' 'keys//p',
    description [;
      "Heavy and iron, its surface pitted with rust from years hanging in the
      damp Herbarium. You know this key from seeing Aelred use it: it opens the
      gate to the Restricted Garden where the dangerous herbs are grown.";
    ],
  has ok_carry;


Room RestrictedGarden "Restricted Garden"                    ! >RestrictedGarden
  with
    name 'restricted' 'garden',
    description [;
      print
        "Here is Aelred's collection of dangerous plants---those too potent for
        casual use, too deadly for error. The beds here are smaller, more
        carefully separated.";
      if (self hasnt general)
        print
          "^^Aelred brought you here only twice, making you repeat each plant's
          name, its use, its danger. ~Respect them, my son~, he said. ~In the
          right dose, they heal. In the wrong, they kill.~";
      give self general;
      print "^^The only exit is out through the gate to the east, which is ";
      if (GardenGate has open) "open."; "closed.";
    ],
    e_to GardenGate,
    out_to GardenGate,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_RestGarden); #EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "Something sweetish and medicinal underneath the cold air. Not
          unpleasant, exactly. But wrong, somehow.";
      Dig:
        "You dare not dig or plant in his garden. Not today.";
    ],
    cheap_scenery
      CS_ADD_LIST Core (cs_outdoor)
    ,
  has ;


Object -> RestBeds "beds"                                            ! >RestBeds
  with
    name 'dangerous' 'beds' 'bed' 'plants',
    description
      "The beds are smaller and carefully separated here---no risk of
      cross-contamination. You recognise monkshood by its dark leaves and hooded
      flowers, foxglove by its pink bells, henbane by its sickly-sweet smell.",
    before [;
      Receive, Take, Remove:
        "Soon, it will be your daily labour to manage these---but not yet.";
    ],
  has
    pluralname scenery container open;


Plant -> -> MonkshoodPlant "monkshood plant"                   ! >MonkshoodPlant
  with
    name 'monkshood' 'aconite' 'wolfsbane',
    description
      "Several feet high, with spikes of helmet-shaped, deep blue flowers.",
    before [;
      Smell: <<Smell Monkshood>>;
      Taste: <<Taste Monkshood>>;
    ],
  has toxic ;


Constant MSG_CAN_BE_LETHAL
  "You dare not. It can be lethal even in small doses.";

Herb -> -> -> Monkshood "monkshood sprig"                           ! >Monkshood
  with
    name 'monkshood' 'aconite' 'wolfsbane',
    description
      "The flowers are deep blue, and in a shape like a monk's cowl, hence the
      name.",
    before [;
      Smell:
        "You cautiously sniff: barely any scent at all. The plant saves its
        power for those who consume it.";
      Taste: print_ret (string) MSG_CAN_BE_LETHAL;
    ],
  has toxic ;


Plant -> -> FoxglovePlant "foxglove plant"                      ! >FoxglovePlant
  with
    name 'foxglove',
    description
      "A tall plant with distinct stems of flowers: bell-shaped and pink.",
    before [;
      Smell: <<Smell Foxglove>>;
      Taste: <<Taste Foxglove>>;
    ],
  has toxic ;


Herb -> -> -> Foxglove "foxglove sprig"                              ! >Foxglove
  with
    name 'foxglove',
    description
      "The flowers are pink and bell-shaped, dangling in a long spike---each
      bloom like a tiny glove finger, hence the name.",
    before [;
      Smell:
        "Barely any scent at all, just a faint greenness, like cut stems.";
      Taste: print_ret (string) MSG_CAN_BE_LETHAL;
    ],
  has toxic ;


Plant -> -> HenbanePlant "henbane plant"                         ! >HenbanePlant
  with
    name 'henbane',
    description
      "A sprawling plant, with yellow and purple bell-shaped flowers.",
    before [;
      Smell: <<Smell Henbane>>;
      Taste: <<Taste Henbane>>;
    ],
  has toxic ;


! on = looked up henbane

Herb -> -> -> Henbane "henbane sprig"                                 ! >Henbane
  with
    name 'henbane',
    description "The flowers are dirty yellow and streaked with purple.",
    before [;
      Smell: "Reminiscent of stale urine. Very unpleasant.";
      Taste: "You wouldn't dare. You've been taught that it's very toxic.";
    ],
  has toxic ;


Object -> MandrakeRoot "mandrake root"                        ! >MandrakeRoot
  with
    name 'mandrake' 'root',
    initial
      "A small gnarled mandrake root pushes from the earth, pale and forked like
      a tiny human figure.",
    description
      "A small, pale, forked root twisted into a vaguely human shape.",
    before [;
      Smell:
        "An unpleasant, earthy smell.";
      Taste:
        "You take a tiny nibble, and find it extremely unpleasant.";
      Eat:
        "You've already learned from Brother Aelred enough to know you shouldn't
        eat this.";
      Prune:
        <<Take self>>;
    ],
    after [;
      Take:
        if (self hasnt moved)
          "You wrap your fingers around it carefully and pull it free. The root
          forks into two distinct limbs below the crown---the shape the ancients
          called anthropomorphon, the man-formed. They said it screamed when
          pulled from the earth. The silence feels like a small mercy.";
    ],
  has
    toxic ok_carry convo ;

! ------------------------------------------------------------- Refectory

! only meal would be after None (at 3pm)
Room Refectory "Refectory"                                          ! >Refectory
  with
    name 'hall' 'refectory',
    description
      "The Refectory is a long, austere hall where the community takes its meals
      in silence while one brother reads aloud from the lectern. Two rows of
      trestle tables stretch the length of the room, their surfaces scrubbed
      clean. High windows along the wall admit @(DS_LIGHT) that barely reaches
      the floor. The smell of pottage lingers faintly in the air.

      ^^A doorway to the south leads to the Kitchen, and a wide opening to the
      north returns out to the Cloister.",
    n_to CloisterS,
    s_to Kitchen,
    out_to CloisterS,
    toward_slype n_to,
    before [;
      Smell: if (noun == nothing) "The scent of pottage from previous meals.";
      Listen: "You can hear activity in the Kitchen to the south.";
      SitAny: <<Enter RefectoryBenches>>;
    ],
    cheap_scenery
      1 'kitchen' [;
        Enter: <<Go FAKE_S_OBJ>>;
        default: "The Kitchen is south of here.";
      ]
      1 'lectern' [;
        Examine: "A plain wooden stand, used for reading during meals.";
        Take, Push, Pull, Turn: "You dare not move it.";
        Receive: "You dare not clutter it with your stuff.";
      ]
      CS_THEM 'window' 'windows' [;
          "The windows are only a bare opening in the wall, and
          too high up to do anything with.";
      ]
      CS_THEM 4 'trestles' 'trestle' 'table' 'tables' [;
        Examine: "The tables are bare and well-washed.";
        Take, Push, Pull, Turn: "You dare not mess with the tables.";
        Search: "The tables are bare.";
        Receive: "You dare not clutter the meal tables with your stuff.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


Chair -> RefectoryBenches "benches"                          ! >RefectoryBenches
  with
    description "Plain wooden benches.",
    name 'bench' 'benches',
    article "some",
    before [;
      Turn, Pull, Push:
        "Rearranging the furniture here would irritate Brother Martin.";
    ]
  has scenery pluralname;


! ------------------------------------------------------------------ Kitchen

! general = been given fish
! on = has tried stairs

Room Kitchen "Kitchen"                                                ! >Kitchen
  with
    name 'kitchen',
    description
      "The priory kitchen is a large room, lit by high windows. A door leads
      north to the Refectory, and stairs descend to the Undercroft below.

      ^^A large table dominates the centre, scattered with implements and
      vessels. A hearth is built into a wall, its fire warming the room.",
    n_to Refectory,
    out_to Refectory,
    d_to Undercroft,
    toward_slype n_to,
    time_left 0,
    cheap_scenery
      1 'undercroft' [;
        Enter: <<Go FAKE_D_OBJ>>;
        default: "The Undercroft is the cellar down from here.";
      ]
      CS_THEM 'window' 'windows' [; "The windows are far above."; ]
      CS_THEM 4 'vegetable' 'vegetables' 'leeks' 'food' [;
        Examine:
          "Leeks. Not your favourite. You remember entire weeks as youth
          where your meals consisted only of them.";
        Take: "You dare not take food from others.";
      ]
      CS_THEM 'implements' 'various' [;
        Examine, Search: "A collection of utensils, knives, and vessels.";
        Take: "You won't. These are needed by Brothers Martin and Remigio.";
      ]
      CS_THEM 5 'utensils' 'knives' 'vessels' 'spices' 'knife' [;
        Examine, Search:
          "You needn't worry about these---Brother Martin is the kitchener.";
        Take: "You won't. These are needed by Brothers Martin and Remigio.";
      ]
      CS_ADD_LIST Core (cs_indoor)
    ,

    on_first_entry [;
  #IfDef HAS_HINTS;
      HintReady(Hint_Kitchen);
      HintReady(Hint_AccessUndercroft);
  #EndIf;
    ],

    fish_give [;
      if (action ~= ##Give) new_line;
      if (Fish hasnt moved) {
        move Fish to player;
        update_moved = true;
        print
          "Brother Martin smiles broadly. ~Hungry, are we, Brother Novice?~ He
          takes a piece of smoked fish and presses it into your hands. ~There.
          Now leave us to our work.~";
      } else {
        print
          "Brother Martin says ~Out, out, Brother. Remigio and I are working.~";
      }
      print " He ushers you out north, to the Refectory.^^";
      PlayerTo(Refectory);
    ],
    each_turn [;
      if (BrMartin in self) {
        self.time_left++;
        if (self.time_left < 4) rfalse;
        self.fish_give();
      }
    ],
    before [;
      Going:
        if (SceneWandering has general)
          return ShouldNotGoNow(self, BrMartin);
      Search:
        if (BrMartin in Kitchen || BrRemigio hasnt general)
          "You can't just search here with another brother here.";
      Smell:
        if (noun == nothing)
          "There is a strong smell from the cauldron.";
      Listen:
        print "You can hear the noise of ";
        if (BrMartin in self) print "Brother Martin and ";
        "Brother Remigio working.";
      Go:
        if (selected_direction == d_to) {
          give Kitchen on;  ! tried going down stairs
          if (BrMartin in location || BrHugh in location)
            print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
          if (BrRemigio in Kitchen && BrRemigio hasnt general)
            "Brother Remigio stops you, apologetically. ~No, not allowed~, he
            says, ~Frate Hugh, he not allow go to cellars.~";
          f_found_darkness = true;
          if (MyCandle notin player || MyCandle hasnt light) {
            print_ret (string) MSG_WONT_GO_DARK;
          }
          print
            "Brother Remigio looks away slyly as you head down the stairs.^";
        }
    ],
    after [;
      Search:
        "There are many things here, but all of them are simple implements
        expected in a kitchen, and you find nothing unexpected or useful.";
    ]
  has ;


Fireplace -> Hearth "hearth"                                           ! >Hearth
  with
    name 'hearth',
    description
      "The hearth is a stone block built into the wall, with a fire burning in
      it. A cauldron hangs above the fire.",
    before [;
      if (BrMartin in location && action ~= ##Search or ##Examine or ##Smell)
        print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
      Receive:
        if (noun == MandrakeRoot)
          "That would spoil the pottage. You think better of this.";
    ]
  has ;


Object -> -> Cauldron "cauldron"                                     ! >Cauldron
  with
    name 'cauldron' 'pot' 'pottage' 'soup' 'stew',
    description
      "The cauldron is a large iron pot hanging over the fire, filled with
      pottage, a thick vegetable stew that will feed the brothers at their next
      meal.",
    before [;
      if (BrMartin in location && action ~= ##Search or ##Examine or ##Smell)
        print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
      Smell: "It smells like leeks.";
      Touch: "Ow, ow, ow.";
      Taste, Eat: "It's not mealtime yet.";
      Blow: "You can't manage to cool it.";
      Search: "The cauldron contains pottage bubbling away.";
      LookUnder: "Below the cauldron is the fire.";
      Take: "It's far too hot and heavy to move.";
      Receive:
        "This is food for you and your brothers. You shouldn't tamper with it.";
    ],
  has scenery;


Object -> KitchenTable "table"                                   ! >KitchenTable
  with
    name 'working' 'table',
    description [;
      print
        "A long high table, big enough for two or three people to work at. It
        has a collection of utensils, knives,";
      if (Fish hasnt moved) print " a piece of smoked fish,";
      print " and vessels of spices on it";
      PrintContents(". Also on it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      Enter, Climb:
        print_ret (string) MSG_DARE_NOT_ANOTHER_BROTHER;
    ],
  has scenery supporter;


Object -> -> Fish "smoked fish"                                          ! >Fish
  class AdjObject,
  with
    article "a piece of",
    adj_name 'smoked',
    noun_name 'fish' 'cod',
    description "Cod? Haddock? You're a gardener, not a fisherman.",
    before [;
      Smell: "A slight whiff of brininess and wood smoke.";
      Eat: <<Taste self>>;
      Taste: "You try a nibble. It's delicious.";
      Take:
        if (Fish hasnt moved) {
          if (BrMartin in Kitchen)
            "Brother Martin is right here. You can't just steal food.";
          if (BrRemigio hasnt general)
            "~Ladro, ladro---uh--thieves!~ Brother Remigio cries, and stops you
            from taking the fish.";
        }
    ],
    after [;
      Take:
        if (Fish hasnt moved)
          "Brother Remigio slyly looks away while you take ", (the) Fish, ".";
    ],
  has
    concealed edible ok_carry ;


! ================================================ Basement


Room Undercroft "Undercroft"                                       ! >Undercroft
  with
    name 'undercroft',
    description [;
      print
        "Barrels crowd this vaulted space beneath the Refectory. Many things the
        priory needs to survive are here: tallow, salt, wine, mustard, grain.
        Smaller items are spread across a table in the corner. The cellarer's
        careful hand is evident in the organisation---each item labelled,
        stacked, accounted for.";
    if (self hasnt visited)
      print
        "^^As cellarer, Brother Hugh alone manages this space: organising the
        stores, counting what remains, arranging what must be purchased. No
        other brother would have reason to come here uninvited.";

    "^^Stairs lead up to the Kitchen. A wide door to the west allows barrels
    to be rolled in and out for deliveries.";
    ],
    u_to Kitchen,
    w_to PassageSouth,
      on_first_entry [;
  #IfDef HAS_HINTS;
        HintReady(Hint_Undercroft);
  #EndIF;
      ],
    before [;
      Go:
        if (selected_direction == u_to && BrHugh in Kitchen) {
          print
            "^Brother Hugh catches you coming up from the Undercroft. ~What were
            you doing down there? It's not allowed.~";
            KillOff(5);
        }
      Listen:
        "Unnervingly, you hear rats, but don't see them.";
      Smell:
        if (noun == nothing)
          "Musty and filled with fragrances from the barrels, especially with
          the overpowering odour of tallow.";
    ],
    each_turn [ o ;
      if (BrHugh in Undercroft) {
        print
          "^Brother Hugh catches you here. ~You!~ he snarls, ~What are you doing
          here?~ ";

        if (BrHugh has general) {
          print "You've been caught here before. ";
          return self.die();
        }
        give BrHugh general;

        objectloop(o ofclass Barrel)
          if (o has open) {
            print "He sees ", (the) o, ", obviously open. ";
            return self.die();
          }

        objectloop (o in Undercroft)
          if (o has evidence) {
            print  "Looking around the room,";
            return self.die(o);
          }

        objectloop (o in player)
          if (o has evidence) {
            print "Searching you,";
            return self.die(o);
          }

        if (Basket in player or Undercroft)
          objectloop (o in Basket)
            if (o has evidence) {
              print "Searching the basket,";
              return self.die(o);
            }

        objectloop (o in MyHood)
          if (o has evidence) {
            print "Searching your hood,";
            return self.die(o);
          }

        print
          "^^He opens the wide door to the west and shoves you out, closing the
          door after.^^";
        PlayerTo(PassageSouth);

      } else if (BrMartin in Kitchen) {
        "^Above, you can hear Brothers Martin and Remigio talking.";
      }
    ],
    die [ item ;
      if (item) print " he finds ", (the) item, ". ";
      print
        "~So, Brother Novice,~ he says quietly, his voice cold.
        ~You've been meddling where you shouldn't.~";
      if (PrayerMat has general) {
        give PrayerMat ~general;
        ev_hugh_attempt = true;
        print
          "^^You see Brother Hugh swing to hit your head, but he stumbles and
          you dodge aside. You manage to escape through the door.

          ^^St Jude has answered your desperate prayer with a miracle.^^";
        PlayerTo(PassageSouth);
        rfalse;
      }
      deadflag = 1;
      print
        "^^You feel a hard object smash against the back of your head. You fall
        to the ground, gasping.

        ^^You feel yourself being stuffed into an empty barrel, and can hear him
        hammering the lid shut. You pass out---mercifully---so you don't feel
        yourself being rolled off the cliffs and into the dark sea.";
      rtrue;
    ],
    time_left 0,
    cheap_scenery
      21 'various' 'smaller' 'items' [;
        Examine, Search, LookUnder: <<Examine UndercroftTable>>;
      ]
      1 'door' [;
        Examine: "It's a broad wooden door.";
        Push, Open, Enter:
          <<Go FAKE_W_OBJ>>;
        Close: "It is already closed.";
        Unlock, Lock: "The door has no lock on it that you can see.";
        LookUnder: "You cannot see anything below the door.";
      ]
      CS_ADD_LIST Core (cs_indoor)
  has
    ~light convo;


Object -> UndercroftTable "table"                             ! >UndercroftTable
  with
    name 'table',
    describe 0,
    description [;
      print "The table here is made of rough wood";
      PrintContents(". On it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      LookUnder: "There is nothing below the table but the dirt floor.";
      Push, Pull, Turn: "You push the table a bit and find nothing unexpected.";
      Climb, Enter: "It is too rickety to stand on safely.";
    ],
  has
    static supporter ;


Object -> -> Ledger "ledger"
  with
    name 'ledger' 'paper' 'cord',
    description
      "It's a sheaf of coarse paper, tied with a simple cord. It seems to record
      recent purchases and sales of goods for the priory.",
    before [;
      Examine:
        if (verb_word == 'read')
          "It's filled with Hugh's cramped hand. The most recent items listed
          are the sale of beeswax candles, a purchase of a barrel of mustard
          seeds, and the sale of sheep from the priory's fields.";
    ],
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ],
  has ;


Object -> -> Stick "pointed stick"                                      ! >Stick
  class AdjObject,
  with
    adj_name 'long' 'pointed',
    noun_name 'stick' 'branch',
    describe 0,
    description
      "It's a long branch from a tree. It may be used for hitting at rats, as
      there's a bit of dried blood on one end.",
    react_before [;
      Go:
        if (IndirectlyContains(player, self) &&
              location.(selected_direction) == GreatDoor or WestGate or Kitchen)
          "You need to drop ", (the) self, " first.
          It's much too large and conspicuous to carry around the priory.";
    ],
    before [;
      Wave:
        "Absolutely nothing magical happens, as you'd expect.";
      Rub:
        <<Rub Blood>>;
      Insert:
        if (second ~= Basket && ~~second ofclass Barrel)
          "The stick wouldn't fit in ", (the) second, ".";
        if (second == Basket)
          "It's too long to fit in the basket properly, but it rests on top of
          it.";
    ],
    after [;
      Take:
        if (self hasnt moved)
          "It's long enough that it's awkward to carry, but you take it all the
          same.";
    ],
  has transparent ;


Object -> -> -> Blood "blood"                                           ! >Blood
  with
    name 'blood',
    description "The blood is well-dried and doesn't seem recent.",
    before [;
      Taste, Smell: "You dare not.";
      Rub:
        "You wipe at it with the sleeve of your habit, but the blood is dried on
        and cannot be removed.";
    ],
  has static ;


Object -> Barrels "barrels"                                           ! >Barrels
  with
    parse_name [;
      ! This object is only for examining; other things, like OPEN BARRELS
      ! should get the usual "which barrel do you mean?"
      if (action ~= ##Examine) return 0;
      return (NextWord() == 'barrels//p');
    ],
    before [ b i ;
      Examine:
        print "You see five barrels: ";
        objectloop (b ofclass Barrel) {
          i++;
          print (address) b.simple_name;
          if (b has open) print " (open)";
          switch (i) {
            1,2,3: print ", ";
            4: print " and ";
            5: ".";
          }
        }
    ],
  has concealed scenery pluralname;


Barrel -> GrainBarrel "grain barrel"                              ! >GrainBarrel
  with
    name 'grain',
    simple_name 'grain',
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~GRAIN~";
      if (self has open)
        print ". It is currently open, revealing dried wheat kernels";
      ".";
    ],
    before [;
      Smell:
        if (self has open)
          "A faint, dusty grain smell.";
      Taste:
        if (self has open)
          "You take a kernel and chew it: hard and chalky, as expected.";
    ],
  has edible;


Barrel -> WineBarrel "wine barrel"                                ! >WineBarrel
  with
    name 'wine',
    simple_name 'wine',
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~WINE~";
      if (self has open)
        print ". It is currently open, revealing dark red wine within";
      ".";
    ],
    before [;
      Drink: "You wouldn't dare steal from the priory's stores.";
      Smell:
        if (self has open)
          "The sharp, fruity scent of wine fills your nostrils.";
      Taste:
        if (self has open)
          "You dip a finger and taste: sour, vinegary. Table wine, not
          sacramental quality.";
    ];


Barrel -> SaltBarrel "salt barrel"                                ! >SaltBarrel
  with
    name 'salt',
    simple_name 'salt',
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~SALT~";
      if (self has open)
        print ". It is currently open, revealing coarse grey salt";
      ".";
    ],
    before [;
      Smell:
        if (self has open)
          "A faint mineral scent, mixed with the tang of the sea.";
      Taste:
        if (self has open)
          "You taste a few crystals: intensely salty, as expected.";
    ],
  has edible;


Barrel -> TallowBarrel "tallow barrel"                          ! >TallowBarrel
  with
    name 'tallow',
    simple_name 'tallow',
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~TALLOW~";
      if (self has open)
        print ". It is currently open, revealing pale, waxy rendered fat";
      ".";
    ],
    before [;
      Smell:
        if (self has open)
          "A greasy, animal smell: not pleasant, but not rotten either.";
      Taste:
        if (self has open)
          "You absolutely refuse to taste rendered animal fat.";
      Take:
        if (self has open)
          "You won't. Leave that to the chandler.";
    ];


Barrel -> MustardBarrel "mustard barrel"                        ! >MustardBarrel
  with
    name 'mustard' 'ground',
    simple_name 'mustard',
    description [;
      print
        "A stout wooden barrel bearing the charcoal mark ~MUSTARD~";
      if (self has open)
        print ". It is currently open, revealing yellow-brown ground mustard";
      ".";
    ],
    before [;
      Smell:
        if (self has open)
          "Sharp and pungent---the unmistakable bite of ground mustard.";
      Taste:
        if (self has open)
          "You taste a tiny amount: fiery hot and bitter. You cough.";
    ],
    after [;
      Search:
        the_time = the_time + 4;
        move MustardPackage to player;
        "After digging around with the stick for several minutes, you find
        something buried deep in the mustard. You pull it free: a small package,
        its burlap stained deep yellow. You take it.";
    ],
  has edible convo ;


Object MustardPackage "mustard-yellow package"                 ! >MustardPackage
  class AdjObject,
  with
    adj_name 'mustard' 'yellow',
    noun_name 'package',
    capacity 1,
    description
      "A small package of burlap, tied with simple cord. Originally dark, it has
      stained deep yellow from the mustard.",
    before [;
      Smell: "It smells sharply of mustard.";
      Taste: "You lick it and can recognise the bite of mustard.";
      Close: "You can't retie the package again, so it will remain open.";
      Receive:
        if (noun ~= StolenPsalter)
          "The package isn't useful as a container for ", (the) noun, ".";
    ],
    after [;
      Open:
        itobj = StolenPsalter;
        "You untie the cord, revealing a small illuminated psalter.";
    ],
  has
    container openable ~open evidence convo ;


Object -> StolenPsalter "illuminated psalter"                   ! >StolenPsalter
  class AdjObject,
  with
    article "an",
    adj_name 'illuminated' 'stolen',
    noun_name 'psalter' 'manuscript' 'book' 'doves' 'wheat' 'grapes',
    description
      "A small psalter, exquisitely crafted. The leather cover is tooled with a
      design of intertwined vines and lilies. Opening it, you see Brother
      Wilfred's unmistakable hand, each page a work of devotion. The opening
      initial 'B' of Psalm 1 (~Beatus vir~) is illuminated in brilliant azure
      and gold leaf, depicting a tree bearing fruit by streams of water.
      Marginal decorations show doves, wheat, and grapes.

      ^^This is clearly one of Wilfred's finest works. It should be kept in the
      Library before it is sold, not hidden away.",
    before [;
      Examine:
        #IfDef HAS_QUOTES;
          if (ev_psalter == false) QuoteBoxSimple(quote_psalter);
        #EndIf;
        ev_psalter = true;
        if (verb_word == 'read')
          "The psalms are beautiful, but what strikes you most is the artistry,
          the hours Wilfred must have spent on each illumination.";
      Search:
        "You feel the psalter will be full of much religious learning for
        you---but in terms of searching it now for clues, you find none.";
      Smell: "It smells sharply of mustard.";
      Taste: "You wouldn't do this to such a precious object.";
    ],
  has
    ~concealed evidence convo ;  ! Remove concealed when player searches


! ---------------------------------------------------- FitzAlan Crypt

Object Ladder "ladder"                                                 ! >Ladder
  with
    name 'ladder',
    found_in [;
      if (location == FitzAlanChantry && FitzAlanAltar has open) rtrue;
      if (location == FitzAlanCrypt) rtrue;
    ],
    description [;
      if (self hasnt general) {
        #IfDef HAS_QUOTES; QuoteBoxSimple(quote_ladder); #EndIf;
        give self general;
      }
      if (player in FitzAlanLargeTomb or FitzAlanSmallTomb)
        "You're higher now, but the ladder is still high above you.";
      if (location == FitzAlanCrypt) "The ladder is far above you.";
      "A narrow wooden ladder leads down into darkness.";
    ],
    before [;
      Climb, Exit:
        if (location == FitzAlanCrypt) "You can't reach the ladder.";
        <<Go FAKE_D_OBJ>>;
      Take, Pull, Push:
        if (location == FitzAlanCrypt) {
          if (player in FitzAlanLargeTomb or FitzAlanSmallTomb)
            print "Even from here, t";
          else print "T";
          "he ladder is much too high to reach.";
        }
        else {
          "The ladder seems attached to the ceiling of the space below.";
        }
      LookUnder:
        if (location == FitzAlanChantry)
          "You cannot see the bottom of the ladder from here.";
        "Given that the ladder is high above, everything in the room is below
        it.";
    ]
  has scenery open;


Room FitzAlanCrypt "FitzAlan Crypt"                             ! >FitzAlanCrypt
  with
    name 'stone' 'walls' 'chamber',
    description
      "This is a small vaulted chamber, no more than ten feet across. The
      central tomb bears the effigy of a knight. Flanking this is a smaller
      undecorated tomb.

      ^^The walls here are finished stone rather than rough-hewn rock, and a
      narrow recess has been cut into them---likely once holding offerings or
      relics. The air is still, undisturbed for decades or longer. A patina of
      dust covers everything, unmarred by footprints save your own.",
    s_to [;
      if (FitzAlanPanel has open) return Crypt;
    ],
    u_to "Alas, the ladder is raised up and well out of your reach.",
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_FACrypt); #EndIf;
    ],
    before [;
      Going:
        if (selected_direction == n_to) {
          print "You slip through the opening behind the panel, revealing...^";
        }
        if (selected_direction == d_to) {
          if (~~IsCarryingLit()) {
            #IfDef HAS_HINTS; HintReady(Hint_candle); #EndIf;
            print_ret (string) MSG_WONT_GO_DARK;
          }

          print
            "^You climb down the ladder.^^", (bd) "~SNAP!~", " As you step off
            the bottom rung, a counterweight somewhere in the mechanism snaps
            the ladder back to the ceiling, far out of reach. Are you
            trapped?^";
        }
      Examine, Search: if (location == thedark) "But it's dark.";
      Listen: "The silence is eerie.";
      Smell:
        if (noun == nothing)
          "The air is thick and dust fills your nostrils.";
      Rub: "You try to clean up some of the dust, but it's a hopeless task.";
    ],
    cheap_scenery
      CS_THEM 1 'footprints' [;
        Examine: "These are just your footprints in the dust.";
        LookUnder: "Just the floor.";
        default: "There's nothing you can really do with them.";
      ]
      CS_THEM 'crypts' 'tombs' [;
        Examine:
          "There are two tombs here, one larger and one smaller.";
        default:
          "[To do anything with the tombs, address them individually.]";
        ]
      19 'fitzalan' 'knight' 'lion' 'arms' 'armor' 'armour' 'shield'
          'carvings' 'carving' 'effigy' [;
        Examine, LookUnder:
          "The knight, shield, and lion are well done, but they're mere carvings
          in the stone.";
        Search, Smell, Touch: ;
        Push, Pull, Take, Turn:
          "The knight and its shield and arms are carved into the stone. They
          don't respond to your manipulation.";
        default:
          "There's nothing you can do with these.";
      ]
      1 'dust' [;
        Rub: "This would be an impossible task.";
        default: "It's simply dust, and it's everywhere.";
      ]
      1 'opening' [;
        if (FitzAlanPanel hasnt open) "You can't see any such thing.";

        Examine:
          "This is the opening revealed by the open panel. You can go south
          through it.";
        Enter:
          <<Go FAKE_S_OBJ>>;
        default:
          "It's merely an opening in the wall. You can only go through it.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
    cant_go [;
      if (FitzAlanPanel hasnt open) "It appears there is no exit from here.";
      self.Room::cant_go();
    ],
  has
    ~light;


Object -> Recess "recess"
  with
    name 'recess',
    description [;
      print "The recess is a space cut into the wall";
      PrintContents(". In it ", self, ISARE_BIT);
      ".";
    ],
    before [;
      Enter: "It's much too small for you.";
    ]
  has scenery container open ;


Tomb -> FitzAlanLargeTomb "larger tomb"                     ! >FitzAlanLargeTomb
  with
    noun_name 'large' 'larger' 'central' 'center' 'centre' 'tomb',
    description
      "Large, heavy, and sealed. The carving shows a knight in chainmail, his
      hands clasped in prayer. His shield displays a lion, the FitzAlan arms."
  has
    ~proper;


Tomb -> FitzAlanSmallTomb "smaller tomb"                    ! >FitzAlanSmallTomb
  with
    noun_name 'undecorated' 'small' 'smaller' 'tomb',
    description
      "Probably for the FitzAlan wife or children, this is a simple square
      block, fully sealed.",
  has
    ~proper;


Constant MSG_PANEL_AFFIXED
  "The art panel seems fixed to the distinctive brass frame.";

! open = open
Object -> FitzAlanPanel "art panel"                             ! >FitzAlanPanel
  class AdjObject,
  with
    adj_name 'wooden' 'wood' 'faded' 'noble' 'three' 'painted',
    noun_name 'art' 'panel' 'youths' 'corpses' 'inscription' 'painting',
    initial [;
      if (self has open)
        "The panel is ajar, revealing an opening to the south.";
      if (frame has general)
        "The panel is currently closed flush against the wall.";

      "Against the southern wall hangs a faded wooden panel depicting a painted
      scene, its Latin inscription barely legible in the gloom.";
    ],
    description [;
      if (self has open)
        "The panel is ajar from the wall, revealing an opening to the south.";

      "A large wooden painted panel set in a distinctive brass frame, it depicts
      the Three Living and the Three Dead---three noble youths recoiling from
      three crowned corpses who gesture toward them. Woven beneath in Gothic
      script: ~QUOD FUIMUS, ESTIS; QUOD SUMUS, ERITIS~ (What we were, you are;
      what we are, you will be). Time has taken its toll on the pigments.";
    ],
    before [;
      Take:
        "Before you even try, you realise this would be too large to carry.";
      Burn:
        "Given how damp it is here, you couldn't catch it alight.";
      Search:
        "Besides your search for meaning in this memento mori, you find nothing
        unexpected in the artwork.";
      Touch:
        "You can feel the damp from the room on the art.";
      Turn, Swing: "Nothing happens when you try to rotate the panel.";
      Push:
        if (Frame hasnt general)
          print_ret (string) MSG_PANEL_AFFIXED;
        if (self has open) <<Close self>>;
        print_ret (string) MSG_PANEL_AFFIXED;
      Pull:
        if (self has open) "The panel is already ajar.";
        print_ret (string) MSG_PANEL_AFFIXED;
      LookUnder:
        if (self hasnt open)
          "The panel and frame are attached to the wall.";
      Open:
        if (Frame has general) <<Push Button>>;
      Close:
        if (self has open) {
          give self ~open;
          "You push the panel against the wall and hear a click from inside the
          frame.";
        }
        if (Frame has general)
          "The panel is already closed.";
    ],
    has
      static transparent;


! general = player has examined frame
Object -> -> Frame "brass frame"                                        ! >Frame
  class AdjObject,
  with
    adj_name 'distinctive' 'brass',
    noun_name 'frame',
    before [;
      Search, Examine:
        give self transparent;
        if (FitzAlanPanel has open)
          "The panel and frame are ajar from the wall, revealing an opening.";
        give self general;
        "The brass frame encloses the art panel. Examining it closely, you find
        a small button on the right-hand side of the panel.";
      Push, Swing, Turn:
        if (self has general) "Perhaps if you tried to do that to the button?";
        "Nothing unexpected happens.";
      LookUnder:
        <<LookUnder FitzAlanPanel>>;
      Open:
        if (self has general) <<Push Button>>;
      Close:
        <<Close FitzAlanPanel>>;
      Pull:
        <<Pull FitzAlanPanel>>;
    ],
  has
    static ~transparent;


Object -> -> -> Button "button"                                        ! >Button
  with
    name 'brass' 'button',
    description "It's a small brass button on the side of the frame.",
    before [;
      Pull:
        "Pulling on the button does nothing.";
      Push:
        if (FitzAlanPanel hasnt open) {
          give FitzAlanPanel open;
          if (self hasnt moved) {
            give self moved;
            TaskDone(TASK_FA_PANEL);
            "You push the button and hear a faint click from inside the frame.
            The panel pops ajar from the wall, revealing an opening to the
            south.";
          }
          "Pushing the button, the panel once again swings open, revealing the
          opening to the south.";
        }
        "You push the button but hear no click. Perhaps this is because the
        panel is already open?";
    ],
  has
    static;

! ---------------------------------------------------------- Crypt


Room Crypt                                                              ! >Crypt
  with
    short_name [;
      print "Main Crypt";
      if (TombEzra has general) print " (hiding)";
      rtrue;
    ],
    description [;
      print
        "The crypt stretches dimly before you, thick stone pillars supporting
        low vaulted arches. Rows of tombs line the walls; the air is thick and
        damp.";
      if (FitzAlanPanel has open)
        print
          " An opening in the north wall reveals a passage.";
      else
        print " A section of the north wall has been covered with wood planks.";

      "^^A large bell is in a stand by the stairs heading upward, and a small
      doorway is to the south.";
    ],
    u_to CryptStairs,
    n_to [;
      if (FitzAlanPanel has open) return FitzAlanCrypt;
    ],
    s_to CryptVestry,
    time_left 0,
    each_turn [;
#IfDef HAS_HINTS;
      self.time_left++;
      HintReady(Hint_Crypt);
      if (self.time_left > 4)
        HintReady(Hint_CryptEscape);
#EndIf;
    ],
    crypt_shout [;
      if (self hasnt general) {
        give self general;
        SceneCrypt.scene_start();
        "You scream loudly and hear it echo throughout the area. You feel
        certain someone above will have heard.";
      }
      "You've already shouted here, and dare not do it again.";
    ],
    before [;
      Going:
        if (selected_direction == s_to)
          print
            "You head south through the opening behind the panel,
            revealing...^";
      Smell:
        if (noun == nothing or Crypt) "Heavy, damp, and earthy.";
      Shout:
        self.crypt_shout();
        rtrue;
    ],
    cheap_scenery
      1 'doorway' [;
        Enter: <<Go FAKE_S_OBJ>>;
        default: "The doorway to the south is merely an opening in that wall.";
      ]
      4 'opening' 'passage' 'north' 'wall' [;
        Enter:
          if (FitzAlanPanel has open)
            <<Go FAKE_N_OBJ>>;
          "The panel covers the opening you entered through.";
        Examine:
          if (FitzAlanPanel has open)
            "This is the passage back to the FitzAlan crypt.";
          "The panel covers the opening you entered through.";
      ]
      CS_THEM 'pillars' 'arches' [;
        "They're part of the ceiling and far too high for you to do anything
        with them.";
      ]
      CSP_TOMBS CS_THEM 2 'tombs//p' 'crypts//p' [;
        Examine, Search:
          if (self hasnt general) {
            print "You cast your eyes over the tombs.";
            give self general;
            #IfDef HAS_QUOTES; QuoteBoxSimple(quote_crypt); #EndIf;
          }
          "There are six tombs holding the earthly remains of former priors:
          Brothers Gordian, Ezra, Crispin, Dunstan, Godric, and Ambrose.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has
    ~light convo ;


Object -> BlankPanel "wood panel"                                  ! >BlankPanel
  class AdjObject,
  with
    adj_name 'blank' 'wood',
    noun_name 'panel' 'planks',
    description [;
      print
        "This side may have once had art on it; it's impossible to tell because
        this side has been boarded over with thick planks of oak, perhaps to
        provide insulation from the now-disused family crypt";
      if (FitzAlanPanel has open)
        print ".^^The panel is ajar, revealing an opening to the north";
      ".";
    ],
    before [;
      Pull, Close:
        if (FitzAlanPanel hasnt open)
          "It already is pulled shut, and you can't pry the planks off.";
        give FitzAlanPanel ~open;
        Crypt.n_to = 0;
        "You pull the panel closed and hear a click in the frame.";
      Push, Turn:
        if (FitzAlanPanel has open)
          "The panel is already ajar.";
        "Push as you may, it doesn't open from this side.";
      Search, LookUnder:
        if (FitzAlanPanel hasnt open)
          "You find nothing interesting about the panel---other than your
          frustration that it doesn't open from this side.";
        "You find nothing unusual in the planks.";
      Take:
        if (FitzAlanPanel hasnt open)
          "You cannot pry the planks off the panel.";
    ],
  has static scenery;


Tomb -> TombGordian "Brother Gordian's tomb"                      ! >TombGordian
  with
    noun_name 'gordian' 'gordian^s' 'gordians' 'gordan' 'gordan^s' 'gordans'
        'gordianus' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    history_text [;
      TaskDone(TASK_LEARNED_FOUNDING_DATE);
      "Gordian (1112-1192). Founder of the priory in 1152, formerly Master
      Builder to the Earl of Pembroke. A man of great skill and piety, he lived
      by three great creeds that he impressed upon the brethren drawn to the new
      priory.

      ^^Gordian designed the church and Cloister himself, from the great bell in
      the tower to the stained glass of the Nave.

      ^^It is said he built the priory as penance for worldly pride, each clever
      mechanism a reminder that God's mysteries surpass man's cleverness. He
      served as prior from its founding until his death.";
    ],
  has ~enterable convo ;


Tomb -> TombEzra "Brother Ezra's tomb"                               ! >TombEzra
  with
    noun_name 'ezra' 'ezra^s' 'ezras' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    description
      "Brother Ezra's tomb is a stone block with a lid on which his name is
      carved. It sits in the dankest corner of the crypt, positioned between two
      thick pillars that cast deep shadows behind it.",
    react_before [;
      if (self hasnt general) rfalse;

      Listen, Smell, Examine, Wait, Pray, Insert, Eat, Think,
      Blow, Consult, Drink, Transfer, Look, Drop, SwitchOff, Extinguish,
      WaitHours, WaitMinutes, WaitMoves, WaitUntil:
        ;

      Go:
        print "You stand.^";
        give self ~general;
        if (selected_direction == u_to or out_to) rtrue;
        new_line;
      Exit:
        give self ~general;
        "You stand.";
      default:
        print "(To do so, you get up from crouching)^";
        give self ~general;
    ],
    before [;
      Hide:
        if (self has general) "You are already crouching down and hiding.";
        give TombEzra general;  ! hidden
        "You crouch far down on the darkest side of ", (the) self, ".";
    ],
    history_text
      "Ezra (1155-1212). Elected as the second prior in 1192 and served in this
      role for 18 years. He built out the Infirmary and the Infirmary Chapel and
      opened the priory to religious pilgrims travelling to Wales. Contemporary
      brothers remembered him for his flaming orange hair and for his bravery:
      he always said he would protect his brethren from danger to his very
      limits.",
  has ~enterable  ;


Tomb -> TombCrispin "Brother Crispin's tomb"                      ! >TombCrispin
  with
    noun_name
      'crispin' 'crispin^s' 'crispins' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    history_text
      "Crispin (1180-1248). Gained renown in the Holy Land as a young man, then
      took his vows and joined the priory. The second-longest serving prior
      (1210-1248), he brought many benefactors and the priory saw many pilgrims
      pass through hoping to meet the man who had taken the cross with such
      honour.",
  has ~enterable ;


Tomb -> TombDunstane "Brother Dunstan's tomb"                    ! >TombDunstane
  with
    noun_name
      'dunstan' 'dunstan^s' 'dunstans' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    history_text
      "Dunstan (1210-1270). Entered the priory from a trading family in
      Pembroke. Elected prior in 1248, after the death of Prior Crispin, he
      served for 22 years until his death. The latter half of his time as prior
      was marred by the start of the Second Baron's War and a decline in the
      prestige of the priory.",
  has ~enterable ;


Tomb -> TombGodric "Brother Godric's tomb"                         ! >TombGodric
  with
    noun_name
      'godric' 'godric^s' 'godrics' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    history_text
      "Godric (1230-1299). Entered the priory as a child and was raised in its
      confines. Known best for his singing voice, he was the cantor from his
      early twenties, and was elected prior at only 40. He served in this role
      for 25 years (1270-1295), stepping down only a few years before his
      death.",
  has ~enterable ;


Tomb -> TombAmbrose "Brother Ambrose's tomb"                      ! >TombAmbrose
  with
    noun_name
      'ambrose' 'ambrose^s' 'ambroses' 'tomb' 'crypt' 'tombs//p' 'crypts//p',
    history_text
      "Ambrose (1255-1310). After losing two brothers in the civil wars, Ambrose
      took his vows at twenty. He was elected as prior and served 1295-1310.
      During his administration, he emphasised the importance of silence, and
      began the tradition of total silence throughout the grounds except in very
      limited circumstances. It is said that, in addition to his offices, he
      spent several hours daily silently praying in memory of his lost
      brothers.",
  has ~enterable ;


! general = rung and in the sequence for rescue

Object -> CryptBell "crypt bell"                                    ! >CryptBell
  class AdjObject,
  with
    adj_name 'crypt' 'pewter',
    noun_name 'bell',
    description
      "A large bell in a stand, both made of pewter. You've heard it once rung
      during a Mass in the crypt, and it was loud enough that you heard it on
      the Cloister.",
    before [;
      Turn, Pull, Attack, Push:
        if (self has general)
          "You've already rang it, and dare not do it again.";
        SceneCrypt.scene_start();
        give self general;
        "You sound it with vigour which produces an almost deafening peal as it
        echoes. You feel certain someone above will have heard that.";
      Take: "It's far too heavy to move.";
    ]
  has scenery;


! -------------------------------------------------------- Crypt Vestry

Room CryptVestry "Crypt Vestry"                                   ! >CryptVestry
  with
    name 'crypt' 'vestry',
    description
      "The Crypt Vestry is a long passage of rough stone. This may have
      originally been designed to be another crypt, but it is used to store
      materials needed for masses held in the crypt, and there are some such
      things on a ledge. The room is very infrequently used, since such masses
      are quite rare.

      ^^The only exit out is the way you came.",
    n_to Crypt,
    out_to Crypt,
    before [;
      Smell:
        if (noun == nothing) "Heavy, damp, and earthy.";
    ],
    cheap_scenery
      CS_THEM 'items' 'things' [;
        Examine, Search: <<Search VestryLedge>>;
      ]
      CS_THEM 11 'pewter' 'platters' [;
        Examine: "These are heavy and simply made.";
        default: "Leave the platters be.";
      ]
      1 'cup' [;
        Examine: "A simple vessel for water and wine in services.";
        default: "Leave the cup be.";
      ]
      CS_THEM 1 'materials'
        "The materials are on the ledge. You could examine that."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has
    ~light;


Object -> VestryLedge "ledge"                                     ! >VestryLedge
  with
    name 'ledge' 'shelf' 'plank',
    inside_description
      "From your vantage on the ledge, you see nothing further here, and
      nothing unexpected about the stone above.",
    description
      "It's a thick plank fastened to the wall. It contains several items,
      likely needed for services held down here.",
    react_before [;
      Go:
        if (player in self && selected_direction == d_to) <<Exit self>>;
    ],
    before [;
      Climb: <<Enter self>>;
      Search:
        print
          "Searching around, you find some pewter platters, a cup, and some old
          cloth";
        PrintContents(". Also on it ", self, ISARE_BIT);
        ".";
      Pull, Turn, Push:
        "It's firmly attached to the wall.";
    ],
    after [;
      Enter: "With some difficulty you climb onto the shelf.";
      Exit: "You scramble back down from the ledge.";
    ],
  has
    scenery
    enterable
    supporter ;


Object -> -> OldCloths "old cloths"
  with
    parse_name [ w1 w2 w3 w4 ;
      w1 = NextWord();
      w2 = NextWord();
      w3 = NextWord();
      w4 = NextWord();
      if (w1 == 'cloths' or 'cloth') { return 1; }
      if (w1 == 'old' && w2 == 'cloths' or 'cloth') { return 2; }
      if (w1 == 'cloth' or 'cloths' && w2 == 'pile') { return 2; }
      if (w1 == 'pile') {
        if (w2 == 0) { return 1; }
        if (w2 == 'cloths' or 'cloth') { return 2; }
        if (w2 == 'of' && w3 == 'cloths' or 'cloth') { return 3; }
        if (w2 == 'of' && w3 == 'old' && w4 == 'cloths' or 'cloth') return 4;
      }
    ],
    article "a pile of",
    description
      "They have clearly been here for years, as they are mouldy from the
      damp.",
    before [;
      Search, LookUnder:
        if (self hasnt general) {
          give Coins ~concealed;
          give self general;
          ! move Coins to location;
          itobj = Coins;
          "Aha! While the cloths are rotting and ruined, under them, you find a
          sack.";
        }
        "There is nothing else hidden in the cloths.";
      Smell:
        "Mould. You wince.";
      Taste:
        "You dare not.";
      Take:
        if (self hasnt general) {
          give Coins ~concealed;
          give self general;
          ! move Coins to location;
          itobj = Coins;
          "As you start to gather them, you find that under them was a sack. You
          decide against taking the rotting cloths.";
        }
        "Given their condition, you fear mould spreading. You decide not to take
        them.";
    ]
  has
    pluralname concealed;


Object -> -> Coins "sack"                                               ! >Coins
  with
    short_name [;
      print "sack";
      if (self has moved) print " of coins";
      rtrue;
    ],
    initial "Now prominent on the ledge is a sack.",
    parse_name [ w1 w2 w3 w4 ;
      w1 = NextWord();

      if (self hasnt general) {
        if (w1 == 'sack') return 1; return 0;
      }

      w2 = NextWord();
      w3 = NextWord();
      w4 = NextWord();

      ! print "DEBUG coins=", (address) w1, " ", w2, "^";

      if (w1 == 'sack') {
        if (w2 == 0) return 1;
        if (w2 == 'of' && w3 == 'silver' && w4 == 'coins') return 4;
        if (w2 == 'of' && w3 == 'coin' or 'silver' or 'coins') return 3;
        return 1;
      }
      if (w1 == 'coin' && w2 == 'sack') return 2;
      if (w1 == 'coin' or 'coins' or 'silver') return 1;
      return 0;
    ],
    description [;
      themobj = self;
      print
        "The sack is dark burlap, smeared with yellow powder, tied with
        simple cord";
      if (self hasnt general) {
        ev_coins = true;
        give self general;
        ". Opening it, your hands tremble: the weight is unmistakable. Silver
        coins spill into view: groats and pennies, perhaps ten shillings' worth.

        ^^Your breath catches. A small fortune, enough to feed the priory for a
        season. Hidden here, among the dead, where none have need of it.";
      }
      else
        ", heavy with silver coins.";
    ],
    before [;
      Empty:
        "The coins are evidence. Best to leave them in the sack.";
      Taste:
        "You dare not lick the sack or coins---but perhaps you could try to
        taste the powder?";
      Receive:
        "There's no room for anything else.";
      Close:
        "It's already tied closed.";
      Examine:
        if (ImplicitGrabIfNotHeld(self)) rtrue;
      Open:
        if (ImplicitGrabIfNotHeld(self)) rtrue;
        if (self hasnt general) <<Examine self>>;
        "You loosen the cord, check the contents---still silver---and tie it
        closed again. The sight of such wealth still unsettles you.";
      Search:
        if (ImplicitGrabIfNotHeld(self)) rtrue;
        if (self hasnt general) <<Examine self>>;
        "The sack contains only the coins. More money than you've ever held.";
      Take:
        if (self in player) {
          print "You already have the sack";
          wn = verb_wordnum + 1;
          if (NextWord() == 'coin' or 'coins') print ". Leave the coins in it";
          ".";
        }
      Smell:
        "There are several competing scents: metallic, mouldy, and also sharp,
        like a spice.";
    ],
    after [;
      Take:
        if (self has moved) rfalse;
        if (self has general)
          "You take the sack, trying to ignore how the coins shift and clink.
          Your vow of poverty weighs heavier than the silver.";
        print "You take it, noting metallic clinking as you do.^";
        if (input_action ~= ##Take) new_line;
        rtrue;
    ],
  has evidence convo concealed transparent ;


Object -> -> -> SackPowder "yellow powder"
  class AdjObject,
  with
    adj_name 'yellow',
    noun_name 'powder',
    description
      "The yellow powder is almost a stain, as if it were finely ground.",
    before [;
      Take, Rub: "You can't get the powder stains off this.";
      Smell, Taste: "You can't place it, but it's sharp, like a spice.";
      Touch: "It's very finely ground.";
      LookUnder: "The only thing under the powder is the sack itself.";
    ]
  ;


! ============================================== Second Floor

Room DayStairs "Day Stairs"                                         ! >DayStairs
  with
    name 'day' 'stairs',
    description
      "You're in the middle of a set of broad stone steps. The steps dip in the
      centre from generations of sandaled feet. This staircase is used by you
      and the brethren to travel between the Cloister and the dorters above when
      there's enough light and warmth to use outdoor stairs.

      ^^Above is the upper living areas and below is the Cloister walk.",
    d_to CloisterNE,
    u_to Hall,
    toward_slype d_to,
    cheap_scenery
      CS_THEM 13 'broad' 'stone' 'steps' 'stairs'
        "The steps are carved stone and unremarkable."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_exposed)
    ,
  has ;

! ---------------------------------------------------- Hall

Room Hall "Hall"                                                   ! >Hall
  with
    name 'hall' 'corridor' 'passages',
    description
      "This plain corridor connects the two dorters. Wooden floorboards creak
      underfoot. There are passages to the north, south, and east. Broad stairs
      lead down to the Cloister.",
    n_to Dorter,
    s_to LayDorter,
    d_to DayStairs,
    e_to Necessarium,
    toward_slype d_to,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_Hall); #EndIf;
    ],
    cheap_scenery
      CS_THEM 11 'wooden' 'floorboards' "There's nothing special about them."
      CS_THEM 'dorter' 'dorters' [;
        "There are two ~dorters~ (dormitories), the larger, to the north, for
        choir monks; the smaller, to the south, for lay monks.";
      ]
      CS_THEM 11 'broad' 'stairs' [;
        Enter: <<Go FAKE_D_OBJ>>;
        default:
          "These stairs are the Day Stairs, and lead down toward the Cloister.";
      ]
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
    before [;
      Go:
        if (selected_direction == d_to && g_current_service == SceneMatins)
          "You shouldn't be exploring the priory now. You should go down the
          Night Stairs from your Dorter to join the office.";
    ],
  has ;

! --------------------------------------------------- Dorter

Room Dorter "Dorter"                                                   ! >Dorter
  with
    description [;
      ! On first turn of game, don't overwhelm player with room description
      if (turns == -1) {
        "^There are several of your fellow monks here---Brothers Benedict, Hugh
        and Anselm---along with your mentor, Brother Aelred.";
      }

      "This great room is used by all of the choir monks except the prior,
      Brother Oswald. It could easily provide rest for twenty brothers, but
      there are only eight cots in here now. Each cot has a chest at its foot
      for any meagre possessions the brother has.

      ^^A window high up reflects @(DS_LIGHT) on the floor.

      ^^A doorway leads south to the Hall. Narrow stairs descend to the Quire,
      where offices are held.";
    ],
    d_to NightStairs,
    s_to Hall,
    toward_slype d_to,
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_dorters); #EndIf;
    ],
    before [;
      Smell:
        if (noun == nothing)
          "The room smells of wool and straw, of tallow and cold stone. It is
          the smell of a life stripped of comfort.";
    ],
    cs_more
      44
        'brother' 'oswald' 'oswald^s' 'oswalds' 'chest' 'box' 'cot' 'bed' [;
        "Brother Oswald has neither cot or chest here; as the prior, he has
        separate living quarters.";
      ]
      44 'brother' 'remigio' 'remigio^s' 'remigios' 'chest' 'box' 'cot' 'bed'
      [;
        "Brother Remigio has neither cot nor chest here; as a lay monk, he
        quarters in the Lay Dorter.";
      ]
      'window' 'windows'
        [;
          Examine:
            "An unglazed opening in the stone wall, high above you.";
          default: "The window is too high to do anything with it.";
        ]
      'hall' 'doorway' [;
        Examine: "The doorway leads to the Hall, to the south.";
        Enter: <<Go FAKE_S_OBJ>>;
      ]
    ,
    cheap_scenery
      1 'quire' [;
        "The Quire is the room below, where you and your brothers perform your
        offices.";
      ]
      1 'dorter' LookInstead
      11 'narrow' 'stairs'
        "These stone stairs lead down to the church below."
      CS_THEM 'wool' 'straw' "Wool and straw are just parts of the cots."
      1 'tallow' [;
        Examine, Smell:
        "On moonless nights, there is often a tallow candle. There is none here
        now.";
      ]
      11 'cold' 'stone' "The stone is rough and not finished."
      CS_ADD_LIST Dorter (cs_more)
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has ;


!-------------------------------------- Cots

Object -> Cots "cots"
  with
    parse_name [ ;
      if (action ~= ##Examine or ##Search or ##LookUnder) return 0;
      if (NextWord() == 'cots//p' or 'beds//p' or 'mattresses//p') return 1;
      return 0;
    ],
    description
      "Thin straw mattresses on wooden frames, one for each brother.
      Comfort is not the point.",
    before [;
      Search: "You see nothing on any of the cots.";
      LookUnder: "You look under the cots and find nothing.";
    ]
  has
    concealed scenery pluralname;


Cot -> BrAelredCot "Brother Aelred's cot"
  with
    adj_name 'brother' 'aelred' 'aelred^s' 'aelreds' ;

Cot -> BrAnselmCot "Brother Anselm's cot"
  with
    adj_name 'brother' 'anselm' 'anselms' 'anselm^s' ;

Cot -> BrBenedictCot "Brother Benedict's cot"
  with
    adj_name 'brother' 'benedict' 'benedict^s' 'benedicts' ;

Cot -> BrHughCot "Brother Hugh's cot"
  with
    adj_name 'brother''hugh' 'hughs' 'hugh^s' ;

Cot -> BrMartinCot "Brother Martin's cot"
  with
    adj_name 'brother' 'martin' 'martin^s' 'martins' ;

Cot -> BrCuthbertCot "Brother Cuthbert's cot"
  with
    adj_name 'brother' 'cuthbert' 'cuthberts' 'cuthbert^s' ;

Cot -> BrWilfredCot "Brother Wilfred's cot"
  with
    adj_name 'brother' 'wilfred' 'wilfred^s' 'wilfreds',
    before [;
      Smell: "It smells a bit like rosemary. He must keep some around.";
    ],
  ;

Cot -> BrAldwinCot "your cot"
  with
    adj_name 'brother' 'your' 'mine' 'my' 'aldwin' 'aldwin^s' 'aldwins',
    react_before [;
      Go:
        if (player in self) {
          print "(first getting up from your cot)^";
          move player to location;
        }
    ],
    before [;
      Search, LookUnder:
        "There is nothing on or below your cot.";
      Enter, LieOn:
        "The Rule discourages sloth. You've already risen for the day.";
      Kneel:
        move player to location;
        "You kneel on your cot for a moment, and then rise.";
    ],
    after [;
      Exit: "You leave your cot.";
    ],
;

!-------------------------------------- Chests

Object -> Chests "chests"                                              ! >Chests
  with
    parse_name [;
      if (action ~= ##Examine) return 0;
      if (NextWord() == 'chests//p' or 'boxes//p') return 1;
      return 0;
    ],
    description "The chests are simple wooden boxes with lids.",
  has
    concealed scenery pluralname;

Chest -> BrAelredChest "Brother Aelred's chest"                   ! >ChestAelred
  with adj_name 'brother' 'aelred' 'aelred^s' 'aelreds';

Chest -> BrAnselmChest "Brother Anselm's chest"                   ! >ChestAnselm
  with adj_name 'brother' 'anselm' 'anselms' 'anselm^s';

Chest -> BrBenedictChest "Brother Benedict's chest"             ! >ChestBenedict
  with adj_name 'brother' 'benedict' 'benedicts' 'benedict^s';

Chest -> BrCuthbertChest "Brother Cuthbert's chest"
 with adj_name 'brother' 'cuthbert' 'cuthbert^s' 'cuthberts';

Chest -> BrHughChest "Brother Hugh's chest"
  with adj_name 'brother' 'hugh' 'hughs' 'hugh^s';

Chest -> BrMartinChest "Brother Martin's chest"                   ! >ChestMartin
  with adj_name 'brother' 'martin' 'martins' 'martin^s';

Chest -> BrWilfredChest  "Brother Wilfred's chest"               ! >ChestWilfred
  with adj_name 'brother' 'wilfred' 'wilfreds' 'wilfred^s';

Chest -> MyChest "your chest"                                    ! >MyChest
  with
    adj_name 'brother' 'your' 'mine' 'my' 'aldwin' 'aldwins' 'aldwin^s',
    description [;
      print
        "Your chest is like all of the other brothers' chests: A simple wooden
        box with a lid";
      if (self has open) print ". It is open";
      ".";
    ],
  ;

!-------------------------------------- Chest contents

Object Rosary "rosary" BrBenedictChest                                 ! >Rosary
  with
    name 'rosary',
    description
      "A set of plain beads strung together. You've seen the brother carry them
      around at times.",
    before [;
      Attack, Cut:
        "Destroying another's property isn't something you'd consider.";
    ],
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
  ],
  has ;


Object Sketch "sketch" BrWilfredChest                                          ! >Sketch
  with
    name 'drawing' 'sketch',
    description
      "A fine ink sketch of the priory entrance, showing the artistry of the
      masonry and the door carving. You recognise Brother Wilfred's distinctive
      style.",
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ],
  has ;


Object Seashell "seashell" BrAnselmChest                                   ! >Seashell
  class AdjObject,
  with
    adj_name 'sea' 'scallop',
    noun_name 'seashell' 'shell',
    description
      "A perfectly-shaped scallop shell, perhaps kept as a badge of a
      pilgrimage.",
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ],
  has ;


Object Comb "comb" BrCuthbertChest                                      !> Comb
  with
    name 'comb',
    description
      "A plain wooden comb. You're surprised that Brother Cuthbert has this,
      given how he's lectured you about the evils of vanity.",
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
  ],
;


Object Letters "letters" BrHughChest                                  ! >Letters
  class AdjObject,
  with
    adj_name 'rose' 'hugh' 'rose^s' 'hugh^s',
    noun_name 'letters' 'letter',
    description "A pair of letters on rough, cheap paper.",
    invent [;
      print "some letters";
      if (self has general) print " from Rose";
      rtrue;
    ],
    before [;
      Examine:
        if (verb_word ~= 'read') rfalse;
        ImplicitGrabIfNotHeld(Letters);
        ev_rose_letters = true;
        give self general;
        print "The first letter reads:^^";

        @set_text_style 4;
        print
          "Dearest Brother Hugh,

          ^^I write to you in desperation, though it shames me to beg. The
          harvest failed again this year, and what little we had has gone to the
          lord's rent. My William can barely stand now---his leg has worsened
          terribly since Candlemas. The wound festers and will not heal.

          ^^It must be cut, else the poison will spread to his heart. There is a
          surgeon in Norwich, but the cost---Hugh, it is three shillings. We
          have not three pence.

          ^^I have sold all I can: the good kettle, even the winter blankets.

          ^^I know the Rule forbids monks from keeping wealth. I know you have
          given all to God. But if there is any way, any kindness you might ask
          of your abbot, any alms the monastery might spare for Christian
          charity. My William will die without it.

          ^^Your sister in Christ and in blood, ^Rose";
        style roman;

        print "^^The second letter reads:^^";

        @set_text_style 4;
        print
          "Dearest Hugh,

          ^^May God bless you a thousand times for your mercy. The two shillings
          came just as William could no longer rise from bed.

          ^^We took William to the surgeon. He cut the leg below the knee. It
          was terrible, Hugh, but necessary. William lives, praise God, though
          he is weak yet.

          ^^But the surgeon demands another shilling and sixpence still owed. He
          will not wait past Michaelmas. And now William cannot work at all---he
          who used to haul timber is now fit only to sit and weave baskets, if
          his strength returns.

          ^^I hate to ask again after your generosity. The shame burns in me.
          But Hugh, they will take our cottage for the debt. We have nowhere.
          Starvation comes.

          ^^If there is anything more you can do---any favour you might ask---I
          swear by Our Lady I will never ask again. One more shilling would save
          us.

          ^^Your grateful sister, ^Rose";
        style roman;
        "";
    ],
  has
    pluralname evidence convo ;


! ---------------------------------------------------- Night Stairs


Room NightStairs "Night Stairs"                                   ! >NightStairs
  with
    description
      "Midway on the narrow stone stairs connecting the Dorter to the Quire.
      These are the Night Stairs: three times each night, monks file down in
      darkness for Matins, Lauds, and Prime. The walls are close, the air
      still.^^

      A lone candle flickers in its niche.",
    d_to Quire,
    u_to Dorter,
    toward_slype d_to,
    cheap_scenery
      CS_PARSE_NAME [;
        if (NextWord() == 'night' && NextWord() == 'stairs') return 2;
      ] LookInstead
      1 'quire' [;
        Enter: <<Go FAKE_D_OBJ>>;
        default: "The ~Quire~ is the room below.";
      ]
      1 'dorter' [;
        Enter: <<Go FAKE_U_OBJ>>;
        default: "The ~Dorter~ is the room above.";
      ]
      1 'sconce' "The sconce is built into the wall."
      1 'niche' [;
        "The only thing in this is the candle, and there's room for nothing
        else.";
      ]
      CS_THEM 22 'narrow' 'stone' 'steps' 'stairs'
        "There is nothing unusual about the stairs."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
    before [;
      Smell:
        if (noun == nothing) <<Smell TimeCandle>>;
    ]
  has ~light ;


Candle -> TimeCandle "canonical hour candle"                       ! >TimeCandle
  with
    name 'canonical' 'hour' 'time' 'lone' 'candle',
    describe 0,
    initial
      "A lit candle sits in a sconce built into the stone wall.",
    description [ hour ;
      g_last_accurate_time = turns;
      hour = the_time / 60;
      print
        "This candle is a ~canonical hour candle~. It is used by ",
        (The) BrCuthbert, " to tell the hours for offices and when to ring the
        great bell. ";

      "It has burned down past ", hour, " marks, leaving ", 24 - hour, " marks
      remaining below the flame. From it, you estimate the time as ",
      (SundialTime) the_time, ".";
    ],
    before [;
      Extinguish:
        "You'd best not extinguish the time candle: the whole community depends
        on it for keeping the hours.";
      Take:
        if (f_found_darkness)
          print "You now know how useful a candle would be---but ";
        print
          (The) BrCuthbert, " would be very annoyed if this disappeared, and if
          you were suspected, you'd have heavy penance. ";
        if (f_found_darkness)
          "You'll have to find another source of light than this.";
        "You think better of this act.";
      Pull: <<Take self>>;
      Push: "It's already firmly seated in the sconce.";
      Touch: "Ouch. Quite warm.";
      Smell: "There's an unpleasant aroma of burning tallow from the candle.";
      Turn: "You turn the candle pointlessly in the sconce.";
      Taste: "For some reason, you lick it. It is unpleasant and fatty.";
      LookUnder: "There is nothing else in the niche.";
    ]
  has
    static light;

! ---------------------------------------------------- Necessarium

Room Necessarium "Necessarium"                                  ! >Necessarium
  with
    name 'necessarium',
    description
      "This narrow chamber extends from the Hall. A wooden bench with several
      latrine holes runs along one wall, each opening onto the dung pit far
      below. The smell is overpowering. Cold, foul air rises from the pit. The
      only exit is out to the west.",
    w_to Hall,
    out_to Hall,
    toward_slype w_to,
    before [;
      Smell, Taste: "In this foul place, you dare not.";
      Climb:
        if (selected_direction == d_to)
          "You wouldn't fit in a latrine hole, praise be.";
    ],
    on_first_entry [;
      #IfDef HAS_HINTS; HintReady(Hint_Nec); #EndIf;
    ],
    cheap_scenery
      'dung' 'pit' "Happily, you can only barely see it from up here."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has
    ;


Object -> Latrines "latrines"                                      ! >Latrines
  class AdjObject,
  with
    adj_name 'wooden',
    noun_name 'bench' 'latrine' 'latrines' 'hole' 'holes',
    describe
      "The bench is a wooden box with holes cut into it.",
    before [;
      Enter:
        "You don't need to use the latrines just now.";
      Search, LookUnder:
        "Even if you could see anything far down in the pit, you wouldn't want
        to.";
    ],
    after [;
      Receive:
        remove noun;
        "You drop ", (the) noun, " in ", (the) self,
        ", losing it in the filth far below.";
    ]
  has
    pluralname scenery container open;


! ---------------------------------------------------- LayDorter

Room LayDorter "Lay Dorter"                                 ! >LayDorter
  with
    name 'lay' 'dorter',
    description [;
      print
        "This chamber was built to house the lay brothers, those who serve
        without taking full vows. The walls are marked with darker patches where
        other cots once stood, and you can see the worn floorboards where chests
        were dragged back and forth over the years. Now the room holds only
        Brother Remigio's single cot and chest, pushed against a far wall.";

      if (self hasnt visited)
        print
          " The priory's decline is nowhere more visible than in this emptiness,
          this quiet room that once held the sounds of simple men at their
          evening prayers.";

      "^^The only exit is north to the Hall.";
    ],
    n_to Hall,
    out_to Hall,
    toward_slype n_to,
    before [;
      Listen:
        if (noun == nothing) "The room is eerily silent.";
    ],
    cheap_scenery
      CS_THEM 11 'darker' 'patches' [; "These are just marks on the wall."; ]
      CS_THEM 11 'worn' 'floorboards'
        "The floorboards reveal nothing special."
      CS_ADD_LIST Core (cs_church)
      CS_ADD_LIST Core (cs_indoor)
    ,
  has
    light;


Chest -> BrRemigioChest "Brother Remigio's chest"                ! >ChestRemigio
  with adj_name 'brother' 'remigio' 'remigios' 'remigio^s';


Object -> -> PilgrimBadge "pilgrim badge"
  with
    name 'pilgrim' 'badge' 'pewter',
    description
      "A small badge, cheaply cast in pewter but carefully kept. It depicts a
      figure in a monk's robe: St Francis of Assisi, you think, given the birds
      around him. The kind of thing sold to pilgrims at a shrine. How it ended
      up in an English priory, in the chest of a Tuscan lay brother, is a story
      you will never fully know.",
    after [;
      Take:
        if (self hasnt moved)
          print_ret (string) theft_messages-->(random(theft_messages-->0));
    ],
  has  ;


Cot -> BrRemigioCot "Brother Remigio's cot"
  with
    adj_name 'brother' 'remigio' 'remigios' 'remigio^s',
  ;


Object -> LayCots
  with
    name 'cots' 'mattresses' 'beds',
    before [;
      meta = 1;
      "[There is only one cot here: Brother Remigio's.]";
    ]
  has scenery concealed ;


!===============================================================================
!========================================================================== Game


[ Initialise o ;
  if (false) o = o; ! silences warning and emits no code (is optimized away)

  #IfNDef DEBUG;
    print
      "Even if you've played other interactive fiction before, you should read
      the help. There are game-specific commands.

      ^^Would you like to read that (y/n)? ";
    if (YesOrNo()) {
      <Help>;
      print
        "^You can always re-read that with ~HELP~.

        ^^Press ENTER to continue > ";
      _ReadPlayerInput(true, true);
    }
  #EndIf;

  ClearScreen();

  #IfDef DEBUG;
    <RandomSeed 100>;
    #IfDef FULL_DEBUG;
      print "^*** FULL DEBUGGING MODE^";
    #IfNot;
      print "^*** PLAYTESTING MODE^";
      ! <ScriptOn>;
    #EndIf;
  #EndIf;

  #IfDef HAS_QUOTES; QuoteBoxSimple(quote_opening); #EndIf;
  SetTime(SceneMatins.time_start, 1);
  lookmode = 2;  ! verbose mode by default

  ! Make these concealed so we can have a customized first-round message.
  ! Then they'll be unconcealed.
  move BrAelred to Dorter;
  give BrAelred concealed;
  move BrHugh to Dorter;
  give BrHugh concealed;
  move BrBenedict to Dorter;
  give BrBenedict concealed;
  move BrAnselm to Dorter;
  give BrAnselm concealed;

  ! just so they don't all arrive at once, making a long list of text
  move BrMartin to Hall;
  move BrWilfred to Hall;

  ! Starting other places
  move BrRemigio to LayDorter;
  move BrCuthbert to BellTower;
  move BrOswald to PriorsSolar;

  print
    "^^Early autumn, 1346:

    ^^The great bell strikes, bolting you out of sleep. One peal---Matins, first
    of the eight daily offices. Two in the morning, and the wind off the Channel
    coast has found every gap in the Dorter walls.

    ^^You lie in your cot still in your habit, as the monks of the priory of Our
    Lady of Thorns must attend office below without delay. Five months a novice
    here, and still you have not yet made peace with the schedule.^^";

#IfDef HAS_HINTS;
  objectloop(o ofclass Option) {
    if (o provides in_menu && o.in_menu == HintGeneral) {
      HintReady(o);
    }
  }
#EndIf;

  SceneMatins.scene_start();

  ! convenience since he's the most likely to notice
  himobj = BrAelred;

  DescribeLight();

  ! Don't print the banner at start; print it after first office
  return 2;
];


! add this object so can add to darkness w/o an InScope fn & call
!
Object Dark thedark
  with
    add_to_scope [;
      if (scope_reason ~= PARSING_REASON or TESTSCOPE_REASON) rfalse;

      if (real_location == Sacristy) {
        PlaceInScope(SacristyDoor);  ! so we can find door
        PlaceInScope(Sacristy);      ! so room actions, like smell, work
      }
      if (real_location == Crypt) {
        ! Otherwise, player can't turn-off-light and then hide or ring bell.
        PlaceInScope(CryptBell);
        PlaceInScope(TombEzra);
        PlaceInScope(TombAmbrose);
        PlaceInScope(TombCrispin);
        PlaceInScope(TombDunstane);
        PlaceInScope(TombGodric);
        PlaceInScope(TombGordian);
        PlaceInScope(BlankPanel);
      }
      if (real_location == FitzAlanCrypt) {
        PlaceInScope(FitzAlanPanel);
        PlaceInScope(Frame);
        PlaceInScope(Button);
      }
    ],
  has scenery concealed ;



!===============================================================================
!====================================================================== Routines


!--------------------------------------  Printing Routines

[ bd s;
  style bold;
  print (string) s;
  style roman;
];


[ ital s;
  @set_text_style 4;
  print (string) s;
  style roman;
];


[ mono s;
  font off;
  print (string) s;
  font on;
];


[ HisHerTheir o;
  if (o has pluralname or neuter) print "their";
  else if (o hasnt animate) print "its";
  else if (o has female) print "her";
  else print "his";
];

! This what "TIME" command uses, player's built-in sense

[ ReallyRoughTime mins hour ;
  mins = the_time % 60;
  hour = the_time / 60;

  if (mins >=20 && mins <= 40) print "half past ";
  else if (mins >=8 && mins < 20) print "past ";
  else if (mins >40 && mins < 50) { print "approaching "; hour++; }
  else if (mins >= 50) { hour++; }
  if (hour == 12) { print "noon"; rtrue ; }
  print (LanguageNumber) hour % 12, " in the ";
  if (hour < 12) print "morning";
  else if (hour > 17) print "evening";
  else print "afternoon";
];


!-------------------------------------- Fixing Pronoun Handling

! PunyInform doesn't do any automatic pronoun setting, so this is a crude
! version:
!
! - figure out if the current object is in scope; if not, set the
!   f_set_himobj flag (or her,it,etc); FixPronouns will pick something
!   suitable.
! - overall strategy: if the previous object still in scope, keep it ---
!   this way "X KNIFE. GET IT." will always be the knife.

[ CheckPronouns ;
  f_set_himobj = ~~TestScope(himobj);
  f_set_herobj = ~~TestScope(herobj);
  f_set_themobj = ~~TestScope(themobj);
  f_set_itobj = ~~TestScope(itobj);
  LoopOverScope(FixPronouns);
  if (f_set_himobj) { himobj = 0; }
  if (f_set_herobj) { herobj = 0; }
  if (f_set_themobj) { themobj = 0; }
  if (f_set_itobj) { itobj = 0; }
];


[ FixPronouns o ;
  ! always prefer BrAelred body in the chapel, so its doesn't default to St
  ! Roch
  if (f_set_himobj && location == InfirmaryChapel) {
    himobj = BrAelredBody;
    f_set_himobj = false;
  }

  ! throw out hidden things or scenery from consideration.
  ! if an object is in/on a container/supporter, don't pick them as the
  ! new default object ("there is an altar with a knife on it" should never
  ! default to the knife as being the itobj)
  if (
    o has concealed or scenery
    || o == player
    || parent(o) ~= location or Stalls)
    rfalse;

  ! Be careful reusing this --- the game it was written for has no "neuter"
  ! animate, nor does it have pluralname animates.

  if (f_set_herobj && o has animate && o has female) {
    herobj = o;
    f_set_herobj = false;
  }

  else if (f_set_himobj && o has animate && o hasnt female) {
    himobj = o;
    f_set_himobj = false;
  }

  else if (f_set_themobj && o has pluralname) {
    themobj = o;
    f_set_themobj = false;
  }

  else if (f_set_itobj && o hasnt animate && o hasnt pluralname) {
    itobj = o;
    f_set_itobj = false;
  }
];


!-------------------------------------- General routines

[ StoryPause key ;
  print "^     ----------------------- && -----------------------";
  if (0->$1F ~= 'z' && ~~xcommsdir) { print " "; @read_char 1 -> key; }
  new_line;
];


Array array_exits_check static -> n_to s_to w_to e_to u_to d_to ;

[ PrintExits join_with i count found o;

  for (i = 0 : i < 6 : i++) {
    o = location.(array_exits_check->i);
    if (metaclass(o) == Object || (metaclass(o) == Routine && o()))
      count++;
  }
  if (count == 0) { print "(none)"; return; }
  found = count;

  for (i = 0 : i < 6 : i++) {
    o = location.(array_exits_check->i);
    if (metaclass(o) == Object || (metaclass(o) == Routine && o())) {
      print (DirName) array_exits_check->i;
      if (count > 2) { print ", "; }
      else if (count == 2) {
        if (found > 2) print ",";
        print " ", (string) join_with, " ";
      }
      count--;
    }
  }
];


[ AskFail;
  if (~~f_gave_hint_about_ask_re_brothers) {
    f_gave_hint_about_ask_re_brothers = true;
    "^[There are other things you can ask, but one good idea is to ask the
    brothers about each other.]";
  }
];


[ ShouldNotGoNow loc monk ;
  "You shouldn't go to ", (the) loc, " now. ", (the) monk, " will be there and
  will report you for not working in the Garden with Brother Aelred.";
];


! Wrapper for Achieved; allows for debugging
[ TaskDone t ;
  #IfDef FULL_DEBUG;
    if (task_done->t == 0) print "^*** DEBUG: task: ", (PrintTaskName) t;
  #EndIf;
  Achieved(t);
];


[ ClimbDownFirst o ;
  "You'd have to climb down from ", (the) o, " first.";
];


[ IsCarryingLit obj;
  obj = child(player);
  while (obj ~= 0) {
    if (obj has light) return true;
    obj = sibling(obj);
  }
  return false;
];


! Called because entered
! dark room or room become dark (ie, Sacristy door closed)

[ NowInDark ;
  if (f_been_in_dark == false) {
    #IfDef HAS_QUOTES; QuoteBoxSimple(quote_darkness); #EndIf;
    f_been_in_dark = true;
  }
];


[ PropToDir prop;
  if (prop == n_to) return FAKE_N_OBJ;
  if (prop == s_to) return FAKE_S_OBJ;
  if (prop == e_to) return FAKE_E_OBJ;
  if (prop == w_to) return FAKE_W_OBJ;
  if (prop == u_to) return FAKE_U_OBJ;
  if (prop == d_to) return FAKE_D_OBJ;
  print "NOPE";
  return nothing;
];


[ KillOff time;
  if (~~time) time = 7;
  print
    "^^For violating a serious rule of the priory, you are sentenced to bread
    and water for ", (LanguageNumber) time, " days. By the time your penance
    ends, any chance of solving any mystery has long passed.";
  deadflag = DEAD_FAILED;
];


[ MurderWord w;
  return w ==
      'murder' or 'poison' or 'poisoning' or 'death' or 'killer' or 'murderer'
      or 'smell' or 'autopsy' or 'corpse' or 'body';
];


[ DieIfToxic ate ;
  if (self hasnt toxic) rfalse;
  deadflag = DEAD_ILL;
  print
    "Foolishly, you decide to eat ", (the) ate, ". You spend several days in the
    Infirmary. Any chance you had of solving Brother Aelred's murder passed.";
];


! Used for things like reporting the lighting conditions

Constant CLOCK_NIGHT 1;      !
Constant CLOCK_MORNING 2;
Constant CLOCK_AFTERNOON 3;
Constant CLOCK_EVENING 4;

[ RoughTime ;
  if (the_time >= 1320 || the_time <= 360) return CLOCK_NIGHT;  ! 10p-6a
  if (the_time <= 720) return CLOCK_MORNING;                    ! 6a-noon
  if (the_time <= 1080) return CLOCK_AFTERNOON;                 ! noon-6p
  return CLOCK_EVENING;                                         ! 6p-10p
];


[ DescribeLight ;
  switch (RoughTime()) {
    CLOCK_NIGHT: string DS_LIGHT "pale moonlight";
    CLOCK_MORNING: string DS_LIGHT "cool morning light";
    CLOCK_AFTERNOON: string DS_LIGHT "bright afternoon light";
    CLOCK_EVENING: string DS_LIGHT "slanted evening light";
  }
];


[ LookInstead;
  print "The ~", (name) location, "~ is the area of the church you're in.^";
  if (~~f_explained_look) {
    f_explained_look = true;
    "^[Since this is the area you're in, the game won't describe it here. To see
    the description, use LOOK. To help you deduce this, location names are
    always written capitalised.]";
  }
];



!-------------------------------------- Contraband / Carelessness


[ WasCareless in_solar ;
  print "---you've been caught";
  if (~~f_already_careless) {
    f_already_careless = true;
    ! don't change this so that it returns true!
    if (~~in_solar) {
      print
        ".^^You are given a very stern speech.";
    } else {
      print
        ".^^Brother Oswald lectures sternly about this and then ejects you from
        the room.";
    }
    print
      "^^If you want to keep investigating, you'll need to be more careful.^";

    if (in_solar) {
      new_line;
      PlayerTo(CloisterNW);
    }
  } else {
    print " a second time!";
    KillOff(7);
    rtrue;
  }
];


[ CheckHidContraband ;
  if (f_hid_contraband && ~~task_done->TASK_HID_CONTRABAND) {
    TaskDone(TASK_HID_CONTRABAND);
    "^You found a way to carry illicit things unnoticed. ";
  }
];


[ CheckForContraband o caught_with mloc ;
  if (f_forgive_contraband_one_turn) {
    f_forgive_contraband_one_turn = false;
    rfalse;
  }
  ! Should think on this. is this too generous? But don't want them dying
  ! going to the last service with the psalter, either
  if (f_enough_evidence) rfalse;

  ! Don't do this during the crypt rescue since there's so much darkness and
  ! hiding and such
  if (SceneCrypt has general || location == Undercroft) rfalse;

  ! check for contraband, first thing becomes 'caught_with':
  objectloop (o in player) {
    if (o hasnt ok_carry) {
      caught_with = o;
      break;
    }
  }

  ! no contraband, safe
  if (caught_with == 0) rfalse;

  if (~~f_noted_having_contraband_first_time && caught_with) {
    print
      "^[Carrying items not related to your work here (such as ",
      (the) caught_with, ") is against priory rules.
      Find a way to hide these or carry them unnoticed.]^";
    f_noted_having_contraband_first_time = true;
  }

  NarcInRoom();
  if (g_narc == 0) rfalse;

  ! carrying lit candles in view of others is always a problem

  if (location ~= Kitchen or Undercroft && (MyCandle has light)) {
    print "^", (The) g_narc;
    if (g_narc_loc ~= location)
      print " enters from ", (the) g_narc_loc, " and";
    print
      " catches you carrying the lit candle.
      ~Where did you get that? Candles aren't to be wasted by novices.~";
    KillOff(3);
    rtrue;
  }

  f_warned_contraband++;
  switch (f_warned_contraband) {

    1: rfalse;  ! first violation is free

    2:
      print "^You should be more careful. If ", (the) g_narc, " had noticed";
      " you carrying ", (the) caught_with, ", you'd have faced severe
      punishment.";

    3:
      "^Again: be careful! Openly carrying contraband, like ",
      (the) caught_with, ", will get you in trouble.";

    default:
      print "^", (The) g_narc, " ", ;
      mloc = parent(g_narc);
      if (parent(mloc) ~= nothing) mloc = parent(mloc);
      if (mloc ~= location) print "enters from ", (the) g_narc_loc, ". He ";
      print
        "notices you openly carrying ", (the) caught_with,
        ". ~Brother Novice, what are you doing with that? That has nothing to do
        with your duties here.~";
      KillOff(3);
  }
];


! Is a "narc" in this room?
!
! All monks are narcs except Wilfred and Remigio

[ _Narc loc m mloc i;
  for (i = 1 : i < ALL_MONK_NUM : i++) { ! skip aelred
    m = all_monks-->i;
    if (m == BrWilfred or BrRemigio) continue;

    mloc = parent(m);
    if (parent(mloc) ~= nothing) mloc = parent(mloc);

    if (mloc == loc) {
      g_narc = m;
      g_narc_loc = loc;
      rtrue;
    }
  }
  rfalse;
];


! Is a non-narc monk in this area? (searching recursively)
!  non-narcs are sleeping wilfred, remigio

[ NarcInRoom loc ;
  g_narc = 0;
  if (loc == 0) loc = location;

  if (_Narc(loc)) return true;

  switch (loc) {
    Garth:
      return _Narc(CloisterN) || _Narc(CloisterW)
          || _Narc(CloisterE) || _Narc(CloisterS);
    CloisterNW: return _Narc(CloisterW)  || _Narc(CloisterN);
    CloisterN:  return _Narc(CloisterNW) || _Narc(CloisterNE);
    CloisterNE: return _Narc(CloisterN)  || _Narc(CloisterE);
    CloisterW:  return _Narc(CloisterSW) || _Narc(CloisterNW);
    CloisterE:  return _Narc(CloisterNE) || _Narc(CloisterSE);
    CloisterSW: return _Narc(CloisterW)  || _Narc(CloisterS);
    CloisterS:  return _Narc(CloisterSW) || _Narc(CloisterSE);
    CloisterSE: return _Narc(CloisterS)  || _Narc(CloisterE);
  }
  rfalse;
];


!-------------------------------------- Evidence


[ CalculateEvidence
        _coins _psalter _henbane _note _chron _letters _hugh_attempt _total;
  ! *need* to know it's a suspicious death, and have a reason to blame hugh
  _coins        = task_done->TASK_EVIDENCE_COINS * 5;
  _psalter      = task_done->TASK_EVIDENCE_PSALTER * 5;
  _henbane      = task_done->TASK_EVIDENCE_HENBANE_DECOCT * 5;
  _note         = task_done->TASK_EVIDENCE_LETTER * 5;
  _chron        = task_done->TASK_READ_CHRONICLE * 2;
  _letters      = task_done->TASK_ROSE_LETTERS * 3;
  _hugh_attempt = ev_hugh_attempt * 5; ! hugh attempted to kill us!


  ! don't even know it's a death
  if (~~g_suspicion_level) rfalse;

  ! no crime proved
  if (~~(_coins || _psalter || _note)) rfalse;

  ! preponderance of evidence
  _total = (
    _coins +
    _psalter +
    _henbane +
    _note +
    _chron +
    _letters +
    _hugh_attempt +
    g_suspicion_level);

  return _total;
];


[ CheckEvidence ;

  g_suspicion_level = g_suspicion_level
    || ((ev_symptoms && ev_hen_symptoms)
    || ev_coins
    || ev_rose_letters
    || ev_note
    || ev_chronicle
    || ev_psalter
  );

  if (ev_symptoms && (~~ev_hen_symptoms)
        && ~~task_done->TASK_BECAME_SUSPICIOUS) {
    ! can do before death, so be careful in wording
    ! they may know hen symptoms before aelred's symptoms --- if so, don't
    ! print this; they'll succeed in the next case.
    TaskDone(TASK_BECAME_SUSPICIOUS);
    print
      "^This definitely feels like an unnatural ";
      if (BrAelred hasnt general) print "condition"; else print "death";
      print ". You resolve to discover what happened to Aelred.^";
  }

  if (ev_symptoms && ev_hen_symptoms && ~~task_done->TASK_MATCH_SYMPTOMS) {
    TaskDone(TASK_MATCH_SYMPTOMS);
    TaskDone(TASK_BECAME_SUSPICIOUS);
    print
      "^You recognise in Brother Aelred's symptoms the signs of henbane
      poisoning. This death wasn't caused by a heart attack.^";
   }

  ! need to get decoction, look up symptoms, and knew him symptoms
  if (ev_symptoms && ev_hen_symptoms && ev_took_poison
          && ~~task_done->TASK_EVIDENCE_HENBANE_DECOCT) {
    TaskDone(TASK_EVIDENCE_HENBANE_DECOCT);
    print
      "^Now that you've recognised the symptoms of henbane poisoning in Brother
      Aelred and found the henbane decoction, you're even more certain he died
      of unnatural means.

      ^^Henbane causes violent convulsions and terrible pain before death. No
      herbalist would choose such suffering for themselves, even if they were
      desperate enough to commit the mortal sin of self-murder.

      ^^This was murder.^";
  }

  if (ev_coins && ~~task_done->TASK_EVIDENCE_COINS) {
    TaskDone(TASK_EVIDENCE_COINS);
    print "^These coins are certainly evidence of wrongdoing";
    if (ev_note)
      print " and may have come from the buyer who wrote that note.^";
    else
      print ", but you're not sure where they came from.^";
  }

  if (ev_rose_letters && ~~task_done->TASK_ROSE_LETTERS) {
    TaskDone(TASK_ROSE_LETTERS);
    print "^Where could Brother Hugh have found the money she mentions?";
    if (ev_chronicle && ~ev_psalter) {
      print
        " You have a dreadful feeling it might have come from the
        missing psalter or perhaps an earlier one that disappeared.";
    } else if (ev_psalter && ~~ev_chronicle) {
      print
        " You wonder if this is related to the psalter you found.";
    } else if (ev_chronicle && ev_psalter) {
      print
        " You fear it came from the sale of stolen psalters,
        like the one you found hidden away.";
    } else if (ev_note) {
      print " Might it have come from the buyer who wrote that note you found?";
    }
    if (ev_rosehips) {
      print
        " You think of those rosehips left at St Jude's altar. Hugh has been
        praying for her---desperately enough to seek the saint of hopeless
        causes.";
    }
    new_line;
  }

  if (ev_note && ~~task_done->TASK_EVIDENCE_LETTER) {
    TaskDone(TASK_EVIDENCE_LETTER);
    print
      "^Who wrote this note? An outsider? Buying precious priory property? And
      who was meant to find it and read it?";
    if (ev_chronicle && ev_psalter) {
      print
        " These must be the items that have been disappearing, like the psalter
        you found.";
    } else if (ev_chronicle && ~~ev_psalter) {
      print
        " Perhaps this is related to the disappearance of the psalter you read
        about.";
    } else if (ev_psalter && ~~ev_chronicle) {
      print
        " Perhaps this is related to that psalter you found buried in the
        Undercroft.";
    }
    new_line;
  }

  if (ev_chronicle && ~~task_done->TASK_READ_CHRONICLE) {
    TaskDone(TASK_READ_CHRONICLE);
    if (ev_psalter) {
      print
        "^Perhaps the missing psalter is the one you found in the Undercroft?";
    } else if (ev_note) {
      print
        "^Perhaps that missing psalter is related to that note you found about
        buying illuminated manuscripts?";
    } else {
      print "^The priory seems to be struggling in ways you hadn't realised.";
    }
    new_line;
  }

  if (ev_psalter && ~~task_done->TASK_EVIDENCE_PSALTER) {
    TaskDone(TASK_EVIDENCE_PSALTER);
    print "^There's some serious wrongdoing here. Why was this hidden?";
    if (ev_chronicle && ev_note) {
      print
        " This must be related to its disappearance, and to that note you found
        about stealing illuminated manuscripts.";
    } else if (ev_note) {
      print
        " You wonder if this is related to that note you found.";
    } else if (ev_chronicle) {
      print
        " This sounds like the one that Brother Wilfred couldn't find.";
    }
    new_line;
  }

  if (ev_rosehips && ~~task_done->TASK_IDENTIFIED_ROSEHIPS) {
    TaskDone(TASK_IDENTIFIED_ROSEHIPS);
    if (ev_rose_letters) {
      print
        "^St Jude is the patron of lost causes. Brother Hugh has a sister in
        desperate need, and someone has been leaving offerings here, quietly,
        privately. You feel certain you know who.^";
    }
  }
];


!-------------------------------------- End game


Object MercyOrJustice
  with
    react_before [;
      f_did_confess = true;
      if (action == ##Choose or ##NoTalk ||
            (action == ##Tell && noun == BrWilfred)) {
        wn = consult_from;
        switch (NextWord()) {
          'mercy': action = ##Mercy;
          'justice': action = ##Justice;
          'neither': action = ##Neither;
        }
      }
      if (action == ##Mercy) Ending(DEAD_MERCY);
      else if (action == ##Justice) Ending(DEAD_JUSTICE);
      else if (action == ##Examine && noun == BrWilfred)
        "You cannot look to Brother Wilfred for this.";
      else if (action == ##Ask && noun == BrWilfred)
        "Brother Wilfred has told you that you must decide alone.";
      else if (action == ##Think)
        "You look inwards, hoping for a clear answer.";
      else if (action == ##Pray)
        "You pray for guidance and listen inwards for your choice.";
      else if (action == ##Neither) {
        print
          "You choose neither and postpone your responsibility. You can see the
          disappointment on Brother Wilfred's face.^";
      }
      else {
        meta = true;
        "You must choose ", (mono) "JUSTICE", ", ", (mono) "MERCY", ", or ",
        (mono) "NEITHER", " (to not decide).";
      }
      remove self;
      rtrue;
    ],
  has scenery ;


[ SceneConfession ;
  move MercyOrJustice to location;
  if (f_did_confess) {
    "You once again offer Brother Wilfred your confession, and he offers you the
    same choice: choose justice or choose mercy?";
  }

  "^Wilfred listens as you explain your discoveries.", (PresentEvidence) 0,
  "^^A great sadness crosses Wilfred's face. ~My son,~ he begins, then pauses.
  ~No. 'Aldwin'. You are no longer a child.~

  ^^He sighs deeply. ~I have grown more forgiving in my old age. I no longer
  feel it is my place to judge others' sins---only to hear them and offer what
  comfort I can.

  ^^~But you... you have chosen this life. And if you are to be a true brother
  here, you must be capable of making great and terrible choices.~

  ^^He looks at you steadily. ~So I leave this to you, Aldwin. Will you bring
  these accusations to our prior? If you do, Hugh will surely hang. Or will you
  forgive him, even knowing justice may demand otherwise?

  ^^~This is your choice. Choose wisely, and choose with prayer.~

  ^^What will you do? Choose justice or mercy?";
];


[ PresentEvidence;
  if (task_done->TASK_EVIDENCE_COINS)
    print " The coins hidden among the dead.";
  if (task_done->TASK_EVIDENCE_PSALTER)
    print " The discovered stolen psalter.";
  if (task_done->TASK_EVIDENCE_HENBANE_DECOCT)
    print " The deadly henbane decoction.";
  if (task_done->TASK_EVIDENCE_LETTER)
    print " The note seeking priory manuscripts.";
  if (task_done->TASK_ROSE_LETTERS)
    print " The letters to Rose, showing previous payment.";
  if (ev_hugh_attempt)
    print " And, most damning, the attempt on your life.";
];


[ Ending choice ;
  deadflag = choice;

  switch(choice) {
    DEAD_JUSTICE:
      print
        "^You tell Prior Oswald everything.", (PresentEvidence) 0, "^^Hugh is
        taken by the sheriff within days. He is tried, condemned, and hanged
        before the month is out. Rose dies alone that winter, with no brother to
        tend her. You inquire among travellers about William, but hear
        nothing.";

      if (MustardPackage has moved || Coins has moved) {
        print "^^You gave Brother Oswald ";
        if (MustardPackage has moved) {
          print "the stolen psalter";
          if (Coins has moved) print " and ";
        }
        if (Coins has moved) print "the sack of silver";
        print ", saving the priory from further financial ruin.";
      }

      print
        "^^You kept your vows of obedience to your Prior. You served truth. But
        standing in the herb garden near where Brother Aelred died, you wonder
        if justice and mercy can ever live in harmony---or if, in choosing one,
        you always betray the other.

        ^^Brother Aelred's words echo: ~One life for two, my son.~ You will
        never know if you honoured his sacrifice, or squandered it.";

    DEAD_MERCY:
      print
        "^You and Brother Wilfred confront Hugh and tell him to leave. Tonight.
        Before questions are asked.";
      if (ev_rose_letters && IndirectlyContains(player, Coins))
        print
          " You give Hugh a shilling's-worth of the coins, and tell him to
          send this to Rose for William's recovery.";
      print
        " Hugh takes flight, and you never learn what becomes of him---or of his
        family.

        ^^You lied to the prior about your day's activities and received penance
        for your actions that day.";

        if (MustardPackage has moved || Coins has moved) {
          print " At least you can give Prior Oswald ";
          if (MustardPackage has moved) {
            print "the stolen psalter";
            if (Coins has moved) print " and ";
          }

          if (ev_rose_letters && IndirectlyContains(player, Coins)) {
            print "the majority of the silver coins";
          } else if (Coins has moved) {
            print "the silver coins";
          }

          print
            ", saying you found them after being assigned to organise the
            Undercroft after the unexplained disappearance of Hugh.";
        }

      print
        "^^But when you pray before the Lady of Thorns, you remember Brother
        Aelred's last words: ~One life for two, my son.~ Perhaps mercy, not
        justice, was what he hoped for.

        ^^Still, you wonder. A murderer walks free. Does forgiveness make you
        holy, or complicit? You will carry this question all your days.";

    DEAD_INACTION:
      print
        "^Brother Hugh fled in the night, never to be seen again. You had a
        chance to resolve this by sharing what you learned, but you didn't. You
        cannot meet the eyes of Brother Wilfred without feeling shame.

        ^^In the weeks that followed, Brother Wilfred grew silent and withdrawn.
        He stopped eating, stopped illuminating. One morning, he simply didn't
        wake. Whether from grief for Brother Aelred or despair at the priory's
        decline, he had lost his will to live.

        ^^Three brothers lost. The Rule continues, but the light grows dimmer.";

    DEAD_UNSOLVED:
      print
        "^Brother Aelred was buried the next day in the priory graveyard, marked
        only by a simple wooden cross.

        ^^On warm days, you bring him rosemary and lay it next to his cross.";

      if (CalculateEvidence() >= 5) {
        print "^^You reflect on what you learned. The strange death.";
        PresentEvidence();
        print " Still, y";
      } else {
        print "^^Y";
      }
      print
        "ou can't shake the feeling that you failed him, that the last thing you
        could have done for your mentor, you left undone. ";
      if (MustardPackage has moved || Coins has moved) {
        print "At least you can give Prior Oswald ";
        if (MustardPackage has moved) {
          print "the stolen psalter";
          if (Coins has moved) print " and ";
        }
        if (Coins has moved) print "the sack of silver";
        print ", saving the priory from further financial ruin.";
      } else {
        print "You'll carry that feeling for all your days.";
      }
  }
];




!===============================================================================
!======================================================================= Grammar

!-------------------------------------- Scopes & matchers

! "LOOK UP FOO IN BOOK" scope --- rather than using topics, I use objects as
! the things that can be looked up (this allows the normal parsing to find
! things, so stuff like "LOOK UP HUGH IN BOOK" and "LOOK UP BROTHER HUGH IN
! BOOK" both work because the BrHugh handles that itself)

[ ConsultScope o ;
  switch (scope_stage) {
    1: rfalse;
    2: objectloop (o provides history_text) PlaceInScope(o);
    3: "I don't know what resource you're trying to use.";
  }
];


[ AskScope o;
  switch (scope_stage) {
    1: rfalse;
    2: objectloop (o has convo) PlaceInScope(o); rtrue;
  }
];


[ FollowScope ;
  switch (scope_stage) {
    1: rfalse;
    2:
      if (BrAelred notin nothing) PlaceInScope(BrAelred);
      if (location == Slype && BrAelredDying hasnt general)
        PlaceInScope(BrAelredDying);
      if (location == InfirmaryChapel)
        PlaceInScope(BrAelredBody);
      PlaceInScope(BrAnselm);
      PlaceInScope(BrBenedict);
      PlaceInScope(BrCuthbert);
      PlaceInScope(BrHugh);
      PlaceInScope(BrMartin);
      PlaceInScope(BrOswald);
      PlaceInScope(BrRemigio);
      PlaceInScope(BrWilfred);
      PlaceInScope(Pax);
      rtrue;
    3: "You can only follow the brothers.";
  }
];


[ CabinetNumber n a b c d ;
  ! This should only be used for all-wheels; for other objects, fail here and
  ! the parser will move to next verb form (in this case, parsing a number).
  !
  ! This is important --- this lets us SET FIRST WHEEL TO 7.
  if (noun ~= Wheels) { return GPR_FAIL; }

  ! Now that we know this is the the "wheels" object, we never fail (that would
  ! let is fall through to trying to parse as a number, making stuff like
  ! SET WHEELS TO 12 do something. Instead, if we don't set parsed_number to
  ! something else before we return, it will be -1, and Wheels.SetTo will know
  ! that it was an invalid number and complain.
  parsed_number = -1;
  n = WordAddress(wn);

  ! this should always parse a "number", even if it's mis-formed.
  ! so count this as a parsed word. it'll be parsed as -1 if not good.

  ! acceptable forms are 1-2-3-4 and 1234
  switch (WordLength(wn++)) {
    7:
      if (n->1 ~= '-' || n->3 ~= '-' || n->5 ~= '-') return GPR_NUMBER;
      a = n->0 - '0'; b = n->2 - '0'; c = n->4 - '0'; d = n->6 - '0';
    4:
      a = n->0 - '0'; b = n->1 - '0'; c = n->2 - '0'; d = n->3 - '0';
    default:
      ! Invalid, but accept here --- we'll complain in SetTo
      return GPR_NUMBER;
  }

  if (a < 0 || a > 9 ||
      b < 0 || b > 9 ||
      c < 0 || c > 9 ||
      d < 0 || d > 9)
    ! Invalid, but we'll print a message saying so in SetTo, so accept here
    return GPR_NUMBER;

  parsed_number = a * 1000 + b * 100 + c * 10 + d;
  return GPR_NUMBER;
];

!========================================================================= Verbs

!------------------------------------------ Meta verbs and similar special verbs

[ AboutSub; MenuAbout.select(); ];

[ SolveSub;
  if (~~f_enough_evidence)
    "[When you've found enough evidence, you'll be told how you can proceed.]";

  if (g_current_service && location == Quire) {
    print "[If you want to make a public accusation, use ", (mono) "SHOUT";
    if (g_current_service hasnt on) print " once the service starts";
    ".]";
  }

  "You've learned enough to solve the crime, but you can continue if you'd like
  to better understand the crime.

  ^^To make a public accusation, you can do so at the next office. Or you could
  first talk with a sympathetic Brother.";
];


[ CommandsSub;
  Help_specialCmds.description();
  new_line;
  Help_actions.description();
];


[ CreditsSub ;
  About_credits.description();
];


[ ExitsSub ;
  if (location == thedark) "Being so dark, you can't see the exits.";
  print "Exits: ";
  PrintExits("and");
  new_line;
];


[ HelpSub;
  MenuHelp.select();
];


[ HereSub during_look m count p i; for (i = 0 : i < ALL_MONK_NUM : i++) {
    p = parent(all_monks-->i);
    if (p && location == p or parent(p))
      count++;
  }
  if (count == 0) {
    if (~~during_look) "There are no brothers here.";
    rtrue;
  }
  if (during_look) print "^";
  print "Brothers here:";
  for (i = 0 : i < ALL_MONK_NUM : i++) {
    m = all_monks-->i;
    p = parent(m);
    if (p && location == p or parent(p)) {
      print "^- ", (string) m.simple_name, ", the ", (string) m.job_title;
      if (p ~= location) print " (seated)";
    }
  }
  new_line;
];


[ MapSub ;
  font off;
  switch (location) {

    Nave, Quire, Sanctuary, StJudeChapel, LadyChapel,
    FitzAlanChantry, Sacristy:
      print "
        ^     to Tower    to Dorter      to Crypt
        ^  |--/-------------/---------------/----------|
        ^  | U        .   U       .        D    | Fitz |
        ^  |          .           .             |--  --|
        ^ -:   Nave   .   Quire   .  Sanctuary    Lady |
        ^  |          .           .   ____..____|--  --|
        ^  |          .           .  | Sacristy | Jude |
        ^  |----------------  -------------------------|
        ^               to Cloister
        ^                    |^";

    CloisterE, CloisterN, CloisterNE, CloisterNW, CloisterS, CloisterSE,
    CloisterSW, CloisterW, Garth, PriorsSolar, Locutory, Library,
    ChapterHouse, Lavatorium, Refectory, Scriptorium:
      print "
        ^              to Quire    Up to Day Stairs
        ^ Prior's          |      /
        ^   Solar -- NW == N == NE -- Chapter House
        ^            ||    |    ||
        ^ Locutory - W-  Garth  -E -- Scriptorium -- Library
        ^            ||    |    ||
        ^    West -- SW == S == SE -- Slype -- Infirmary
        ^    Gate     |    |            |          |
        ^           Lav  Refectory   to Herb &   Chapel
        ^                  |          Gardens
        ^                Kitchen^";

    Dorter, Necessarium, Hall, LayDorter, NightStairs, DayStairs:
      print "
      ^    Night    |------------------|
      ^   Stairs  __D                  |
      ^ to Quire /  |      Dorter      |
      ^             |                  |
      ^             |----   -----|-----|
      ^      Day  __D    Hall      Nec |
      ^   Stairs /  |----   -----|-----|
      ^       to    |   Lay Dorter     |
      ^  Cloister   |------------------|^";

    Slype, Infirmary, InfirmaryChapel, Herbarium, Garden, RestrictedGarden:
      print "
      ^ |----------------------------------|
      ^          Slype         -           |
      ^ |----+-----  ----+-----| Infirmary |
      ^      | Herbarium |     |           |
      ^ |----+----   ----+-----+-----  ----|
      ^ |      |               |  Chapel   |
      ^ | Rest :     Main      |-----------|
      ^ | Gard |    Garden     |
      ^ |      |               |
      ^ |----------------------|^";

    Porch, Passage, PassageSouth:
      print "
      ^             |------------
      ^   Porch ----:- Nave
      ^     |       |------------
      ^     |
      ^ Passage N --:- West -- Cloister
      ^     |          Gate
      ^     |
      ^ Passage S --:- Undercroft^";

    default: font on; print "There is no in-game map for this area.^";
  }
  font on;
  "^Graphical map at https://lady-of-thorns.netlify.app/map";
];


[ NotADirSub;
  "This game uses only north, south, west, east, up, down, in, and out.";
];


[ OfficesSub;
  TaskDone(TASK_LISTED_OFFICES);
  new_line;

  print (mono)
    "   Matins  2 AM     Sext     Noon
    ^   Lauds   5 AM     None     3 PM
    ^   Prime   7 AM     Vespers  5 PM
    ^   Terce   9 AM     Compline 7 PM";
  new_line;
];


[ TimeSub ;
  if (turns - g_last_accurate_time > 30)
    "From your vague sense of time, it is ", (ReallyRoughTime) the_time, ".";
  "Since you've seen a good source of time recently, you estimate it to be ",
  (SundialTime) the_time, ".";
];


[ WhoSub m i ;
  print "Priory brethren:";
  for (i = 0 : i < ALL_MONK_NUM : i++) {
    m = all_monks-->i;
    print "^- ", (string) m.simple_name, ", the ", (string) m.job_title;
  }
  new_line;
];



Verb meta 'about' *                        -> About;
Verb meta 'accuse' 'solve'
  * topic                                  -> Solve
  *                                        -> Solve;
Verb meta 'commands' *                     -> Commands;
Verb meta 'credit' 'credits' *             -> Credits;
Verb meta 'exits' *                        -> Exits;
Verb meta 'help' *                         -> Help;
Verb meta 'here' *                         -> Here;
Verb meta 'map' *                          -> Map;
Verb meta 'northeast' 'ne'
          'southeast' 'se'
          'northwest' 'nw'
          'southwest' 'sw' *               -> NotADir;
Verb meta 'offices' 'hours' 'services' *   -> Offices;
Verb meta 'time' *                         -> Time;
Verb meta 'who' *                          -> Who;



!--------------------------------------  Verbs that are just for post-confession

[ MercySub;   meta = true; return MSG_PARSER_UNKNOWN_VERB; ];
[ JusticeSub; meta = true; return MSG_PARSER_UNKNOWN_VERB; ];
[ NeitherSub; meta = true; return MSG_PARSER_UNKNOWN_VERB; ];
[ ChooseSub;  meta = true; return MSG_PARSER_UNKNOWN_VERB; ];

Verb 'choose' * topic                      -> Choose;
Verb 'justice' *                           -> Justice;
Verb 'neither' *                           -> Neither;
Verb 'mercy' *                             -> Mercy;


!----------------------------------------------------------- Communication verbs


[ NoTalkSub ;
  meta = true;
  "[Instead, try: ", (mono) "ASK monk ABOUT person/thing", " or ",
  (mono) "TELL monk ABOUT person/thing", ". But: many monks follow their vow of
  silence and others speak only in certain locations.]";
];


Extend 'answer' first
  *                                        -> NoTalk
  * topic                                  -> NoTalk;

Extend 'ask' first
  * creature 'about' scope=AskScope        -> Ask;

Extend 'give' replace
  * noun 'to' creature                     -> Give
  * creature noun                          -> Give reverse
  * 'over' noun 'to' creature              -> Give;

Verb 'greet' 'hello'
  * topic                                  -> NoTalk
  *                                        -> NoTalk;

Extend 'show' replace
  * creature noun                          -> Show reverse
  * noun 'to' creature                     -> Show;

Verb 'talk'
  *                                        -> NoTalk
  * topic                                  -> NoTalk;

Extend 'tell' first
  * creature 'about' scope=AskScope        -> Tell;


!----------------------------------------------------------------- General verbs


[ BurnSub ;
  ! Locations with fireplaces will not call this
  if (noun has light) print_ret (The) noun, " is already lit.";

  if ((~~IsCarryingLit()) && location ~= NightStairs or Scriptorium or Kitchen)
    "You have no source of flame.";

  if (ImplicitGrabIfNotHeld(noun)) rtrue;
  if (location ~= NightStairs or Scriptorium or Kitchen)
    if (ImplicitGrabIfNotHeld(second)) rtrue;

  return MSG_BURN_DEFAULT;
];


[ ConfessSub ;
  print_ret (CObjIs) noun, "n't interested in your confession right now.";
];


[ ConsultSub;
  if (noun == nothing) {
    if (second && second provides history_text && TestScope(MonkGuide)) {
      if (ImplicitGrabIfNotHeld(MonkGuide)) rtrue;
      noun = MonkGuide;
    }
    else if (TestScope(Herbal) && ~~second) {
      if (ImplicitGrabIfNotHeld(Herbal)) rtrue;
      noun = Herbal;
    }
    if (noun) {
      print "(consulting ", (the) noun, ")^";
      <<Consult noun second>>;
    }
    "Exactly what resource are you trying to use?";
  }
  return MSG_CONSULT_NOTHING_INTERESTING;
];


[ ConsultWrongSub ;
  "[Instead, please try ", (mono) "LOOK UP ___ IN the-book", ".]";
];


[ DanceSub ;
  "You are a novice in a Benedictine priory, not a jongleur.";
];


[ ExtinguishSub;
  if (noun == nothing) {
    if (MyCandle in player && MyCandle has light)
      <<Extinguish MyCandle>>;
    "Extinguish what, exactly?";
  }
  if (noun has light)
    "Try as you might, you can't extinguish that.";
  "That's not something you can extinguish.";
];


[ FollowSub mloc dir ;
  ! "[To follow someone, go in the direction they went.]";

  if (~~noun ofclass Monk)
    "You cannot follow ", (the) noun, ".";

  mloc = parent(noun);
  if (parent(mloc) ~= 0) mloc = parent(mloc);

  if (location == mloc) {
    print (The) noun, " is already here.^";
    if (~~f_explained_follow) {
      f_explained_follow = true;
      "^[You can only follow someone right after they leave your location.]";
    }
    rtrue;
  }

  if (noun.prev_loc ~= location)
    "You cannot follow ", (the) noun, " now.";

  if (player notin location)
    "You're not standing.";

  if (noun.prev_dir == 0) {
    print "You cannot follow ", (the) noun, " to ", (the) mloc;
    if (mloc == Undercroft)
      " because other brothers are forbidden to enter this space without
      permission from the cellarer.";
    if (mloc == PriorsSolar)
      " because the door is locked.";
  }

  print "You follow ", (the) noun, " ", (DirName) noun.prev_dir, " to...^";
  dir = DirPropToFakeObj(noun.prev_dir);
  <<Go dir>>;

  ! mloc = parent(noun);
  ! if (mloc == nothing) print_ret (The) noun, " can no longer be followed.";
  ! if (~~mloc ofclass Room or Cloister) mloc = parent(mloc);
  ! if (mloc == location) print_ret (The) noun, " is already here.";

  ! for (i=0 : i<6 : i++) {
  !   if (mloc == location.(array_exits_check->i)) {
  !     print "You follow ", (the) noun, " ", (DirName) array_exits_check->i,
  !       ".^^";
  !     PlayerTo(mloc);
  !     rtrue;
  !   }
  ! }

  ! print_ret (The) noun, " can no longer be followed.";
];


[ GoHelpSub ;
  meta = true;
  print
    "[To go to a location, navigate with directions like ", (mono) "GO NORTH",
    " (or ", (mono) "GO N", " or even ", (mono) "N", "). You may find the provided
    map or the command ", (mono) "MAP", " helpful to decide which way to go.]^";
  wn = consult_from;
  if (NextWord() == 'garden' or 'gardens')
      "^[To find the gardens, go south from the Quire and then you can use the
      command MAP to navigate.]";
];


[ GrindSub;
  "You have no tools for such.";
];


[ HealSub;
  print_ret (The) noun, " doesn't seem unwell.";
];


[ HideSub ;
  if (noun == nothing)
    "Hide behind what, exactly?

    ^^[You should try ", (mono) "HIDE BEHIND ____", ".]";
  if (NarcInRoom()) print_ret (The) g_narc, " would see you trying to hide.";
  "You try, but you realise you could still be easily seen.";
];


[ KneelSub;
  "This isn't a place to kneel.";
];


[ KneelAnySub;
  "You kneel briefly here, then rise back up.";
];


[ KnockSub ;
  if (noun hasnt door) "Nothing happens.";
  "There is no reply.";
];


[ LieOnSub ;
  "This is not a place to lie.";
];


[ LieOnAnySub ;
  "There is no appropriate place here to lie.";
];


[ LockSub k;
  if (ObjectIsUntouchable(noun)) rtrue;
  if (noun hasnt lockable) {
    PrintMsg(MSG_LOCK_NOT_A_LOCK, 'lock');
    rtrue;
  }
  if (noun has locked) {
    PrintMsg(MSG_LOCK_ALREADY_LOCKED, 'lock');
    rtrue;
  }
  if (noun has open) {
    print "(first closing it)^";
    give noun ~open;
  }

  k = noun.with_key;

  if (second == nothing && k ~= nothing && IndirectlyContains(player, k)) {
    second = k;
    print "(with ", (the)second, ")^";
  }
  if (second == nothing) "You don't have the key.";
  if (second ~= k) {
    PrintMsg(MSG_LOCK_KEY_DOESNT_FIT);
    rtrue;
  }
  give noun locked;
  run_after_routines_msg = MSG_LOCK_DEFAULT;
  run_after_routines_arg_1 = 'lock';
];


[ LookUnderSub;
  if (ObjectIsUntouchable(noun)) return;
  if (parent(noun) has supporter or container or enterable)
    "Underneath ", (the) noun, " is ", (the) parent(noun), ".^";
  return MSG_SEARCH_NOTHING_SPECIAL;
];


[ LowerSub;
  print_ret (CTheyreOrThats) noun, " not something you'd lower.";
];


[ MisconceptSub;
  meta = true;
  "That is not a verb I recognise.";
];


[ NoUseSub;
  meta = true;
  "[This game doesn't have a general ", (mono) "USE verb", ". Instead, say how
  you're trying to use something: ", (mono) "SIT ON CHAIR", ", ",
  (mono) "OPEN DOOR", ", ", (mono) "DIG WITH SPADE", ", and so on.]";
];


[ PraySub ;
  if (noun) "[Don't specify a target, just ", (mono) "PRAY", ".]";
  return MSG_PRAY_DEFAULT;
];


[ PruneSub;
  if (~~noun ofclass Herb or Plant)
    "That's not something you can pick, like a plant.";
  <<Cut noun>>;
];


[ RaiseSub;
  print_ret (CTheyreOrThats) noun, " not something you'd pull up.";
];


[ SitSub;
  "This isn't a respectful place to sit.";
];


[ SitAnySub;
  CSPerformAction(##Enter, CSP_FLOOR);
];


[ UnlockSub k;
  if (ObjectIsUntouchable(noun)) rtrue;
  if (noun hasnt lockable) {
    PrintMsg(MSG_UNLOCK_NOT_A_LOCK, 'unlock');
    rtrue;
  }
  if (noun hasnt locked) {
    PrintMsg(MSG_UNLOCK_ALREADY_UNLOCKED, 'unlock');
    rtrue;
  }

  k = noun.with_key;

  if (second == nothing && k ~= nothing && IndirectlyContains(player, k)) {
    second = k;
    print "(with ", (the)second, ")^";
  }
  if (second == nothing) "You don't have the key.";
  if (second ~= k) {
    PrintMsg(MSG_UNLOCK_KEY_DOESNT_FIT);
    rtrue;
  }
  give noun ~locked;
  give noun open;
  "You unlock ", (the) noun, " and open it.";
];


[ WaveToSub;
  "You wave at ", (the) noun, " but get no response.";
];


[ XyzzySub;
  "You're in a monastery, not Colossal Cave.";
];


Extend 'blow' first
  * 'out'/'on' noun                            -> Extinguish;

Extend 'burn' first
  * noun 'in' noun                             -> Burn;

Verb 'chant' = 'sing';

Extend 'climb' first
  * 'on' noun                                  -> Climb
  * 'up' 'on' noun                             -> Climb
  * 'down'                                     -> Exit
  * 'down' noun                                -> Exit
  * 'in' container                             -> Enter;

Verb 'confess'
  * 'to' creature                              -> Confess;

Extend 'consult' first
  * held 'about'/'on' scope=ConsultScope       -> Consult;

Verb 'dance'
  *                                            -> Dance;

Extend 'dig'
  * 'in' noun                                  -> Dig
  * 'in' noun 'with' held                      -> Dig
  *                                            -> Dig;

Verb 'extinguish' 'snuff'
  * noun                                       -> Extinguish
  * 'out' noun                                 -> Extinguish
  * 'light'                                    -> Extinguish;

Verb 'follow'
  * 'after' scope=FollowScope                  -> Follow
  * scope=FollowScope                          -> Follow;

Extend only 'fondle' first
  * noun                                       -> Misconcept;

Extend 'get' first
  * 'down'                                     -> Exit
  * 'up' 'on' noun                             -> Climb;

Extend 'go' first
  * 'to' topic                                 -> GoHelp;

Verb 'grind' 'prepare' 'crush'
  * held                                       -> Grind;

Verb 'heal' 'treat' 'cure' 'assist' 'comfort'
  * creature                                   -> Heal;

Verb 'hide'
  * 'by'/'behind' noun                         -> Hide
  * held 'in' noun                             -> Insert
  *                                            -> Hide;

Extend 'jump'
  * 'on' noun                                  -> Climb;

Verb 'kneel'
  * 'on' noun                                  -> Kneel
  *                                            -> KneelAny
  * 'near' noun                                -> KneelAny;

Verb 'knock'
  * 'on' noun                                  -> Knock;

Extend 'lie' replace
  * 'down'                                     -> LieOnAny
  * 'on' noun                                  -> LieOn
  * 'on' 'top' 'of' noun                       -> LieOn
  *                                            -> LieOnAny;

Extend 'light' first
  * noun 'using'/'from' noun                   -> Burn;

Extend 'lock' first
  * noun                                       -> Lock;

Extend 'look' first
  * 'beneath'/'under'/'behind'/'below' noun    -> LookUnder
  * 'up' scope=ConsultScope 'in' held          -> Consult reverse
  * topic 'up' 'in' held                       -> ConsultWrong
  * 'up' topic 'in' held                       -> Consult reverse
  * topic 'up' 'in' held                       -> Consult reverse
  * 'up' scope=ConsultScope                    -> Consult reverse
  * 'up' topic                                 -> Consult reverse
  * 'in' held 'about' scope=ConsultScope       -> Consult;

Verb 'lower'
  * noun 'down'                                -> Lower
  * noun                                       -> Lower;

Verb 'pet'
  * creature                                   -> Kiss;

Extend 'pick'
  * noun                                       -> Prune;

Verb 'plant'
  * held                                       -> Dig
  *                                            -> Dig;

Extend 'pray' first
  * 'to'/'for'/'about'/'with' noun             -> Pray;

Extend 'pull' first
  * noun 'on'/'over' 'head'                    -> Raise
  * 'up' noun                                  -> Raise
  * noun 'up'                                  -> Raise
  * 'down' noun                                -> Lower
  * noun 'down'                                -> Lower;

Extend 'put' first
  * 'out' noun                                 -> Extinguish
  * noun 'out'                                 -> Extinguish
  * 'down' creature                            -> Drop;

Verb 'raise' 'lift'
  * 'up' noun                                  -> Raise
  * noun 'up'                                  -> Raise
  * noun                                       -> LookUnder;

Extend 'read' first
  * 'about' scope=ConsultScope 'in' held       -> Consult reverse
  * scope=ConsultScope 'in' held               -> Consult reverse;

Verb 'ring' 'toll' 'peal'
  * noun                                       -> Pull;

Extend 'search'
  * noun 'with' noun                           -> Search
  * 'beneath'/'under'/'behind'/'below' noun    -> LookUnder;

Extend 'set' replace
  * noun 'to' CabinetNumber                    -> SetTo
  * noun 'to' number                           -> SetTo
  * noun                                       -> Set;

Extend only 'sit' replace
  * 'down'                                     -> SitAny
  * 'on'/'in'/'inside' noun                    -> Sit
  * 'on' 'top' 'of' noun                       -> Sit
  *                                            -> SitAny;

Extend 'turn' first
  * noun 'to' number                           -> SetTo;

Extend 'unlock' first
  * noun                                       -> Unlock;

Verb 'use' * noun                              -> NoUse;

Extend 'wave' first
  * 'at'/'to' creature                         -> WaveTo;

Verb 'worship' = 'sing';

Verb 'xyzzy' 'plugh' *                         -> Xyzzy;


!===============================================================================
!-==================================================================== debugging

#IfDef DEBUG;

[ SceneScope o ;
  switch (scope_stage) {
    1: rfalse;
    2:
      objectloop (o ofclass Scene) PlaceInScope(o);
      rtrue;
  }
];

Verb meta 'gocheck'     * topic                -> GoToCheck;
Verb meta 'settime'     * number number        -> SetTime;
Verb meta 'realtime'    *                      -> RealTime;
Verb meta 'suspicion'   * number               -> SuspicionChange;
Verb meta 'evidence'    * number               -> Evidence
                        *                      -> Evidence;
Verb meta 'checkhints'  *                      -> CheckHints;
Verb meta '_//'         *                      -> SolveList;
Verb '_light'           *                      -> SolveLight;
Verb '_start'           * scope=SceneScope     -> StartScene
                        *                      -> StartScene;
Verb meta '_stop'       * scope=SceneScope     -> StopScenes
                        *                      -> StopScenes;
Verb meta 'showmonks'   *                      -> ShowMonks;
Verb meta 'quotestest'  *                      -> TestQuotes;
Verb meta '!//'         * topic                -> Comment
                        *                      -> Comment;
Verb '_ending'          * number               -> Ending;


[ CheckHintsSub h;
  print "Not available:^^";
  objectloop (h ofclass HintObj) {
    if (parent(h) == nothing) print (name) h, "^";
  }
];


[ GoToCheckSub loc ;
  loc = location;
  <GoTo>;
  if (loc ~= location) "^^*** Not correct location^^";
];


[ EvidenceSub ;
  if (noun == nothing) print_ret CalculateEvidence();
  f_enough_evidence = noun;
];


[CommentSub i ;
  if (active_timers) {
    print "*** DEBUG DAEMONS:";
    for (i = 0 : i < active_timers : i++)
      print " ", (name) (the_timers-->(i) & ~WORD_HIGHBIT);
    new_line;
  }
  print "*** CHECK EVIDENCE:^";
  font off;
  print
    "  ", ev_symptoms, " symptoms      ",
        ev_hen_symptoms, " hen_symptoms     ",
        ev_took_poison, " took_poison
    ^  ", ev_coins, " coins         ",
        ev_rose_letters, " rose_letters     ",
        ev_note, " note
    ^  ", ev_chronicle, " chronicle     ",
        ev_psalter, " psalter          ",
        ev_rosehips, " rosehips
    ^  ", g_suspicion_level, " suspicion^";
  font on;
  print "*** SCOPE^";
  <Scope>;
  print "*** SCORE";
  <FullScore>;
  print "*** INVENTORY: ";
  <Inv>;
  new_line;
  if (transcript_mode) {
    PrintMsg(MSG_COMMENT_TRANSCRIPT);
  }
  else PrintMsg(MSG_COMMENT_NO_TRANSCRIPT);
];


[ SuspicionChangeSub;
  g_suspicion_level = noun;
  "Suspicion Level set to ", g_suspicion_level, ".";
];


[ SetTimeSub ; SetTime(noun * 60 + second); <<Time>>; ];


[ ZeroPad n; if (n < 10) print "0"; print n; ];


[ RealTime time ;
  print time / 60, ":", (ZeroPad) time % 60;
];


[ RealTimeSub ;
  RealTime(the_time);
  new_line;
];


[ SolveListSub;
  "_cabinet _library _light _crypt _solar _undercroft _start _stop";
];


[ SolveLightSub;
  move MyCandle to player;
  MyCandle.start_light();
  "DEBUG: You have the beeswax candle.^";
];


[ ShowMonksSub m ;
  objectloop (m ofclass Monk) {
    print (The) m, ": ", (name) parent(m);
    if (m.prev_loc) print " was ", (name) m.prev_loc;
    new_line;
  }
];


[ StartSceneSub o ;
  if (noun == nothing) {
    print "^";
    objectloop (o ofclass Scene)
      print (address) o.&name-->0, ": ", (The) o, "^";
    return;
  }

  noun.scene_start();
];


[ StopScenesSub o ;
  if (noun) {
    noun.scene_stop();
  }
  objectloop (o ofclass Scene) {
    if (o has general) {
      o.scene_stop();
    }
  }
];


[ TestQuotesSub i quote_array ;
  for (i = 1 : i <= test_quotes-->0 : i++) {
    quote_array = test_quotes-->i;
    QuoteBoxSimple(quote_array);
  }
];


[ EndingSub ;
  Ending(noun);
];

#EndIf;



!====================================================================== Includesx

#IfDef HAS_HINTS;
  Include "./thorns-hints.inf";
#EndIf;

#IfDef HAS_QUOTES;
  Include "thorns-quotes.inf";
#EndIf;